Работа индикатора в режиме OffLine

 

Привет!

Пишу индикатор со сложными вычислениями, при которых данные могут подгружаться не с первого раза.

Поэтому я принудительно вызываю функцию OnCalculate() по клавише.

Если данные подгрузились с первого раза, то индикатор нормально срабатывает запоминая rates_total и time[]

Если данные не подгрузились, то CalcOffLine возвращает "0", т.е в индикаторе не произошел расчет.

При повторном нажатии клавиши данные подгружаются, индикаторные буферы заполняются правильно, но графики не отображаются.

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[]  
)
{
  if(prev_calculated == 0)
  {
    if (OffLine == true)
    {
      ArrayInitialize(Hi_Buff, EMPTY_VALUE);
      ArrayInitialize(Low_Buff, EMPTY_VALUE);
      ArrayInitialize(a_Hi_Buff, EMPTY_VALUE);
      ArrayInitialize(a_Low_Buff, EMPTY_VALUE);
      ArrayInitialize(Pr_Buff, EMPTY_VALUE);
      m_data.max_value = -DBL_MAX; 
      m_data.min_value = DBL_MAX;
      m_data.midle_value = 0;
      m_data.pr_mem_pos = 0;
      m_data.sec_mem_pos = 0;
      ArrayCopy(tmp_time, time);
      tmp_rates = rates_total;
      return(CalcOffLine(rates_total, time));
    }
    else
    {}


//+------------------------------------------------------------------+
//| Custom indicator On Chart Event function                         |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
  if(id == CHARTEVENT_KEYDOWN)
  {
    if(lparam == 40)
    {
      m_data.ind_max += Istep;
      m_data.ind_min -= Istep;
      IndicatorSetDouble(INDICATOR_MAXIMUM, m_data.ind_max);
      IndicatorSetDouble(INDICATOR_MINIMUM, m_data.ind_min);
    }
    else
    if(lparam == 38)
    {
      m_data.ind_max -= Istep;
      m_data.ind_min += Istep;
      IndicatorSetDouble(INDICATOR_MAXIMUM, m_data.ind_max);
      IndicatorSetDouble(INDICATOR_MINIMUM, m_data.ind_min);
    }
    else
    if(lparam == 82)
    {
      if(OffLine == true)
      {
        double open[]; 
        double high[]; 
        double low[]; 
        double close[]; 
        long tick_volume[]; 
        long volume[];
        int spread[]; 
        OnCalculate(tmp_rates, 0, tmp_time, open, high, low, close,tick_volume, volume, spread);
      }  
    }
    ChartRedraw();
  }
}


Почему? 

Или как заставить индикатор сделать вычисления повторно в offLine режиме?

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Функции обработки событий - Функции - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
prostotrader:

Привет!

Пишу индикатор со сложными вычислениями, при которых данные могут подгружаться не с первого раза.

Поэтому я принудительно вызываю функцию OnCalculate() по клавише.

Если данные подгрузились с первого раза, то индикатор нормально срабатывает запоминая rates_total и time[]

Если данные не подгрузились, то CalcOffLine возвращает "0", т.е в индикаторе не произошел расчет.

При повторном нажатии клавиши данные подгружаются, индикаторные буферы заполняются правильно, но графики не отображаются.



Почему? 

Или как заставить индикатор сделать вычисления повторно в offLine режиме?

в 5-ке вызов OnCalculate для перерасчёта "в ручном режиме" чреват эффектами. Совсем просто НИКАК

для перерасчёта из OnTimer,OnChartEvent: заводить отдельные массивы my_time,my_open,my_high.. аттачить их как индикаторные буферы,
внутри OnCalculate если нет флага OffLine - копировать в них данные из time, open, high...если взведён то не трогать
снаружи при самостоятельном вызове взводить флаг OffLine и вызывать OnCalculate(my_time,my_open,.....); Не забывать убирать флаг обратно; И вызывать ChartRedraw ;
Тогда данные все правильно синхронны и рассчёты правильны.

и даже так отрисовывается через раз. 

Но вышесказанное про перерасчеты (например с другими коэфф),
а при подкачке данных OnCalculate будет и так вызван терминалом. Просто отдайте ему управление :-) Ради контроля/отладки в OnTimer смотреть/печатать SeriesInfoInteger()  SERIES_BARS_COUNT SERIES_SYNCHRONIZED

 
Maxim Kuznetsov #:

в 5-ке вызов OnCalculate для перерасчёта "в ручном режиме" чреват эффектами. Совсем просто НИКАК

для перерасчёта из OnTimer,OnChartEvent: заводить отдельные массивы my_time,my_open,my_high.. аттачить их как индикаторные буферы,
внутри OnCalculate если нет флага OffLine - копировать в них данные из time, open, high...если взведён то не трогать
снаружи при самостоятельном вызове взводить флаг OffLine и вызывать OnCalculate(my_time,my_open,.....); Не забывать убирать флаг обратно; И вызывать ChartRedraw ;
Тогда данные все правильно синхронны и рассчёты правильны.

и даже так отрисовывается через раз. 

Но вышесказанное про перерасчеты (например с другими коэфф),
а при подкачке данных OnCalculate будет и так вызван терминалом. Просто отдайте ему управление :-) Ради контроля/отладки в OnTimer смотреть/печатать SeriesInfoInteger()  SERIES_BARS_COUNT SERIES_SYNCHRONIZED

Большое спасибо за подсказку, совсем забыл, что в индикаторе можно использовать таймер.

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