Indicator stops working after manual refresh of the window

 

Hi All,

I created a custom indicator which draws lines by ObjectCreate function. In general it works how it is expected. If i remove it from chart it remove all created objects. And in general did not have any issue. However after I make right-click refresh it stops working and all objects remain on the chart. I have a feeling that it restart indicator but without calling Deinit. Do you know exactly what is happening after restart? I do not know how to avoid this issue. Please advice. 

#property copyright             "Pavel 2020"
#property version                       "1.00"
#property description   "Индикатор тенденции для заданного таймфрейма"
#property strict
#property indicator_chart_window
#property indicator_buffers   0
#property indicator_plots     0 

input ENUM_TIMEFRAMES timeFrame = PERIOD_H1; //Таймфрейм
input group           "Отображение";
input color Color=Red;                       //Цвет
input ENUM_LINE_STYLE   Style=STYLE_SOLID;   //Тип линии
input int   Width=1;                         //Толщина линии
input group           "Общие настройки";     
input int                       MaxBars = 1000;            //Количество баров
input bool                      ShowError = false;         //Выводить ошибки



double DataBuffer[];
double ColorBuffer[];
double lastValue = 0;
datetime lastTime;
int IndicatorHandler;
double direction = 0;
int lineId = 0;
string prefix = "";
datetime lastBarTime;
int calculated = 0;
long chartId = 0; 


void OnInit()
{
   chartId = ChartID();
   if (timeFrame < Period()){ 
      Alert("Выбраный таймфрейм должен быть больше текущего");
      return;   
   }
   
   IndicatorHandler = iCustom(Symbol(), timeFrame, "TendencyRinaz","",false);
   if (IndicatorHandler== INVALID_HANDLE){
      Alert("Индикатор TendencyRinazSource отвсутсвует в директории Indicators");
      return;
   }

   prefix = "Tendency(Rinaz) HTF " + timeFrame+" ";
}

void OnDeinit(const int reason)
{
   Alert("OnDeinit()");
   IndicatorRelease(IndicatorHandler);
   DeleteLines();
   ChartRedraw( chartId);
   
}
  
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[]
)
{
   double values1[];
   double values2[];
   double colors[];
   int start = 0;
   int barsInTF;

   if (GetLastError()!=0)
   {
      ShowError("");
   }
   
   if(BarsCalculated(IndicatorHandler) == -1){
      ShowError("Данный старшего таймфрейма не готовы. Индиктор работает с задержками при закрытом рынке.");
      return (calculated);
   }
   if( calculated == 0 )
        {
                ArrayInitialize( DataBuffer, 0.0 );
           lastValue = 0;
                if( rates_total > MaxBars )
                        start = rates_total - MaxBars ;
        }
        else
        {
                start = calculated;
   }
   
   barsInTF = Bars(Symbol(), timeFrame, Time[0], Time[start]);//Time[rates_total - 1]);
   
   
   if (CopyBuffer(IndicatorHandler, 0, 0, barsInTF, values1) != barsInTF )
   {
      ShowError("Данные старшего таймфрейма (Values) не готовы. Индиктор работает с задержками при закрытом рынке.");
      return(calculated);
   }
   if (CopyBuffer(IndicatorHandler, 1, 0, barsInTF, values2) != barsInTF)
   {
      ShowError("Данные старшего таймфрейма (Colors) не готовы. Индиктор работает с задержками при закрытом рынке.");
      return(calculated);
   }
   if(BarsCalculated(IndicatorHandler) < barsInTF)
   {
      ShowError("Не все данный старшего таймфрейма были обработаны. Индиктор работает с задержками при закрытом рынке.");
      return(calculated);
   } 

   for( int i = start; i < rates_total-1; i++ )
   { 
      int shift = iBarShift(Symbol(), timeFrame, Time[i], true);
      if ((shift == -1) || (shift >= barsInTF))
      {
         DataBuffer[i] = 0;
         continue;
      }
      
      if(values1[barsInTF - shift - 1] == high[i] ||  values1[barsInTF - shift - 1] == low[i])
      {
         addPivot(values1[barsInTF - shift - 1],Time[i]);
         calculated = i+1;
      }
      
      if(values2[barsInTF - shift - 1] == high[i] ||  values2[barsInTF - shift - 1] == low[i])
      {
         addPivot(values2[barsInTF - shift - 1],Time[i]);
         calculated = i+1;
      }
   }
   Alert("5");
   lastBarTime = Time[0];
      return(calculated);
}

void addPivot(double val, datetime time )
{
   
      
   if(lastValue==0)
   {
      lastValue = val;
      lastTime = time;
      direction = 0;
      return;
   }
   
   if(lastValue==val)
      return;
   if((direction == 1 && val > lastValue)||(direction == -1 && val < lastValue))
   {
      
      ObjectMove(chartId,prefix+lineId,1,time,val);
   }
   else
   {
      lineId ++;
      if(!ObjectCreate(chartId,prefix+lineId,OBJ_TREND,0,lastTime,lastValue,time,val))
      {
         ShowError("Невозможно создать линию");
         return;
      }
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_COLOR,Color);
      //ObjectSetInteger(0,"Tendency"+lineId,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_STYLE,Style);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_WIDTH,Width);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_BACK,true);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_SELECTED,false);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_RAY_LEFT,false);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_RAY_RIGHT,false);
      ObjectSetInteger(chartId,prefix+lineId,OBJPROP_HIDDEN,true);
      
      if(lastValue < val)
         direction = 1;
      else
         direction = -1;
   }

   lastValue = val;
   lastTime = time;

}

void DeleteLines()
{
   for(int i=1;i<=lineId;i++)
   {
      if(ObjectFind(chartId,prefix+i)>=0)
      {
         ObjectDelete(chartId,prefix+i);
      }
   }
   lineId = 0;
}

void ShowError(string msg)
  {
   if (ShowError)
   {
      Alert ("TEndency (Rinaz) HTF Ошибка: " + GetLastError()+". "+msg);
      ResetLastError();
   }
   ResetLastError();
  }
  
  
 

I found a solution. The problem is that on right-click refresh Metatrader trigger an event Calculate (even handler OnCalculate) but with some weird input parameters for example prev_calculated is 0 and etc. Obviously it is a bug which needs to be fixed by MT team. I added these lines in the begging of OnCalculate and it works now. 

   if(calculated!=0 &&prev_calculated==0){
      return(calculated);
   }
 
Evdokimov1917: prev_calculated is 0 and etc. Obviously it is a bug which needs to be fixed by MT team. I added these lines in the begging of OnCalculate and it works now. 
  1. Not a bug. You refreshed, old data has been updated and all bars need to be recalculated — just like the initial run. Therefor prev_calculated must be zero.
  2. Fix your broken code. There is no need for your calculated variable, use the real prev_calculated.
  3. See How to do your lookbacks correctly.
Reason: