Индикатор другого графика

 

Привет!

Пишу индикатор вывода графика на другом графике,

но появляется ошибка с нулевым значение буферов.

 

Помогите найти:

 

//+------------------------------------------------------------------+
//|                                                   Sec_symbol.mq5 |
//|                                      Copyright 2016 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window

#property indicator_buffers 4
#property indicator_plots   1
//
input string SecSymb="MIX-12.16"; //Отображаемый символ
input bool Match=true;            //Точное совпадение свечей по времени

//--- plot Label1
#property indicator_label1  ""
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrWhite, clrGreen,clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- Levels
#property indicator_level1 0
#property indicator_levelwidth 1
#property indicator_levelstyle STYLE_DOT
//--- индикаторные буферы
double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!SymbolSelect(SecSymb,true))
     {
      Alert("Не правильно выбран символ "+SecSymb);
      return(INIT_FAILED);
     }
   int digits=int(SymbolInfoInteger(SecSymb,SYMBOL_DIGITS));
   IndicatorSetInteger(INDICATOR_DIGITS,digits);
   SetIndexBuffer(0,Buffer1,INDICATOR_DATA);
   SetIndexBuffer(1,Buffer2,INDICATOR_DATA);
   SetIndexBuffer(2,Buffer3,INDICATOR_DATA);
   SetIndexBuffer(3,Buffer4,INDICATOR_DATA);
//---
   ArraySetAsSeries(Buffer1,true);
   ArraySetAsSeries(Buffer2,true);
   ArraySetAsSeries(Buffer3,true);
   ArraySetAsSeries(Buffer4,true);
//---
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//---
   IndicatorSetInteger(INDICATOR_LEVELCOLOR,0,clrYellow);
   IndicatorSetString(INDICATOR_SHORTNAME,SecSymb);
   PlotIndexSetString(0,PLOT_LABEL," Open;"+" High;"+" Low;"+" Close");
//---
   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[])
  {
   ArraySetAsSeries(time,true);
   MqlRates rates[];
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer1,EMPTY_VALUE);
      ArrayInitialize(Buffer2,EMPTY_VALUE);
      ArrayInitialize(Buffer3,EMPTY_VALUE);
      ArrayInitialize(Buffer4,EMPTY_VALUE);
      //---
      int attempts=0;
      int result=0;
      int a_cnt=1000;
      //--- делаем 1000 попыток получить таймсерию
      while((attempts<a_cnt) && !IsStopped())
        {
         result=CopyRates(SecSymb,Period(),0,rates_total,rates);
         if(result>0) break;
         for(int i=0; i<a_cnt;i++)
           {
            result=1;
            result=0;
           }
         attempts++;
        }
      if(result>0)
        {
         int mem_pos=result;
         ArraySetAsSeries(rates,true);
         if(Match)
           {
            for(int i=rates_total-1;i>=0;i--)
              {
               int is_done=false;
               for(int j=mem_pos-1;j>=0;j--)
                 {
                  if(time[i]==rates[j].time)
                    {
                     mem_pos=j;
                     Buffer1[i] = rates[j].open;
                     Buffer2[i] = rates[j].high;
                     Buffer3[i] = rates[j].low;
                     Buffer4[i] = rates[j].close;
                     is_done=true;
                     break;
                    }
                 }
               if(!is_done)
                 {
                  Buffer1[i] = EMPTY_VALUE;
                  Buffer2[i] = EMPTY_VALUE;
                  Buffer3[i] = EMPTY_VALUE;
                  Buffer4[i] = EMPTY_VALUE;
                 }
              }
           }
         else
           {
            for(int i=result-1;i>=0;i--)
              {
               Buffer1[i] = rates[i].open;
               Buffer2[i] = rates[i].high;
               Buffer3[i] = rates[i].low;
               Buffer4[i] = rates[i].close;
              }
           }
        }
      else
        {
         Alert("Не скопированы данные по символу "+SecSymb+". Перегрузите индикатор.");
        }
     }
     else
     {
       int diff = rates_total - prev_calculated;
       if(diff>0)
       {
         for(int i=diff-1; i>0; i++)
         {
           Buffer1[i] = Buffer1[i+1];
           Buffer2[i] = Buffer2[i+1];
           Buffer3[i] = Buffer3[i+1];
           Buffer4[i] = Buffer4[i+1];
         }
       }
     }
   if(CopyRates(SecSymb,Period(),0,1,rates)==1)
     {
      if(time[0]==rates[0].time)
        {
         Buffer1[0]= rates[0].open;
         Buffer2[0] = rates[0].high;
         Buffer3[0] = rates[0].low;
         Buffer4[0] = rates[0].close;
        }
     }
   double s_last=SymbolInfoDouble(SecSymb,SYMBOL_LAST);
   IndicatorSetDouble(INDICATOR_LEVELVALUE,s_last);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
prostotrader:

Привет!

Пишу индикатор вывода графика на другом графике,

но появляется ошибка с нулевым значение буферов.

Приветствую. Скорее всего, ошибка здесь:

int diff = rates_total - prev_calculated;
       if(diff>0)
       {
         for(int i=diff-1; i>0; i++)
         {
           Buffer1[i] = Buffer1[i+1];
           Buffer2[i] = Buffer2[i+1];
           Buffer3[i] = Buffer3[i+1];
           Buffer4[i] = Buffer4[i+1];
         }
       }

Вы пытаетесь контролировать приход нового бара, тогда diff = 1. Но в цикле Вы из 1 вычитаете 1, следовательно значения не записываются, т.е. записываются пустые.

Добавлено:

Однако, если это расчет на истории, тогда я не прав.

А, нет, по-идее ошибка логики тут. История рассчитывается в блоке prev_calculated == 0. Здесь же prev_calculated != 0, а значит либо этого кода быть не должно (т.к. он все равно не выполняется), либо ошибка.

 

у меня картинка появилась, повесил на график, 2 раза скомпилировал

хотя ошибку выдает 4401

Доступ к истории

 

 

ERR_HISTORY_NOT_FOUND

4401

Запрашиваемая история не найдена



 

Спасибо, нашел ошибку, "0" появлялся в буферах на новой свече.

Исправил так:

else
     {
       int diff = rates_total - prev_calculated;
       if(diff>0)
       {
         for(int i=diff-1; i>0; i++)
         {
           Buffer1[i] = Buffer1[i+1];
           Buffer2[i] = Buffer2[i+1];
           Buffer3[i] = Buffer3[i+1];
           Buffer4[i] = Buffer4[i+1];
         }
       }
       Buffer1[0]= EMPTY_VALUE;
       Buffer2[0] = EMPTY_VALUE;
       Buffer3[0] = EMPTY_VALUE;
       Buffer4[0] = EMPTY_VALUE;
     }

Теперь всё ОК
 

 
prostotrader:

Теперь всё ОК

Это не OK. Если CopyRates возвращает ноль, то должен быть return(rates_total - 1).

Ваша "ошибка" в оригинале не будет давать о себе знать, если чарт MIX-12.16 открыть рядом с чартом, где висит индикатор. Рядом - все чарты не максимизированы.

Дело в том, что когда чарт максимизирован, то формирование новых баров на других чартах прекращается - экономия ресурсов, видимо. Поэтому CopyRates обламывается при первом запросе нового бара.

 
fxsaber:

Это не OK. Если CopyRates возвращает ноль, то должен быть return(rates_total - 1).

Ваша "ошибка" в оригинале не будет давать о себе знать, если чарт MIX-12.16 открыть рядом с чартом, где висит индикатор. Рядом - все чарты не максимизированы.

Дело в том, что когда чарт максимизирован, то формирование новых баров на других чартах прекращается - экономия ресурсов, видимо. Поэтому CopyRates обламывается при первом запросе нового бара.

Это Вы проверяли? Или это Ваши умозаключения?

У меня оба графика открыты и почему-то всё работает.


 

В клиринг на ДЕМО (19-00)

обратил внимание, что свеча 19-00 не появилась в индикаторе

 

Это связано с демо или ошибка? 

 
prostotrader:

Спасибо, нашел ошибку, "0" появлялся в буферах на новой свече.

Исправил так

Теперь всё ОК
 

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

Лучше сделать так:

else
     {
      if( rates_total > prev_calculated )
       {
           Buffer1[1] = Buffer1[2];
           Buffer2[1] = Buffer2[2];
           Buffer3[1] = Buffer3[2];
           Buffer4[1] = Buffer4[2];
          
        Buffer1[0]= EMPTY_VALUE;
        Buffer2[0] = EMPTY_VALUE;
        Buffer3[0] = EMPTY_VALUE;
        Buffer4[0] = EMPTY_VALUE;
       }      
     }
На всякий случай можно сделать в цикле for( int i = rates_total-prev_calculaded; i > 0; i-- ) { // запись предыдущих значений } // Обнуление текущего. Достаточно один раз при формировании новой свечи.
 
prostotrader:

Это Вы проверяли? Или это Ваши умозаключения?

У меня оба графика открыты и почему-то всё работает.

Вот именно, когда оба графика открыты, и будет работать. Читайте внимательнее, что написано.
 
Alexey Kozitsyn:

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

Лучше сделать так:

else
     {
      if( rates_total > prev_calculated )
       {
           Buffer1[1] = Buffer1[2];
           Buffer2[1] = Buffer2[2];
           Buffer3[1] = Buffer3[2];
           Buffer4[1] = Buffer4[2];
          
        Buffer1[0]= EMPTY_VALUE;
        Buffer2[0] = EMPTY_VALUE;
        Buffer3[0] = EMPTY_VALUE;
        Buffer4[0] = EMPTY_VALUE;
       }      
     }
Нет, ВЫ не правы. Это значение переписывается только один раз, при появлении нового бара, но так как может быть не 1, а несколько баров, то я "подтягиваю" график на N-баров - 1.
 
fxsaber:
Вот именно, когда оба графика открыты, и будет работать. Читайте внимательнее, что написано.

И при закрытом MIX-12.16 тоже работает.

Вы часто говорите:

"Чего болтать, лучше проверьте!"

добавлено