Неправильно работает простой индикатор

 

Добрый день. При написании стрелочного индикатора на основе осцилятора RIF столкнулась с ошибкой:

Индикатор должен показывать стрелку вверх при пересечении вниз,

и стрелку вниз при пересечении вверх. Вот так:



Но во время прогона на тестере стратегий, отображает стрелки не согласно алгоритму:


Вот код написанного мною индикатора, в чем может быть ошибка?

#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrBlue
#property indicator_color2 clrRed
#property indicator_width1 2
#property indicator_width2 2

double UpArrow[];
double DnArrow[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0,UpArrow);
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,233);
   
   SetIndexBuffer(1,DnArrow);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,234);
   
   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[])
{
   int limit = rates_total-2;
   if (prev_calculated > 0) limit = rates_total-prev_calculated;
   if (rates_total-prev_calculated > 1)
   {
      ArrayInitialize(UpArrow, EMPTY_VALUE);
      ArrayInitialize(DnArrow, EMPTY_VALUE);
      limit = rates_total-2;
   }
   
   for (int i=limit; i>=1; i--)
   {
      double Val1 = iCustom(NULL, 0, "RIF", 0, i);
      if (Val1 == EMPTY_VALUE) Val1 = iCustom(NULL, 0, "RIF", 1, i);
      
      if (Val1 != EMPTY_VALUE)
      {
         // Сигнал бай
         if (Val1 < 0)
         {
            double Val2 = iCustom(NULL, 0, "RIF", 0, i+1);
            if (Val2 == EMPTY_VALUE) Val2 = iCustom(NULL, 0, "RIF", 1, i+1);
            
            if (Val2 != EMPTY_VALUE && Val2 > 0) UpArrow[i] = low[i]-10*Point;
         }
         
         // Сигнал селл
         if (Val1 > 0)
         {
            double Val2 = iCustom(NULL, 0, "RIF", 0, i+1);
            if (Val2 == EMPTY_VALUE) Val2 = iCustom(NULL, 0, "RIF", 1, i+1);
            
            if (Val2 != EMPTY_VALUE && Val2 < 0) DnArrow[i] = high[i]+10*Point;
         }
      }
   }
   return(rates_total);
}
//+------------------------------------------------------------------+

Также прикрепляю исходные коды индикаторов:

Файлы:
RIF.mq4  10 kb
Test_RIF.mq4  5 kb
 
Tatiana Zyrianova:

Индикатор должен показывать стрелку вверх при пересечении вниз, и стрелку вниз при пересечении вверх. 

Слишком намудрено в коде с сигналом, сделал чуть проще))

Файлы:
Test2_RIF.mq4  5 kb
 
FXwin:

Слишком намудрено в коде с сигналом, сделал чуть проще))

Может быть, но ошибка все равно осталась)

 
Tatiana Zyrianova:

Может быть, но ошибка все равно осталась)

Там сам индикатор гистограммы в процессе перерисовывается,
а сигнал берётся с текущего бара
и если анализировать предыдущий бар,
то не будет ложных сигналов и не правильных выводов

 

Первое, о чём думаю, это:

for(int i = limit; i >= 0; i--)

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

Код не проверял.
 
FXwin:

Там сам индикатор гистограммы в процессе перерисовывается,
а сигнал берётся с текущего бара
и если анализировать предыдущий бар,
то не будет ложных сигналов и не правильных выводов

К сожалению это не так, в моем варианте кода вычисления производятся только 1 раз за свечу по предыдущей закрытой свече (когда rates_total > prev_calculated), но индикатор RIF почему-то возвращает другие значения, отличающиеся от тех, которые отображаются индикатором.

Aleksei Stepanenko:

Первое, о чём думаю, это:

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

Код не проверял.

В данном случае все вычисления происходят только по закрытому бару...

 
Татьяна, Ваши вычисления да, но в индикаторе "RIF" производится обсчёт текущего бара. А бар ещё не сформирован. Нет?
 
Aleksei Stepanenko:
Татьяна, Ваши вычисления да, но в индикаторе "RIF" производится обсчёт текущего бара. А бар ещё не сформирован. Нет?

Вы имеете в виду, что текущий бар может повлиять на предыдущий, и вычисления стоит производить по свече №2 (0 - текущая)?

 
 Попробуйте поставить единичку вместо нуля в цикле индикатора "RIF".
 
Aleksei Stepanenko:
 Попробуйте поставить единичку вместо нуля в цикле индикатора "RIF".

Сейчас

 
Aleksei Stepanenko:
 Попробуйте поставить единичку вместо нуля в цикле индикатора "RIF".

Спасибо большое, все получилось)

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