Скачать MetaTrader 5

Легальный нативный способ запустить OnCalculate у индикатора?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Комбинатор
16183
Комбинатор  

Есть ли такой?

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

Boris
3925
Boris  

... или на кнопку "Компилировать"!

Всё решилось просто! RefreshRates() перед первыми данными, которые сами не освежаются, и всё в порядке! :))

Комбинатор
16183
Комбинатор  
Короче без искусственных тиков есть способы? Под нативными подразумеваю вообще без длл. Но таких таки вряд ли есть.
Ihor Herasko
10657
Ihor Herasko  
Может, про таймер забыли (хотя вряд ли)?
Комбинатор
16183
Комбинатор  
Scriptong:
Может, про таймер забыли (хотя вряд ли)?
А что делать по таймеру? OnCalculate отрабатывает, но данные новые на графике не видны.
Dina Paches
8043
Dina Paches  
TheXpert:

Есть ли такой?

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

Использую CopyDataOnCalculate (...) в OnCalculate из статьи. Полагаю, это легально. 

Только исходя из особенностей своего кода (обновление значений при конкретных событиях), поставила в OnChartEvent вместо OnTimer следующую часть:

if(id ...)
     {
      Print("Обрабатывается ПОЛЬЗОВАТЕЛЬСКОЕ событие с ID = ",id);
      ...
      OnCalculate(OC_rates_total,OC_prev_calculated,
                  OC_time,OC_open,OC_high,OC_low,OC_close,
                  OC_tick_volume,OC_volume,OC_spread);

      if(jp==1){jp=0;return;}
      if(jp==0){jp=1;return;}

      ChartRedraw();// принудительно перерисуем все объекты на графике
     }

Не могу сказать, насколько это корректно, но работает.

Ihor Herasko
10657
Ihor Herasko  
TheXpert:
OnCalculate отрабатывает, но данные новые на графике не видны.

Не отображаются новые данные из буферов индикатора или графические объекты?
Комбинатор
16183
Комбинатор  
Scriptong:
Не отображаются новые данные из буферов индикатора или графические объекты?
Новые данные из буферов. Граф. объекты отлично появляются после ChartRedraw()
Ihor Herasko
10657
Ihor Herasko  
TheXpert:
Новые данные из буферов. 

Тут возникают следующие рассуждения.

Ситуацию спасает Refresh. Во время refresh с сервера принудительно подкачиваются все данные по текущему графику, которые по каким-то причинам не поступили в терминал. Напрашивается вывод: обновленные данные (несколько тиков текущего бара) не были приняты терминалом, отсюда и невозможность их обработки индикатором.

С другой стороны, насколько я понимаю, такие тики вы наблюдаете визуально, но их, почему-то, не видит сам индикатор. В этом случае возникают мысли о некорректно работающем индикатора.

В любом случае, чтобы не гадать, лучше бы увидеть демо-код (упрощенный код индикатора, с которым работаете), показывающий эту проблему.

 

P. S. А может речь идет о работе индикатора на оффлайн-графике? 

Dina Paches
8043
Dina Paches  
TheXpert:
Новые данные из буферов. Граф. объекты отлично появляются после ChartRedraw()


Сейчас немного уточнила код выше.

Основные же расчёты, в том числе по буферам, прописаны и активизируются, обновляясь, в основном (обычном) OnCalculate, а не в OnChartEvent. Ну и, соответственно, обновляются на графике вне зависимости от поступления тиков и Refresh. Но за счёт кода выше.

P./S.: Откровенно говоря, чувствую себя несколько неуютно, поэтому далее не буду встревать в разговор.

Комбинатор
16183
Комбинатор  

Так, вобщем все перепроверил. Непонятки вобщем. Ладно, по порядку.

Итак. Простой индикатор для проверки работы по таймеру.

//+------------------------------------------------------------------+
//|                                                        Timer.mq4 |
//|                                         Copyright 2014, TheXpert |
//|                                         http://www.trend-lab.ru/ |
//+------------------------------------------------------------------+
#property version   "1.00"
#property strict
#property indicator_separate_window

#property indicator_buffers 1
#property indicator_plots 1

#property indicator_color1 clrRed

double Values[];

bool IsFromTimer;

int OnInit()
{
   SetIndexBuffer(0, Values);
   ArraySetAsSeries(Values, true);
   
   EventSetTimer(5);
   IsFromTimer = false;
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int)
{
   EventKillTimer();
}

void OnTimer()
{
   //fake arrays for OnCalculate
   int ints[];
   long longs[];
   double doubles[];
   datetime datetimes[];
   
   IsFromTimer = true;
   OnCalculate(Bars, 0, datetimes, doubles, doubles, doubles, doubles, longs, longs, ints);
   ChartRedraw();
}

int OnCalculate(const int rates_total,
                const int,
                const datetime &[],
                const double &[],
                const double &[],
                const double &[],
                const double &[],
                const long &[],
                const long &[],
                const int &[])
{
   if (IsFromTimer)
   {
      for (int i = 0; i < Bars; i++)
      {
         Values[i] = (i % 2 == 0) ? -1 : 1;
      }
   }
   else
   {
      for (int i = 0; i < Bars; i++)
      {
         Values[i] = (i % 2 == 0) ? -2 : 2;
      }
   }
   
   Print("IsFromTimer = ", IsFromTimer ? "true" : "false");

   IsFromTimer = false;
   return(rates_total);
}

Если ChartRedraw() нету, данные обновляются по какому-нибудь событию на графике, например, если навесить другой индикатор.

Если ChartRedraw() есть, все отлично обновляется.

Кстати заметил одну фишку нечаянно, которой не знал. При навешивании индикатора, который вызывает индикатор Timer через iCustom у индикатора Timer терминалом принудительно вызывается OnCalculate.

Вот пример вызова

#property version   "1.00"
#property strict
#property indicator_separate_window

#property indicator_buffers 1
#property indicator_plots 1

#property indicator_color1 clrRed

double Values[];

int hTimer;

int OnInit()
{
   SetIndexBuffer(0, Values);
   ArraySetAsSeries(Values, true);
   
   return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
                const int,
                const datetime &[],
                const double &[],
                const double &[],
                const double &[],
                const double &[],
                const long &[],
                const long &[],
                const int &[])
{
   for (int i = 0; i < Bars; i++)
   {
      Values[i] = iCustom(_Symbol, _Period, "Timer", 0, i);
   }

   return(rates_total);
}



Теперь непонятки. Фишка в том, что в прошлые выходные на другом (нужном) индикаторе ChartRedraw() никак ничего не менял, из-за чего и была создана тема.

Буду разбираться дальше. Всем участникам спасибо. Об итоге отпишусь дополнительно.

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий