Let's try to solve this buffer refresh problem

 

I notice a refresh problem in the indicator when switching timeframe. I'm confused at what might be causing it. 

The buffers don't update properly when switching timeframe, and when right clicking the chart and clicking "refresh", everything updates in just one second. Even if I try ChartRedraw() anywhere in the script (or with a timer), it won't update the chart.

Only this refresh button seems to work, so could this be a bug of some kind? I tried altering the code different ways only to waste time unfortunately.


#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4

#property indicator_label1  "Up"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrBrown
#property indicator_width1  2

#property indicator_label2  "Down"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrBrown
#property indicator_width2  2

#property indicator_type3   DRAW_LINE
#property indicator_type4   DRAW_LINE
#property indicator_color3  clrPurple
#property indicator_color4  clrPurple


input int  iPeriods  = 10;

// Buffers
double DynR[];
double DynS[];
double arr_buf_up[];
double arr_buf_down[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {

//--- indicator buffers mapping
   SetIndexBuffer(0, arr_buf_up, INDICATOR_DATA);
   SetIndexBuffer(1, arr_buf_down, INDICATOR_DATA);  
   SetIndexBuffer(2,DynR,INDICATOR_DATA);
   SetIndexBuffer(3,DynS,INDICATOR_DATA);
   
   PlotIndexSetInteger(0,PLOT_ARROW,236);
   PlotIndexSetInteger(1,PLOT_ARROW,238);     
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,10);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-10);
  
   return(INIT_SUCCEEDED);
  }



long prev = 0;
//+------------------------------------------------------------------+
//| 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[])
  {
  
   int lastBar = rates_total-1;

   for(int i=lastBar;i>prev_calculated;i--){  
   
        arr_buf_up[i] = 0; 
        arr_buf_down[i] = 0;
    
        DynR[i] = iHigh(Symbol(), Period(), iHighest(_Symbol, _Period, MODE_HIGH,iPeriods,MathAbs(lastBar - i)));
        DynS[i] = iLow(Symbol(), Period(), iLowest(_Symbol, _Period, MODE_LOW, iPeriods,MathAbs(lastBar - i))); 
     
        
        if((i+2)<rates_total && DynR[i] > DynR[i-1] && DynR[i] == DynR[i+2]){
   
            if(prev != 1) arr_buf_down[i] = high[i];          
            prev = 1;
        }
   
        if((i+2)<rates_total && DynS[i] < DynS[i-1] && DynS[i] == DynS[i+2]){
   
            if(prev != 2) arr_buf_up[i] = low[i];        
            prev = 2;
        }         
   }
   
   return(rates_total);
}



The logic is working correctly after pressing the chart refresh button:


But why this needs to be done, I don't know

Files:
ArrowTest.mq5  3 kb
 
It's ok I have solved the issue
 
Conor Mcnamara #:
It's ok I have solved the issue

what was the solution? it will be helpful because i also faced this.

i am using hacks like ChartSymbolSetPeriod to make it work

 
Arpit T #:

what was the solution? it will be helpful because i also faced this.

i am using hacks like ChartSymbolSetPeriod to make it work

I basically turned it into a two-step process. Instead of using one loop, I used two. The first loop is used to calculate the two calculation buffers, the next loop will check the conditions.

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[])
  {
  
   int lastBar = rates_total-1;

   for(int i=lastBar;i>prev_calculated;i--){  
   
        DynR[i] = iHigh(Symbol(), Period(), iHighest(_Symbol, _Period, MODE_HIGH,iPeriods,MathAbs(lastBar - i)));
        DynS[i] = iLow(Symbol(), Period(), iLowest(_Symbol, _Period, MODE_LOW, iPeriods,MathAbs(lastBar - i)));      
   }
   
   
   for(int i=lastBar;i>prev_calculated;i--){  
   
        arr_buf_up[i] = 0; 
        arr_buf_down[i] = 0;

        if((i+2)<rates_total && DynR[i] > DynR[i-1] && DynR[i] == DynR[i+2]){
   
            if(prev != 1) arr_buf_down[i] = high[i];          
            prev = 1;
        }
   
        if((i+2)<rates_total && DynS[i] < DynS[i-1] && DynS[i] == DynS[i+2]){
   
            if(prev != 2) arr_buf_up[i] = low[i];        
            prev = 2;
        }         
   }
   
   return(rates_total);
}
 
Conor Mcnamara #:

I basically turned it into a two-step process. Instead of using one loop, I used two. The first loop is used to calculate the two calculation buffers, the next loop will check the conditions.

great. it looks like indicator thread problem and this is helpful.