Discussing the article: "Creating multi-symbol, multi-period indicators" - page 2

 

Conducted a small stress test. I switched off the Internet, launched the indicator with the panel on the chart. I have already provided the parameters above. Then I switched on the Internet and got the following result:

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)


The indicator crashed.

 

I also noticed something strange. M15 chart on USDCHF.



If we look at the USDCHF chart, or rather at the red curve of the MA(USDCHF, H1) indicator, then for the last 7 hours the transition to the next value occurred at 00 minutes 5 times. I have highlighted it with red verticals. And only for the last 2 hours everything is normal. Blue verticals. Imho, a clear error with buffer filling....

 
Denis Kirichenko #:

Conducted a small stress test. I switched off the Internet, launched the indicator with the panel on the chart. I have already provided the parameters above. Then I switched on the Internet and got the following result:


The indicator crashed.

Denis Kirichenko #:

I also noticed some strange things. M15 chart on USDCHF.



If we look at the USDCHF chart, or rather at the red curve of the MA(USDCHF, H1) indicator, then for the last 7 hours the transition to the next value occurred at 00 minutes 5 times. I have highlighted it with red verticals. And only for the last 2 hours everything is normal. Blue verticals. Imho, a clear error with buffer filling....

Thanks, I'll look into it
 
Denis Kirichenko #:

Conducted a small stress test. I switched off the Internet, launched the indicator with the panel on the chart. I have already provided the parameters above. Then I switched on the Internet and got the following result:


The indicator crashed.

In line 211 at cursor position 34, the predefined array time[] is accessed:

DrawData(mouse_bar_index,time[mouse_bar_index]);

It turns out that the index passed to the array is incorrect.

It can hardly be more than rates_total-1, most likely it is equal to -1, because it receives its values in the OnChartEvent handler by the iBarShift() function, which can return -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);
     }
  }


In DrawData(), an invalid index value is handled by calling CopyRates(), which will not get any data if the index is negative, and will then exit DrawData():

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

So - before accessing the time[] array, you need to check the bar index passed to the array (in line 211):

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


In general - theory. I haven't tested it, as I am busy developing the continuation of the theme (coloured buffers of multi-indicators and so on). After the next article on this topic is published, I will check and test it (if you don't test it before me with changes in p.211).

 
Artyom Trishkin #:

In line 211, the predefined array time[] is accessed at cursor position 34:

It appears that the index to the array is passed incorrectly.

It can hardly be greater than rates_total-1, most likely it is equal to -1, because it receives its values in the OnChartEvent handler by the iBarShift() function, which can return -1:


In DrawData(), an invalid index value is handled by calling CopyRates(), which will not get any data if the index is negative, and will then exit DrawData():

So - before accessing the time[] array, you need to check the bar index passed to the array (in line 211):


In general - theory. I have not tested it, as I am busy developing the continuation of the topic (coloured buffers of multi-indicators and so on). After the next article on this topic is published, I will check and test it (if you don't test it before me with changes in p.211).

Artem, the bar index can be current, iBarShift() returns 0. But you can't put less than 1 into CopyRates(). That's why we should probably write iBarShift()+1 in any variant, since the bar number and the number of bars are not equal.

 
Alexey Viktorov #:

Artem, the bar index can be current, iBarShift() returns 0. But you cannot put less than 1 into CopyRates(). Therefore, we should probably write iBarShift()+1 in any variant, since the bar number and the number of bars are not equal.

In this context: the index is the bar number

 
Artyom Trishkin #:

In this context: the index is the bar number

Artem, index - yes, it can be zero. But the number of copied elements

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

cannot be equal to zero.

Just like the number of items and the index in the list of items...

 
Alexey Viktorov #:

Artem, the index - yes, it can be zero. But the number of copied elements

cannot be equal to zero.

Just like the number of items and the index in the list of items...

Right here:

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

where does index point ?

 
Artyom Trishkin #:

It's right here:

where does index point ?

That's it, I'll shut up. I didn't look at the code of the DrawData(mouse_bar_index,time) function; that's why I was mistaken...

 

Forum on trading, automated trading systems and testing trading strategies

Discussion of the article "Preparing multisymbol multi-period indicators"

Artyom Trishkin, 2023.11.01 04:46 AM

...After publication of the next article on this topic, I will check and test (if you do not test me before with changes in p.211).


To test something, you have to be in the paradigm of what's going on ))

I realised that it's easier for me to sketch my own version, as I'm not close to the current approach. In particular, it seems to me that the CIndMSTF class is some kind of super class. Then a bunch of indicator classes are created on its basis. Creepy - the IndMSTF.mqh file is 4 thousand lines of code )) I went the way of using an instance of CIndicators class as an indicator collection. It is very convenient. You don't need to invent a bicycle.

Then why should the CIndMSTF class store data on buffers (SBuffer m_buffers[])? We calculated them once in OnCalculate() and that's enough. I.e. we took it as a parameter by reference, calculated it and gave it back...

I'll write more later about what I disagree with once I finish my version....

Yes, I like that there is this mechanism:

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


Artem, one more thing. If articles are written as a manual, which there is a desire to study, then, imho, there are not enough schemes of relationships of those classes, which the developer creates....

Then, why put the code of all indicators in the article material? I mean this section - " Acomplete list of all inheritor classes of the base class of the multisymbol multiperiod indicator". Ilooked at how many lines of code there are .

Here is the beginning:

And here's the end:


Almost 2 thousand. Wow!