OnCalculate() игнорируется в тестере стратегий, но работает в визуальном тестере

 

Здравствуйте. 

А не баг ли это..?

При тестировании советника заметил, что результаты тестов в визуальном и обычном тестерах отличаются, проблема локализовалась в том, 

что в обычном тестере событие OnCalculate() индикаторов вызывалось гораздо реже, чем при визуальном тестировании. 

Это различие в работе удалось победить принудительным вызовом CopyBuffer() на каждом тике эксперта, причем копировал одно значение любого буфера индикатора в посторонний буфер эксперта.

Для воспроизведения проблемы пример кода эксперта:

int TicksTesterIndicatorHandle = INVALID_HANDLE;
double Buf[];
bool InitComplite=false;
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   IndicatorRelease(TicksTesterIndicatorHandle);
  }

void OnTick()
  {
   if(!InitComplite)
     {
      IndicatorInitialization();
     }

   Print("Tick - Expert");

   //if(CopyBuffer(TicksTesterIndicatorHandle,0,0,1,Buf)<=0)
   //  {
   //   Print("Копирование буфера Buf завершилось с ошибкой! Error : ",GetLastError());
   //   return;
   //  }
  }
//+------------------------------------------------------------------+
bool IndicatorInitialization()
  {
//---Получить хэндл индикатора TicksTesterIndicator
   TicksTesterIndicatorHandle=iCustom(NULL, _Period, "TicksTesterIndicator_1");

//--- Нужно проверить, не были ли возвращены значения Invalid Handle
   if(TicksTesterIndicatorHandle<0)
     {
      Print("Ошибка при создании индикатора TicksTesterIndicator - номер ошибки: ",GetLastError(),"!!!");
      return(false);
     }
   else
     {
      Print("TicksTesterIndicator инициализирован, хэндл: ", TicksTesterIndicatorHandle);
      ArraySetAsSeries(Buf, true);
      InitComplite=true;
     }
   return(true);
  }

Пример кода индикатора:

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1

//--- Plot 1 : Гистограмма
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrSilver

//--- Массивы буферов
double HistogramBuffer[];    // размер столбиков гистограммы

int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,HistogramBuffer,INDICATOR_DATA);
  // ArraySetAsSeries(HistogramBuffer, true);
   Print("Индикатор инициализирован");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   Print("OnCalculate() - Indicator");

//---
   int i,start;
   if(prev_calculated==0)
      start=0;
   else
      start=prev_calculated-1;
//--- the main loop of calculations
   for(i=start; i<rates_total; i++)
     {
      HistogramBuffer[i] = iOpen(_Symbol, PERIOD_CURRENT, rates_total-1-i);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

В такой связке результат в логах:

В визуальном тестере OnTick() советника и OnCalculate() индикатора вызываются на каждом тике. (OHLC на М1) ,

без визуального режима OnCalculate() не принтуется, хотя отрисовка индикатора происходит.

Если в коде советника раскоментить строки ниже, то OnTick начнёт вызываться на каждом тике.

   //if(CopyBuffer(TicksTesterIndicatorHandle,0,0,1,Buf)<=0)
   //  {
   //   Print("Копирование буфера Buf завершилось с ошибкой! Error : ",GetLastError());
   //   return;
   //  }

Это баг или фича? Хотелось бы избежать костылей с копированием на каждом тике.

 

зачем????

HistogramBuffer[i] = iOpen(_Symbol, PERIOD_CURRENT, rates_total-1-i);

В OnCalculate УЖЕ ЕСТЬ МАССИВ open[]!!!

 

Где видно что "реже" или "гуще"?

 

Это - явно описанное в документации поведение индикатора при тестировании

#property tester_everytick_calculate

https://www.mql5.com/ru/docs/basis/preprosessor/compilation

Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
  • www.mql5.com
Свойства программ (#property) - Препроцессор - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vladimir Karputov:

зачем????

В OnCalculate УЖЕ ЕСТЬ МАССИВ open[]!!!

Согласен, машинально получилось.

Vladimir Karputov:

Где видно что "реже" или "гуще"?

Не понял вас.

 
Slava:

Это - явно описанное в документации поведение индикатора при тестировании

#property tester_everytick_calculate

https://www.mql5.com/ru/docs/basis/preprosessor/compilation

Действительно. Большое спасибо за оперативность!

 

А можно вопрос от совсем безграмотного пользователя? Спасибо.

Вот скажите, а почему мне, СПБ, нужно прописывать ещё какие-то там #property tester_everytick_calculate ???

Если я тестирую "чёй-то-там-мне нужное", которое рассчитано, само собой, на работу в реале, то с какого фига в ТЕСТЕРЕ я должен ещё устанавливать какие-то дополнительные флаги? 

........

Вот я написал советник, индикатор... не суть. Суть в том, что я ожидаю, что в ТЕСТЕРЕ он будет работать так, как и на реале!!!!!!! А у вас всё наоборот!!! То, что работает в тестере - не работает в реале. А то что работает в реале - не работает в тестере! 

И это только потому, что это РАЗНЫЕ подходы и коды. А должны бать одинаковые!!!

Извините за резкость... 

Но эта "беда" тянется уже оооочень давно!

 
Нужно в мануале в разделе про OnCalculate() сделать упоминание #property tester_everytick_calculate
 
Сергей Таболин:

А можно вопрос от совсем безграмотного пользователя? Спасибо.

Вот скажите, а почему мне, СПБ, нужно прописывать ещё какие-то там #property tester_everytick_calculate ???

Если я тестирую "чёй-то-там-мне нужное", которое рассчитано, само собой, на работу в реале, то с какого фига в ТЕСТЕРЕ я должен ещё устанавливать какие-то дополнительные флаги? 

........

Вот я написал советник, индикатор... не суть. Суть в том, что я ожидаю, что в ТЕСТЕРЕ он будет работать так, как и на реале!!!!!!! А у вас всё наоборот!!! То, что работает в тестере - не работает в реале. А то что работает в реале - не работает в тестере! 

И это только потому, что это РАЗНЫЕ подходы и коды. А должны бать одинаковые!!!

Извините за резкость... 

Но эта "беда" тянется уже оооочень давно!

Вам не нужно ничего прописывать.

Это - экзотический случай, который может учесть только писатель индикатора

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