Новая версия платформы MetaTrader 5 build 3550: улучшения и исправления - страница 23

 
Slava #:

В одном и том же классе не должно быть одинаковых имён методов. Пусть даже и разные типы входных параметров. Например, ObjectInitFromFile и ObjectInitFromArray

Рекомендуемое наименование.

class Object
{
  void ObjectInitFromFile( const string FileName ) {}
  
  template <typename T>
  void ObjectInitFromArray( const T &Array[] ) {}
};


Нерекомендуемое.

class Object
{
  void Init( const string FileName ) {}
  
  template <typename T>
  void Init( const T &Array[] ) {}
};
 

#fxsaber, да, всё правильно. Именно так.

И уже такие имена можно заворачивать в шаблоны

 
Slava #:

#fxsaber, да, всё правильно. Именно так.

И уже такие имена можно заворачивать в шаблоны

Спасибо. Теперь осознал пользу во время поиска - можно четко задать, что искать.

Жаль, нельзя искать вызов методов по сигнатуре. Но для человека, безусловно, по имени удобнее.


Получается, при подобном правиле наименований не образуются перегрузки?

С виртуальными методами иное правило?

 
Slava # :

Не все фичи C++ реализованы. Некоторые реализованы с ошибкой .

Что ты имеешь в виду ?

Но в данном случае, с высоты 30-летнего опыта программирования на C++, я бы сказал: "не надо так делать". Это - путь к трудноуловимым ошибкам.

Больше скажу. Одинаковые имена методов разных (но похожих классов) (особенно в больших проектах) затрудняют поиск вызовов этих методов по проекту

Вы, конечно, правы, но это решать кодеру, а не компилятору.

 

fxsaber #:

Получается, при подобном правиле наименований не образуются перегрузки?

С виртуальными методами иное правило?

Да. Перегрузки - зло, ибо приводят к трудноуловимым ошибкам.

Виртуальные функции - добро. Но тут уже приходится использовать изначальное имя

 
Alain Verleyen #:


Вы, конечно, правы, но это решать кодеру, а не компилятору.

Да

 

Нашел ошибку с кастомными символами в тестере. Build 3580.

Вот часть баров в символе

В терминале показывает все правильно.
В тестере очень много баров (8 из 14) показывают OHC с ценой выше на 1 пункт, чем есть на самом деле.
Запустите в тестере любой индикатор (я запустил ATR) И увидите расхождение данных.
Заметил по данным полученным из OnCalculate(...) в open[0]," ",high[0]," "," ",close[0]. Посмотрел на графики - тоже цена завышена.

Вот скриншоты баров с завышеной ценой. Не показанные бары полностью совпадают. Слева терминал, справа тестер.


Чуть позже заметил и не совпадение тикового объема на баре 23:51.Там Должно быть 0, но видимо тестер исправил его сам на 4, т.к. 0 тиков - нелогично, но надо. Хорошо бы не делать исправления, а выдавать то, что записано.

Реальные объемы и Low на показанном участке проверил  - все совпадают. Но не исключено, что если проверять дальше, может где то и будет расхождение. Думаю надо делать вывод в файл и потом сделать построчное сравнение фалов полученных терминалом и тестером (есть утилита в Notepad++)

Архив с кастомным символом приложил, можете импортировать и воспроизвести проблему.

Файлы:
custom_bug.zip  151 kb
 

Сделал NormalizeDouble(p,Digits()) при записи данных в кастомный символ. После этого тестер тоже стал показывать правильные  данные. Видимо было round цен в тестере и float в терминале. Т.е. тестер оногдв округлял цены вверх, а терминал показывал как есть или отбрасывал лишние знаки после запятой.

Как бы проблема решена. Но хорошо бы сделать одинаковое поведение тестера и терминала.

 
elibrarius #:

Архив с кастомным символом приложил, можете импортировать и воспроизвести проблему.

После запуска советника в Тестере (M1 OHLC) и Терминале (M1)

struct RATES : public MqlRates
{
  string ToString( void ) const
  {
    return((string)this.time + " " +
           ::DoubleToString(this.open, _Digits) + " " +
           ::DoubleToString(this.high, _Digits) + " " +
           ::DoubleToString(this.low, _Digits) + " " +
           ::DoubleToString(this.close, _Digits) +
           ::IntegerToString(this.tick_volume, 5, ' ') +
           ::IntegerToString(this.real_volume, 5, ' ') +
           ::IntegerToString(this.spread, 5, ' '));
  }
};

int OnInit() { return(!MQLInfoInteger(MQL_TESTER)); }

void OnDeinit( const int )
{
  MqlRates Rates[];
  
  const int Size = CopyRates(_Symbol, PERIOD_CURRENT, 0, INT_MAX, Rates);
  
  const int handle = FileOpen((MQLInfoInteger(MQL_TESTER) ? "Tester_" : "Terminal_") + _Symbol + ".txt",
                              FILE_TXT | FILE_WRITE | FILE_COMMON);
                              
  if (handle != INVALID_HANDLE)
  {
    for (int i = 0; i < Size; i++)
    {
      const RATES RatesTmp = Rates[i];
      
      FileWriteString(handle, RatesTmp.ToString() + "\n");
    }
    
    FileClose(handle);
  }
}

Получил два файла для сравнения.

Tester vs Terminal.

Видно, что Тестер насильно подгоняет бар под тиковый объем. Скорректируйте тиковые объемы и попробуйте снова этим советником.

 
elibrarius #:

Сделал NormalizeDouble(p,Digits()) при записи данных в кастомный символ. После этого тестер тоже стал показывать правильные  данные. Видимо было round цен в тестере и float в терминале. Т.е. тестер оногдв округлял цены вверх, а терминал показывал как есть или отбрасывал лишние знаки после запятой.

Выше в архиве данные в csv-формате, поэтому нормализация при воспроизведении (импорт через GUI) проблемы никакого влияния точно не оказывала.