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

 

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

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

 

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

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

 
Короче без искусственных тиков есть способы? Под нативными подразумеваю вообще без длл. Но таких таки вряд ли есть.
 
Может, про таймер забыли (хотя вряд ли)?
 
Scriptong:
Может, про таймер забыли (хотя вряд ли)?
А что делать по таймеру? OnCalculate отрабатывает, но данные новые на графике не видны.
 
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();// принудительно перерисуем все объекты на графике
     }

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

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

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

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

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

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

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

 

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

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


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

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

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

 

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

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

//+------------------------------------------------------------------+
//|                                                        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() никак ничего не менял, из-за чего и была создана тема.

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