Buffers shift to the left when new data is loaded

 

Hello 

I have this system which is supposed to wait until a number of bars has been loaded on the chart of the indicator.

(or that's what i think it achieves)

Why ? the calculation that has to "result" in a "signal" has to be done strictly in a sequence and with a minimum required amount of data.(bars)

Here is the problem i can't figure out.

Regardless of whether or not i use as series index buffers (or not), if the indicator splices or loads more data in the past 

then the output buffers move to the left.

In this replication test i am drawing the highs and lows on the output buffers to track the issue better.

So when new data comes in on a chart that does not have the required data amount yet the buffers start shifting to the left.

Thanks.

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
double bufferH[],bufferL[];
/*
TESTS : 
[x] If we have decided to render , and , more bars are added later
    will the indicator AUTO shift the CALCULATED indexes correctly ?
    -NO!
[x] Blockade of calcs until min bars for timeframe exist and custom 
    first initialization without waiting for ticks
    -DONE but if the delta of added bars is yuge it does not shift!  
*/
//state control
  ENUM_TIMEFRAMES CONTROL_TFS[]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
     int CONTROL_TFS_MIN_BARS[]={60000,30000,20000,10000,10000,6000,2500,500,100};
  bool CONTROL_stabilized=false;
  int CONTROL_bars_loaded=0,CONTROL_bars_processed=0;
  datetime CONTROL_first_bar_time=0,CONTROL_last_bar_time=0;
  uint CONTROL_last_ms_of_bars_change=0;
  int CONTROL_active_tf=-1;
  bool CONTROL_BUSY=false;
  void reset_control(){
       CONTROL_BUSY=false;
       CONTROL_active_tf=-1;
       CONTROL_stabilized=false;
       CONTROL_bars_loaded=iBars(_Symbol,_Period);
       CONTROL_bars_processed=0;
       CONTROL_first_bar_time=0;
       CONTROL_last_bar_time=0;
       if(CONTROL_bars_loaded>0){
         CONTROL_first_bar_time=iTime(_Symbol,_Period,CONTROL_bars_loaded-1);
         CONTROL_last_bar_time=iTime(_Symbol,_Period,0);
         }
       CONTROL_last_ms_of_bars_change=GetTickCount();
       for(int i=0;i<ArraySize(CONTROL_TFS);i++){
          if(_Period==CONTROL_TFS[i]){CONTROL_active_tf=i;break;}
          }
       Print("CONTROL::Active timeframe "+EnumToString(CONTROL_TFS[CONTROL_active_tf])+" initial bars ("+IntegerToString(CONTROL_bars_loaded)+"/"+IntegerToString(CONTROL_TFS_MIN_BARS[CONTROL_active_tf])+")");
       }

int OnInit()
  {
  SetIndexBuffer(0,bufferH);PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrCyan);
  SetIndexBuffer(1,bufferL);PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);PlotIndexSetInteger(1,PLOT_LINE_COLOR,clrOrangeRed);
  ArrayFill(bufferH,0,ArraySize(bufferH),0.0);
  ArrayFill(bufferL,0,ArraySize(bufferL),0.0);
  ArraySetAsSeries(bufferH,true);
  ArraySetAsSeries(bufferL,true);
  reset_control();
  return(INIT_SUCCEEDED);
  }
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(!ArrayGetAsSeries(time)){
    ArraySetAsSeries(open,true);
    ArraySetAsSeries(high,true);
    ArraySetAsSeries(low,true);
    ArraySetAsSeries(close,true);
    ArraySetAsSeries(time,true);
    }
  if(CONTROL_stabilized){
  Comment("Normal "+IntegerToString(ArraySize(time)));
  }else{
  int errors=0;
  ResetLastError();
  datetime last_tick=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME);
  errors+=GetLastError();ResetLastError();
  int psecs=PeriodSeconds(_Period);
  errors+=GetLastError();ResetLastError();
  //ifno errorrs
  if(errors==0&&ArraySize(time)>0){
  //we want the bar to be the latest !
  datetime minbartime=(datetime)((long)last_tick-(long)psecs*2);
  if(time[0]>=minbartime){
  if(SymbolIsSynchronized(_Symbol)||(CONTROL_active_tf>=0&&ArraySize(time)>=CONTROL_TFS_MIN_BARS[CONTROL_active_tf])){
    int new_bars=ArraySize(time);
    if(new_bars>CONTROL_bars_loaded){
      CONTROL_last_ms_of_bars_change=GetTickCount();
      CONTROL_bars_loaded=new_bars;
      CONTROL_first_bar_time=time[ArraySize(time)-1];//iTime(_Symbol,_Period,CONTROL_bars_loaded-1);
      CONTROL_last_bar_time=time[0];//iTime(_Symbol,_Period,0);
      }
      Comment("Synchronizing...["+TimeToString(last_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"]\nBars "+IntegerToString(CONTROL_bars_loaded)+"/"+IntegerToString(CONTROL_TFS_MIN_BARS[CONTROL_active_tf])+"\nloaded("+IntegerToString(CONTROL_bars_loaded)+")arrays("+IntegerToString(ArraySize(bufferH))+")");
    //if load is enough
      if(CONTROL_bars_loaded>=CONTROL_TFS_MIN_BARS[CONTROL_active_tf]&&CONTROL_bars_loaded==ArraySize(bufferH)){
        //do initial load HERE
          ArrayFill(bufferH,0,ArraySize(bufferH),0.0);
          ArrayFill(bufferL,0,ArraySize(bufferL),0.0);
            for(int i=ArraySize(time)-1;i>=0;i--){
               bufferH[i]=high[i];//iHigh(_Symbol,_Period,i);
               bufferL[i]=low[i];//iLow(_Symbol,_Period,i);
               }
            CONTROL_bars_processed=CONTROL_bars_loaded;
        CONTROL_stabilized=true;
        Comment("Stabilized");
        }
    //if load is enough ends here 
    } 
  }////we want the bar to be the latest ! ends here
  }//if no errors ends here   
  }
  return(rates_total);
  }


void OnDeinit(const int reason)
  {
  reset_control();
  }
 
You have to check if prev_calculated is 0 to reset the data and start fresh calculation.
 
Samuel Manoel De Souza #:
You have to check if prev_calculated is 0 to reset the data and start fresh calculation.

thanks