Обсуждение статьи "Готовим мультисимвольные мультипериодные индикаторы" - страница 2

 

Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:

CL      0       22:29:43.402    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
OS      0       22:29:43.402    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
DQ      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
QL      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
IO      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
PQ      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
LN      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
KE      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
JH      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
RK      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
OD      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
CR      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
GE      0       22:30:04.495    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::OnTimer::MA(EURUSD,H1:10): Tick emulation. Attempt 1 of 3 ...
II      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
LD      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
DH      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
NH      0       22:30:34.093    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RG      0       22:30:34.093    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
JM      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
KP      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
CD      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
FL      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RK      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
OM      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for a new tick and when the indicator will be calculated...
PI      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Calculation not completed
ND      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
PN      2       22:30:39.604    TestMSTFMovingAverages (EURUSD,M15)     array out of range in 'TestMSTFMovingAverages.mq5' (211,34)


Индикатор вылетел.

 

Ещё заметил странности. График М15 на USDCHF. 



Если посмотрим на график USDCHF, а вернее на красную кривую индикатора МА(USDCHF, H1), то за последние 7 часов переход на следующее значение происходил в 00 минут 5 раз. Выделил красными вертикалями. И только последние 2 часа всё нормально. Синие вертикали. Имхо, явный косяк с заполнением буферов...

 
Denis Kirichenko #:

Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:


Индикатор вылетел.

Denis Kirichenko #:

Ещё заметил странности. График М15 на USDCHF. 



Если посмотрим на график USDCHF, а вернее на красную кривую индикатора МА(USDCHF, H1), то за последние 7 часов переход на следующее значение происходил в 00 минут 5 раз. Выделил красными вертикалями. И только последние 2 часа всё нормально. Синие вертикали. Имхо, явный косяк с заполнением буферов...

Спасибо, буду разбираться
 
Denis Kirichenko #:

Провёл небольшое стресс-тестирование. Выключил интернет, запустил индикатор с панелью на график. Параметры уже предоставил выше. Потом включил интернет, получил такой результат:


Индикатор вылетел.

В строке 211 в позиции курсора 34 идёт обращение к предопределённому массиву time[]:

DrawData(mouse_bar_index,time[mouse_bar_index]);

Выходит, что индекс в массив передан некорректный.

Больше rates_total-1 он вряд ли может быть, скорее всего равен -1, так как получает свои значения в обработчике OnChartEvent функцией iBarShift(), которая может вернуть -1:

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- Работа с панелью
//--- Вызываем обработчик событий панели
   panel.OnChartEvent(id,lparam,dparam,sparam);

//--- Если курсор перемещается или щелчок по графику
   if(id==CHARTEVENT_MOUSE_MOVE || id==CHARTEVENT_CLICK)
     {
      //--- Объявляем переменные для записи в них координат времени и цены
      datetime time=0;
      double price=0;
      int wnd=0;
      //--- Если координаты курсора преобразованы в дату и время
      if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,wnd,time,price))
        {
         //--- записываем индекс бара, где расположен курсор в глобальную переменную
         mouse_bar_index=iBarShift(Symbol(),PERIOD_CURRENT,time);
         //--- Выводим данные бара под курсором на панель
         DrawData(mouse_bar_index,time);
        }
     }

//--- Если получили пользовательское событие - выводим об этом сообщение в журнал
   if(id>CHARTEVENT_CUSTOM)
     {
      //--- Здесь может быть обработка щелчка по кнопке закрытия на панели
      PrintFormat("%s: Event id=%ld, object id (lparam): %lu, event message (sparam): %s",__FUNCTION__,id,lparam,sparam);
     }
  }


В функции DrawData() некорректное значение индекса обрабатывается при вызове CopyRates(), которая не получит данных при отрицательном индексе, и после этого будет осуществлён выход из DrawData():

//--- Если данные бара по указанному индексу получить не удалось - уходим
   if(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)
      return;

Значит - перед обращением к массиву time[] нужно проверять индекс бара, передаваемый в массив (в строке 211):

//--- Выводим на панель данные бара под курсором (либо текущий бар, если курсор за пределами графика)
   if(mouse_bar_index>WRONG_VALUE && mouse_bar_index<rates_total)
      DrawData(mouse_bar_index,time[mouse_bar_index]);


В общем - теория. Не тестировал, так как занят разработкой продолжения темы (цветные буферы мульти- индикаторов и такое прочее). После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)

 
Artyom Trishkin #:

В строке 211 в позиции курсора 34 идёт обращение к предопределённому массиву time[]:

Выходит, что индекс в массив передан некорректный.

Больше rates_total-1 он вряд ли может быть, скорее всего равен -1, так как получает свои значения в обработчике OnChartEvent функцией iBarShift(), которая может вернуть -1:


В функции DrawData() некорректное значение индекса обрабатывается при вызове CopyRates(), которая не получит данных при отрицательном индексе, и после этого будет осуществлён выход из DrawData():

Значит - перед обращением к массиву time[] нужно проверять индекс бара, передаваемый в массив (в строке 211):


В общем - теория. Не тестировал, так как занят разработкой продолжения темы (цветные буферы мульти- индикаторов и такое прочее). После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)

Артём, индекс бара может быть и текущий,  iBarShift() возвращает 0. А вот в CopyRates() меньше 1 засунуть нельзя. Поэтому, наверное надо писать iBarShift()+1 в любом варианте, так-как номер бара и количество баров не равны.

 
Alexey Viktorov #:

Артём, индекс бара может быть и текущий,  iBarShift() возвращает 0. А вот в CopyRates() меньше 1 засунуть нельзя. Поэтому, наверное надо писать iBarShift()+1 в любом варианте, так-как номер бара и количество баров не равны.

В данном контексте: индекс - и есть номер бара

 
Artyom Trishkin #:

В данном контексте: индекс - и есть номер бара

Артём, индекс — да, он может быть и нулю равен. Но количество копируемых элементов

int  CopyRates( 
   string           symbol_name,       // имя символа 
   ENUM_TIMEFRAMES  timeframe,         // период 
   int              start_pos,         // откуда начнем  
   int              count,             // сколько копируем 
   MqlRates         rates_array[]      // массив, куда будут скопированы данные 
   );

нулю не может быть равно.

Точно так-же как количество позиций и индекс в списке позиций…

 
Alexey Viktorov #:

Артём, индекс — да, он может быть и нулю равен. Но количество копируемых элементов

нулю не может быть равно.

Точно так-же как количество позиций и индекс в списке позиций…

Вот здесь:

if(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)

куда указывает index ?

 
Artyom Trishkin #:

Вот здесь:

куда указывает index ?

Всё, умолкаю. Я не смотрел код функции DrawData(mouse_bar_index,time); потому и ошибался…

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Обсуждение статьи "Готовим мультисимвольные мультипериодные индикаторы"

Artyom Trishkin, 2023.11.01 04:46

...После публикации очередной статьи по этой теме, буду проверять и тестировать (если Вы раньше меня не протестируете с внесением изменений в стр.211)


Чтобы что-то тестировать, нужно быть в парадигме происходящего ))

Я понял, что мне легче свою версию набросать, т.к. мне не близок текущий подход. В частности, мне кажется, что класс CIndMSTF какой-то супер класс. Потом на его базе создаётся куча индикаторных классов. Жуть - файл IndMSTF.mqh на 4 тыс. строк кода )) Я пошёл по пути использования в качестве индикаторной коллекции экземпляр класса CIndicators. Очень удобно. Не нужно изобретать велосипед... 

Потом зачем в классе CIndMSTF хранить данные по буферам (SBuffer m_buffers[])? Один раз обсчитали их в OnCalculate() и хватит. Т.е. приняли как параметр по ссылке, посчитали и отдали...

Напишу ещё попозже о том, с чем не согласен, как закончу свою версию...

Да, понравилось, что есть вот этот механизм:

...При работе с данными не текущего графика для исключения "освобождения" таймсерии, необходимо не реже. чем раз в две минуты обращаться к этой таймсерии. В этом случае будет происходить "удержание" таймсерии, что ускорит к ней обращение (не нужно будет каждый раз дожидаться синхронизации данных)...


Артём, ещё такой момент. Если статьи пишутся как пособие, к-рое есть желание изучать, то имхо, не хватает схем взаимоотношений тех, классов, к-рые разработчик создаёт...

Потом, зачем выкладывать код всех индикаторов в материал статьи? Я о б этом разделе - "Полный список всех классов-наследников базового класса мультисимвольного мультипериодного индикатора".  Специально посмотрел, сколько строк кода там. 

Вот начало:

 А вот конец:


Почти 2 тыс. Ошалеть!

Причина обращения: