MT5 :: Где искать ошибку? Или ошибка индикатора, работающего по данным другого индикатора?

 

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

У меня есть тиковый индикатор, который не привязан ни к какому ТФ. На его основе, я написал советник.

Для этого мне понадобились ещё два стандартных индикатора, работающих на данных моего тикового индикатора.

//********* индикаторы
int         handle_newCandles;
double      buf_NCT_open[];
double      buf_NCT_close[];
double      buf_NCT_high[];
double      buf_NCT_low[];

int         handle_TEMA;
double      buf_TEMA[];

int         handle_VIDA;
double      buf_VIDA[];
//*********
bool        my_new_bar           = false;          // новый бар
double      my_saved_last_closed = -1.0;           // цена закрытия последнего бара
int         sig_count            = 0;
//*********
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   OnInitGeneral();
//+---------------------
   ArraySetAsSeries(buf_NCT_close,true);
   ArraySetAsSeries(buf_NCT_high ,true);
   ArraySetAsSeries(buf_NCT_low  ,true);
   ArraySetAsSeries(buf_NCT_open ,true);
   ArraySetAsSeries(buf_TEMA     ,true);
   ArraySetAsSeries(buf_VIDA     ,true);
//+---------------------
   handle_newCandles = iCustom(Symbol(),Period(),"my_Chart\\newCandle_3.01",in_candle_size,in_candle_from);
   if(handle_newCandles == INVALID_HANDLE)
   {
      writeErrorFile(program_name,program_version,"Ошибка получения хэндла индикатора newCandle.");
      return(INIT_FAILED);
   }
   ChartIndicatorAdd(0,1,handle_newCandles);
   
   handle_TEMA       = iTEMA(Symbol(),Period(),in_period_tema,0,handle_newCandles);
   if(handle_TEMA == INVALID_HANDLE)
   {
      writeErrorFile(program_name,program_version,"Ошибка получения хэндла индикатора TEMA.");
      return(INIT_FAILED);
   }
   ChartIndicatorAdd(0,1,handle_TEMA);
   
   handle_VIDA       = iVIDyA(Symbol(),Period(),in_period_vida_cmo,in_period_vida_ema,0,handle_newCandles);
   if(handle_VIDA == INVALID_HANDLE)
   {
      writeErrorFile(program_name,program_version,"Ошибка получения хэндла индикатора VIDA.");
      return(INIT_FAILED);
   }
   ChartIndicatorAdd(0,1,handle_VIDA);
//+---------------------
   return(INIT_SUCCEEDED);
}

Уже после этого у меня возникли сомнения в правильности работы стандартных индикаторов. Дело в том, что при подключении советника к графику всё отрисовывается правильно. А дальше...

Прогоняю оптимизацию, запускаю одиночный тест и в открывшемся окне вижу, что эти стандартные индикаторы нарисованы не в окне моего индикатора, а на основном графике. Почему?

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

И тут я был ошарашен - результат отличался кардинально! Почему?

Я решил написать тестовый советник, который не торгует, а просто записывает данные индикаторов в файл.

void OnTick()
{
//+------------------------------------------
      // определяем новый бар
      my_new_bar  = false;
      if(CopyBuffer(handle_newCandles,3,0,1,buf_NCT_close) == 1)
      {
         if(buf_NCT_close[0] > 0.0)
         {
            if(buf_NCT_close[0] != my_saved_last_closed) my_new_bar           = true;
            if(my_saved_last_closed < 0.0)               my_new_bar           = false;
            if(buf_NCT_close[0] != my_saved_last_closed) my_saved_last_closed = buf_NCT_close[0];
         }
      }
      
      if(my_new_bar && copyBuffers())
      {
         //Print("my_new_bar");
         my_new_bar  = false;
//+----------
         ENM_TRADESIGNAL   buy_sell = TRADESIGNAL_NO;
//+---------------------
         // проверка на открытие позиции
            if(buf_VIDA[0] < buf_NCT_low[0]  && buf_TEMA[0] >= buf_NCT_open[0] && buf_TEMA[0] <= buf_NCT_close[0])   buy_sell = TRADESIGNAL_BUY;
            // 2
            else
            if(buf_VIDA[0] > buf_NCT_high[0] && buf_TEMA[0] <= buf_NCT_open[0] && buf_TEMA[0] >= buf_NCT_close[0])   buy_sell = TRADESIGNAL_SELL;

         if(buy_sell == TRADESIGNAL_BUY || buy_sell == TRADESIGNAL_SELL)
         {
            string pos_string = IntegerToString(++sig_count,2,'0') + " ======================" + "\n"
                              + "buy_sell = " + EnumToString(buy_sell) + " " + TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS) + "\n"
                              + "O H L C  = " + DoubleToString(buf_NCT_open[0],Digits()) + " || "
                                              + DoubleToString(buf_NCT_high[0],Digits()) + " || "
                                              + DoubleToString(buf_NCT_low[0],Digits()) + " || "
                                              + DoubleToString(buf_NCT_close[0],Digits()) + "\n" 
                              + "TEMA = "     + DoubleToString(buf_TEMA[0],Digits()) + "\n"
                              + "VIDA = "     + DoubleToString(buf_VIDA[0],Digits()) + "\n";
            
            writeErrorFile(program_name,program_version,pos_string);
            if(sig_count >= 10) ExpertRemove();
         }
}
//+------------------------------------------------------------------+
bool copyBuffers()
{
   int from    = 0;
   int count   = 5;
   
   if(CopyBuffer(handle_newCandles,0,from,count,buf_NCT_open) != count)
   {
      Print(__FUNCTION__);
      Print("Ошибка копирования значений open индикатора newCandle");
      writeErrorFile(program_name,program_version,"Ошибка копирования значений open индикатора newCandle");
      return(false);
   }
   if(CopyBuffer(handle_newCandles,1,from,count,buf_NCT_high) != count)
   {
      Print(__FUNCTION__);
      Print("Ошибка копирования значений high индикатора newCandle");
      writeErrorFile(program_name,program_version,"Ошибка копирования значений high индикатора newCandle");
      return(false);
   }
   if(CopyBuffer(handle_newCandles,2,from,count,buf_NCT_low) != count)
   {
      Print(__FUNCTION__);
      Print("Ошибка копирования значений low индикатора newCandle");
      writeErrorFile(program_name,program_version,"Ошибка копирования значений low индикатора newCandle");
      return(false);
   }
   if(CopyBuffer(handle_newCandles,3,from,count,buf_NCT_close) != count)
   {
      Print(__FUNCTION__);
      Print("Ошибка копирования значений close индикатора newCandle");
      writeErrorFile(program_name,program_version,"Ошибка копирования значений close индикатора newCandle");
      return(false);
   }
//+----------
   if(CopyBuffer(handle_TEMA,0,from,count,buf_TEMA) != count)
   {
      Print(__FUNCTION__);
      Print("Ошибка копирования значений индикатора TEMA");
      writeErrorFile(program_name,program_version,"Ошибка копирования значений индикатора TEMA");
      return(false);
   }
//+----------
   if(CopyBuffer(handle_VIDA,0,from,count,buf_VIDA) != count)
   {
      Print(__FUNCTION__);
      Print("Ошибка копирования значений индикатора VIDA");
      writeErrorFile(program_name,program_version,"Ошибка копирования значений индикатора VIDA");
      return(false);
   }
//+---------------------
   return(true);
}

Запустил этот советник на двух ТФ и получил вот такой результат:


Здесь чётко видно, что данные стандартных индикаторов не совпадают!

Почему так? И что нужно сделать, чтобы эти индикаторы заработали нормально?

 

Решил проверить значения буферов этих же индикаторов только уже на открытии нового бара на графике.

На разных ТФ значения моего индикатора, как и должно, в одно и то же время полностью совпадают. А вот значения стандартных - гуляет...


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