MT4 drawing error when candles are deleted - page 2

 
Laszlo Csipkes #:

Excuse me, but the predefined Time[], Low[],High[] etc. arrays are just as much a part of the programming language as the low[] array received in the parameter list.
There’s no 'deprecated' label next to them in the documentation, so why their its use not recommended?
I'll replace the array references and see if that solves the problem.

Here is the link to the documentation for the Time[] array: http://docs.mql4.com/predefined/time

I don’t see anything in the description indicating that this couldn’t be used in the OnCalculate() function. Where can I find information on exactly what can and cannot be used within the OnCalculate function?

Please understand the difference between the globally scoped predefined variables and the locally provided parameters passed by the OnCalculate() handler. They are not the same and in certain situations their data can be completely different.

So, depend only the locally passed parameters as much as possible. Don't mix the two concepts. This is important.

As stated, in most cases you will not notice the problem, but when the exceptions come up you will realise the issue if you do it incorrectly. So, do it correctly from the start.

PS! This is a question of proper programming and best practice of the newer MQL4+ versus the older MQL4 way of doing things. Don't mix the two up.

 
William Roeder #:
Where do you reset those buffers to EMPTY_VALUE when the conditions are not met?
I don't understand the question.
If I place a signal on an M1 candle starting at a round hour (for example, 06:00), why would I need to monitor it later? Could the start time of the candles change retroactively?
 
Laszlo Csipkes #: I don't understand the question. If I place a signal on an M1 candle starting at a round hour (for example, 06:00), why would I need to monitor it later? Could the start time of the candles change retroactively?

In your code, you assign values to the buffers when certain conditions are met, but never assign any value when the the conditions are NOT met.

So, what value should the buffers have when the conditions are NOT met? The most probable answer is EMPTY_VALUE (it depends on what you want to achieve).

Here is a clue in pseudo code (two variants of the same thing) ...

buffer[ index ] = condition ? value : EMPTY_VALUE;
if( condition )
  buffer[ index ] = value;
else
  buffer[ index ] = EMPTY_VALUE;
 
Laszlo Csipkes #:
If you set the 'Max Bars in Chart' value, MT4 periodically deletes the oldest candles to maintain this number (as I’ve observed, and indicator monitoring also confirmed, it deletes 128 candles).

I can't reproduce it. I set 'Max Bars in Chart' = 10 and attached a test indicator when there were 10 bars on the chart. It's been 2 hours, there are already over 140 bars on the chart and the terminal hasn't deleted anything yet.


 
Vladislav Boyko #:

I can't reproduce it. I set 'Max Bars in Chart' = 10 and attached a test indicator when there were 10 bars on the chart. It's been 2 hours, there are already over 140 bars on the chart and the terminal hasn't deleted anything yet.

I suspect that the terminal will truncate the predefined timeseries arrays, but will not truncate the indicator buffers and the OnCalculate function parameter arrays.

But my terminal does not want to truncate anything at all.

 
Fernando Carreiro #:

In your code, you assign values to the buffers when certain conditions are met, but never assign any value when the the conditions are NOT met.

So, what value should the buffers have when the conditions are NOT met? The answer is EMPTY_VALUE!

Here is a clue in pseudo code (two variants of the same thing) ...

I rewrote it as requested and also added an EMPTY_VALUE initialization (although the system fills the buffers with EMPTY_VALUE by default, I've checked this multiple times).
We'll see if there will be any signal issues.
Thanks for the advice!

#property strict
#property indicator_chart_window
#property indicator_buffers 3

double buff_a[], buff_b[], buff_c[];
int limit, mins;

int OnInit(){
   
   SetIndexBuffer(0, buff_a);
   SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID, 1, clrLightBlue);
   SetIndexArrow(0, 108);
   
   SetIndexBuffer(1, buff_b);
   SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID, 2, clrOrange);
   SetIndexArrow(1, 108);
   
   SetIndexBuffer(2, buff_c);
   SetIndexStyle(2, DRAW_ARROW, STYLE_SOLID, 3, clrGreen);
   SetIndexArrow(2, 108);
   
   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[]){
   
   limit = (int)MathMin(rates_total - 1, rates_total - prev_calculated);
   
   for(int index = limit; index > 0; index--){
      buff_a[index] = EMPTY_VALUE;
      buff_b[index] = EMPTY_VALUE;
      buff_c[index] = EMPTY_VALUE;
      
      mins = TimeMinute(time[index]);
      
      if(mins % 60 == 0){
         buff_c[index] = low[index] - (high[index] - low[index]);
      }else if(mins % 30 == 0){
         buff_b[index] = low[index] - (high[index] - low[index]);
      }else if(mins % 15 == 0){
         buff_a[index] = low[index] - (high[index] - low[index]);
      }
   }
   
   return(rates_total);
}
 
Vladislav Boyko #:

I suspect that the terminal will truncate the predefined timeseries arrays, but will not truncate the indicator buffers and the OnCalculate function parameter arrays.

But my terminal does not want to truncate anything at all.

When I noticed, I changed the limit value to 200 candles, and then it didn't delete for me either.
However, after I set the limit back to 50.000, it appeared again.

Now, I'll start testing with the rewritten indicator and see if there will be any further signal shifts.

 
Laszlo Csipkes #:
Now, I'll start testing with the rewritten indicator and see if there will be any further signal shifts.

Of course, there will be no shifts if you abandon the predefined time series arrays and use only the parameters of the OnCalculate function.

 
Laszlo Csipkes #:
However, after I set the limit back to 50.000, it appeared again.

Limit 50000 bars. For almost 3 hours of the indicator's operation on the M1 timeframe, the terminal did not delete anything. I can't reproduce the situation you described where the terminal deletes bars.

The indicator I ran (your indicator + logging):

#property strict
#property indicator_chart_window
#property indicator_buffers 1

double buff_a[];
int limit, mins;

int OnInit(){
   
   SetIndexBuffer(0, buff_a);
   SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID, 1, clrLightBlue);
   SetIndexArrow(0, 108);
   return(INIT_SUCCEEDED);
}

#define _toStr(a) StringFormat(#a" = %i; \n", a)
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[]){
   
   limit = (int)MathMin(Bars - 1, rates_total - prev_calculated);
   for(int index = limit; index > 0; index--){
      mins = TimeMinute(Time[index]);
      if(mins % 15 == 0){
         buff_a[index] = Low[index] - (High[index] - Low[index]);
      }
   }
   static string  text = "";
   text = _toStr(rates_total) + _toStr(Bars) + _toStr(ArraySize(High)) + _toStr(ArraySize(high)) + _toStr(ArraySize(buff_a)) + _toStr(prev_calculated);
   Comment(text);
   if(rates_total != prev_calculated)
      Print(text);
   return(rates_total);
}
#undef _toStr

void OnDeinit(const int reason) { Comment(""); }
 

Thank you for your help! After 1.5 days of testing, the chart finally isn't falling apart.

I will now rewrite the original indicator, and I hope this will resolve the issue there as well.


However, I’d like to know where I can find information about deprecated functions and arrays. Thanks in advance!