При переключении TimeFrame на панеле инструментов индикатор рисует неверно

 
Здравствуйте Уважаемые профессионалы mql. Скажите пожалуйста, почему индикатор со стрелками типа Fractals рисует стрелки в разных местах графика, после повторного переключения TimeFrame стрелки рисуются правильно. На TF H4 всегда рисуются неправильно, хотя в тестере все работает? Файл прилагаю.
Файлы:
AirFractals.mq5  13 kb
 
Ekaterina Belova:
Здравствуйте Уважаемые профессионалы mql. Скажите пожалуйста, почему индикатор со стрелками типа Fractals рисует стрелки в разных местах графика, после повторного переключения TimeFrame стрелки рисуются правильно. На TF H4 всегда рисуются неправильно, хотя в тестере все работает? Файл прилагаю.
//+------------------------------------------------------------------+
//|                                                  AirFractals.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2

//---- input parameters
//extern int       rpoint=150;
input string         strName1 = "";        //ФРАКТАЛЫ
input int       range_fractal = 5;         //ранг фрактала (нечётные числа не менее 3)
input int        nRangePoints = 15;        //Дистанция стрелок (в пипс)
input int               nBars = 200;       //Смотреть в историю на __ баров (0 - вся история)

input string         strName2 = "";        //ВИЗУАЛИЗАЦИЯ
input int           nWithdraw = 1;         //Толщина
input color             clrUp = clrGreen;  //Цвет стрелки "ВВЕРХ"
input color           clrDown = clrRed;    //Цвет стрелки "ВНИЗ"

//---- buffers
double Ext1[];
double Ext2[];
int center=0;

double cur=0;
bool found=false;
ENUM_TIMEFRAMES tfPeriod=0;
int counted_bars = 0;
int nRange_fractal = 0;
bool bFirst = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   bFirst = true;
   counted_bars = nBars;
//---- indicators
   nRange_fractal = range_fractal;
   if(nRange_fractal % 2 == 0)
      nRange_fractal++;
   if(nRange_fractal<3)
      nRange_fractal=3;
   center=nRange_fractal/2 + 1 ;
//scenter=range_fractal/2;

   SetIndexBuffer(0,Ext1,INDICATOR_DATA);
   SetIndexBuffer(1,Ext2,INDICATOR_DATA);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);

   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ARROW);
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_ARROW);

//--- зададим коды символом из набора Wingdings для свойств PLOT_ARROW
   PlotIndexSetInteger(0,PLOT_ARROW,217); // стрелка вверх
   PlotIndexSetInteger(1,PLOT_ARROW,218); // стрелка вниз

   PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrUp);
   PlotIndexSetInteger(1,PLOT_LINE_COLOR,clrDown);

   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,nWithdraw);
   PlotIndexSetInteger(1,PLOT_LINE_WIDTH,nWithdraw);

   PlotIndexSetString(0,PLOT_LABEL,"Up");
   PlotIndexSetString(1,PLOT_LABEL,"Down");
//PlotIndexSetString(2,PLOT_LABEL,"Atr");

//--- зададим cмещение стрелок по вертикали в пикселях

   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,-nRangePoints);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,nRangePoints);
//--- установим в качестве пустого значения 0
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);

   ArraySetAsSeries(Ext1,true);
   ArraySetAsSeries(Ext2,true);


   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   for(int i=ObjectsTotal(ChartID())-1; i>=0; i--)
     {
      string szNameObj=ObjectName(ChartID(),i);
      if(StringFind(szNameObj,"96635")>-1)
        {
         ObjectDelete(ChartID(),szNameObj);
        }
     }
   Comment("");
  }
//+------------------------------------------------------------------+
//| 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);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(open,true);

//tfPeriod = Period();
   int limit = rates_total - prev_calculated;
   if(limit>1)
     {
      ArrayInitialize(Ext1,0);
      ArrayInitialize(Ext2,0);
     }
   if(bFirst)
     {
      if(nBars==0)
         limit = rates_total - (1+2*center);
      else
         limit = fmin(nBars,rates_total-(1+2*center));
     }

   if(limit>0)
      limit+=nRange_fractal-1;
//----
   for(int i=limit; i>=0; i--)
     {
      Ext1[i]=Ext2[i]=0;
      //*******create history******
      //*******fractal up**********
      found=false;
      cur=high[i+center];
      if(cur>high[i+1] && cur>high[i+nRange_fractal])
         found=true;
      else
         found=false;
      if(found)
        {
         for(int j=1; j<center; j++)
           {
            if(cur>=high[i+center-j] && cur>=high[i+center+j])
               found=true;
            else
              {
               found=false;
               break;
              }
           }
        }
      if(found)
        {
         Ext1[i+1]=high[i+1];
         Ext1[i+2]=0;
        }
      //*************fractal down*************
      found=false;
      cur=low[i+center];
      if(cur<low[i+1] && cur<low[i+nRange_fractal])
         found=true;
      else
         found=false;
      if(found)
        {
         for(int k=1; k<center; k++)
           {
            if(cur<=low[i+center-k] && cur<=low[i+center+k])
               found=true;
            else
              {
               found=false;
               break;
              }
           }
        }
      if(found)
        {
         Ext2[i+1]=low[i+1];
         Ext2[i+2]=0;
        }
     }
   if(bFirst)
     {
      ChartRedraw();
      bFirst = false;
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+

Буферы индикаторов сначала нужно инициализировать пустым значением при первом запуске.

Если для расчётов используете текущий символ и период графика, то не нужно обращаться к функции iBars() - эти данные есть в предопределённой переменной rates_total.

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

Остальное тоже вызывает вопросы. Странные переменные со странным назначением...

 
Artyom Trishkin #:

Буферы индикаторов сначала нужно инициализировать пустым значением при первом запуске.

Если для расчётов используете текущий символ и период графика, то не нужно обращаться к функции iBars() - эти данные есть в предопределённой переменной rates_total.

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

Остальное тоже вызывает вопросы. Странные переменные со странным назначением...

Большое спасибо.

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