Have issue with MT5 indicator on reloading MT5 app

 

I created a  MT5 indicator. It seems to work but has a problem when reloading MT5 for a higher timeframe than the chart period:

recompile or dragg and drop

above: recompile or drag and drop

on reloading app

above: reloading the MT5 application

//+------------------------------------------------------------------+
//|                                                          Atr.mqh |
//|                                    Copyright 2019, Robert Baptie |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "lamar"
#property link      "https://www.mql5.com"
#property version   "1.00"
//#include <INCLUDE_FILES\\WaveLibrary.mqh>
#include <Indicators\Oscilators.mqh>
class CAtr : public CiATR
  {
private :
   //int               m_period;
   //struct sAtrStruct
   //  {
   //   double         tr;
   //   double         sum;
   //  };
   //sAtrStruct        m_array[];
   //int               m_arraySize;
public :
   bool              timedEvent;
   bool              haveData;
   void              CAtr::CAtr();
   void              CAtr::~CAtr();
   color             CAtr::findColor(int _index);
   int               CAtr::findIndexPeriod(ENUM_TIMEFRAMES _TF);
   bool              Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period);
  };
//+------------------------------------------------------------------+
//|Constructor                                                       |
//+------------------------------------------------------------------+
CAtr::CAtr()
  {
   timedEvent=false;
   haveData = false;
   return;
  }
//+------------------------------------------------------------------+
//| Initialize                                                             |
//+------------------------------------------------------------------+
//bool              Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int ma_period)
//  {
//  if()
//   return true;
//  else
//   return false;
//  }
//+------------------------------------------------------------------+
//|return index of tf passed in                                      |
//+------------------------------------------------------------------+
int CAtr::findIndexPeriod(ENUM_TIMEFRAMES _TF)
  {
   ENUM_TIMEFRAMES allTimeFrames[22] =
     {
      PERIOD_M1,
      PERIOD_M2,
      PERIOD_M3,
      PERIOD_M4,
      PERIOD_M5,
      PERIOD_M6,
      PERIOD_M10,
      PERIOD_M12,
      PERIOD_M15,
      PERIOD_M20,
      PERIOD_M30,
      PERIOD_H1,
      PERIOD_H2,
      PERIOD_H3,
      PERIOD_H4,
      PERIOD_H6,
      PERIOD_H8,
      PERIOD_H12,
      PERIOD_D1,
      PERIOD_W1,
      PERIOD_MN1,
      PERIOD_CURRENT
     };
   for(int i=0; i<ArraySize(allTimeFrames); i++)
      if(_TF==allTimeFrames[i])
         return i;
   Print(__FUNCTION__," Error: TF Not Found");
   DebugBreak();
   return -1;
  }
//+------------------------------------------------------------------+
//|return color of index passed in                                   |
//+------------------------------------------------------------------+
color CAtr::findColor(int _index)
  {
   color allColors[22] =
     {
      clrPink,
      clrPaleTurquoise,
      clrGreen,
      clrAliceBlue,
      clrLightBlue,
      clrCrimson,
      clrDeepPink,
      clrOliveDrab,
      clrLightGreen,
      clrChocolate,
      clrWhite,
      clrRed,
      clrWhiteSmoke,
      clrCoral,
      clrBurlyWood,
      clrDarkOrange,
      clrDarkSeaGreen,
      clrDarkKhaki,
      clrCornflowerBlue,
      clrLightSlateGray,
      clrChartreuse,
      clrOlive
     };
   return allColors[_index];
   Print(__FUNCTION__," Error: colr from index Not Found");
   DebugBreak();
   return NULL;
  }
//+------------------------------------------------------------------+
//|Destructor                                                        |
//+------------------------------------------------------------------+
CAtr::~CAtr()
  {
   return;
  }
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//|                                                 Copyright © 2020 |
//+------------------------------------------------------------------+
#property description "ATR, Multi-timeframe"
//#include <INCLUDE_FILES\\WaveLibrary.mqh>
#include <CLASS_FILES\CAtr.mqh>
enum ENUM_CAT_ID {TRD,VOL};
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "ATR"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
input ENUM_TIMEFRAMES      waveHTFPeriod  =  PERIOD_M2;      // Timeframe 2 (TF2) period
input int                  inpAtrPeriod   =  14; // ATR period
input ENUM_LINE_STYLE      lineStyle      =   STYLE_DOT;//Line Style
input ENUM_CAT_ID          catalystID =  TRD;// TRD or VOL
//input bool                 showErrorMessages = false;
//int htfIndex=findIndexPeriod(waveHTFPeriod);
double valATR[];
//bool timedEvent = false;
int               bufferSize  =  -1;
static datetime   time0       =  NULL;
int               limit       =  NULL;
static int        htfShift    =  -1;
static int        pHtfShift   =  -1;
CAtr iAtr;
//+------------------------------------------------------------------+
//| OnInit                                                           |
//+------------------------------------------------------------------+
int OnInit()
  {
// map index buffers
   SetIndexBuffer(0,valATR,INDICATOR_DATA);
//--- set buffers as series, most recent entry at index [0]
   ArraySetAsSeries(valATR,true);
//--- set color for tf
   PlotIndexSetInteger(0, PLOT_LINE_COLOR,    iAtr.findColor(iAtr.findIndexPeriod(waveHTFPeriod)));
   PlotIndexSetString(0,PLOT_LABEL,"ATR("+EnumToString(catalystID)+":"+string(inpAtrPeriod)+":"+EnumToString(waveHTFPeriod)+")");
//--- Set the line drawing
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE, lineStyle);
   IndicatorSetString(INDICATOR_SHORTNAME,"ATR("+EnumToString(catalystID)+":"+string(inpAtrPeriod)+":"+EnumToString(waveHTFPeriod)+")");
//--- get ATR handle
   iAtr.Create(_Symbol,waveHTFPeriod,inpAtrPeriod);
   int waitMS = 1;
   Print("-----------------------",TimeCurrent(),"--------------------------");
   EventSetMillisecondTimer(waitMS);
   Print("OnTimer set to ",waitMS," ms");
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|ensure have a refreshed dataset for indicator                     |
//+------------------------------------------------------------------+
void OnTimer()
  {
   ResetLastError();
   iAtr.Refresh();
   CIndicatorBuffer *buff = iAtr.At(0);
   if(!iAtr.timedEvent && (buff.Total() > 0))
     {
      EventKillTimer();
      iAtr.timedEvent = true;
     }
   else
      Print(__FUNCTION__, "buffer size < 1 ",GetLastError());
  }
//+------------------------------------------------------------------+
//| OnCalculate                                                      |
//+------------------------------------------------------------------+
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[])
  {
   if(!iAtr.timedEvent)
     {
      Print(__FUNCTION__," not processing rates no timed event yet "+TimeToString(TimeCurrent()));
      return rates_total;
     }
   if(!iAtr.haveData)
     {
      // first pass
      iAtr.haveData =true;
      limit=rates_total-1;
      Print(__FUNCTION__," limit !havedata: ",limit," will process all bars because have data from Refresh insruction "+TimeToString(TimeCurrent()));
     }
   else
     {
      limit=rates_total-prev_calculated;
      if(limit > 0)
         limit -=1;
     }
// new bar of CTF?
   datetime tda[];
   ArraySetAsSeries(time,true);
   bool isNewBar=(time0!=time[0]);
   if(isNewBar)
     {
      Print(__FUNCTION__," limit:  ",limit);
      time0=time[0];
        {
         ResetLastError();
         CIndicatorBuffer *buff = iAtr.At(0);
         bufferSize = buff.Total();
         if(bufferSize <= 0)
           {
            iAtr.Refresh();
            Print(__FUNCTION__, " Failure 1: size been reset < 1 Attempt to refresh Rates because buffersize < 0 "+TimeToString(TimeCurrent()));
           }
         if(bufferSize <= 0)
            Print(__FUNCTION__, " Failure 2: Buffer size < 1 after Reset ",GetLastError());
         else
           {
            for(int shift=limit; shift>=0; shift--)//start rates_total down to zero
              {
               if(shift>(rates_total-inpAtrPeriod-1))
                  continue;
               else
                 {
                  htfShift=iBarShift(_Symbol,waveHTFPeriod,time[shift],true);
                  pHtfShift=iBarShift(_Symbol,waveHTFPeriod,time[shift+1],true);
                  if((shift == 0) || (shift == rates_total-inpAtrPeriod-1))
                     Print("shift ",shift," limit ",limit," time[shift] ",time[shift]," time,[shift+1] ",time[shift+1], " hffshift ",htfShift," pHtfShift ",pHtfShift);
                  if((pHtfShift == -1) || (htfShift == -1))
                     continue;
                  if(htfShift != pHtfShift)
                    {
                     double tempATRArray[];
                     if(CopyBuffer(iAtr.Handle(),0,htfShift,1,tempATRArray)<=0)
                        Print(__FUNCTION__," failed to get ATR buffer, phtfShoft: "+IntegerToString(pHtfShift));
                     else
                        valATR[shift]=tempATRArray[0];
                     continue;
                    }
                  else
                     valATR[shift]=valATR[shift+1];
                 }
              }
           }
        }
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| OnDeinit                                                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+


I cant understand why iBarshift returns -1 (see trace for index on reloading the MT5 app above).

I see I can override a Initialise stub of CAtr (ATR object code above), but am at a loss as to what to reset/include to get it operating correctly

Any direction appreciated

 

https://www.mql5.com/en/articles/5

Reading the manual helped ... IndicatorsCounted section.

   if(!iAtr.timedEvent)
     {
      Print(__FUNCTION__," !timedEvent ");
      return rates_total;
     }
   else if(!iAtr.haveData)
     {
      // first pass
      iAtr.haveData = true;
      return (1);
      Print(__FUNCTION__," !havedata, limit: ",limit);
     }
   else
     {
      limit=rates_total-prev_calculated;
      if(limit > 0)
         limit -=1;
     }
//.
//.
//.

So specific problem I made is solved and I now have opportunity to check out and develop the code