Download MetaTrader 5

CopyBuffer problem (bug?)

To add comments, please log in or register
mqltools
25
mqltools  

#property copyright ""
#property link      ""
#property version   "1.00"
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_plots 1
#property  indicator_color1  Silver
#property  indicator_width1  2
double     MacdBuffer[];
int        handle;
int OnInit()
  {
   SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_HISTOGRAM);
   handle=iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE);
   return(0);
  }

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 count = rates_total - prev_calculated;
   Print("count = ", count);
  
   //bug start - the error is present when count == 1
   double buf[];
   ArrayResize(buf, count);
   CopyBuffer(handle, 0, 0, count, buf);
   for(int i = 0; i < count; i++) MacdBuffer[i] = buf[i];
   //bug end
  
   //CopyBuffer(handle, 0, 0, count, MacdBuffer); // <--- WORKS

   return(rates_total);
  }

When count == 1, suddenly ALL displayed values of MacdBuffer are some completely bogus value (the same).

However, when CopyBuffer is used, everything works perfectly, even when count == 1.

This is just a proof of concept of code; I know intermediate buffer is redundant here. I found it while writing a custom indicator

 Bug present

 Bug present

 Bug not present

 

hasayama
626
hasayama  
Try to get rid of ArrayResize(buf, count). I believe CopyBuffer will do it by its own. Maybe it is the reason of your problem, as well.
Alexey Da
Moderator
6635
Alexey Da  

There is no bug.

Please check your code. When you copy 1 value, you are copying it to wrong place. You should copy buf[0] to MacdBuffer[rates_total-1] instead of MacdBuffer[0].

mqltools
25
mqltools  

I'm sorry, but that's not true. This results in INVERTED macd  (inversion in the whole domain of all bars).

But regardless, when count  == 1, everything still changes to one weird value.

   for(int i = 0; i < count; i++) MacdBuffer[rates_total-1-i] = buf[i];

 

The "nobug" chart uses (only) CopyBuffer; the "bug" chart uses this for.

Without for, ie MacdBuffer[rates_total-1] = buf[0], it just shows, for every tick, another bar from the end. No difference.

(note: there was no count == 1 value, so no weird one-value everywhere... yet) 

 

hasayama: You are right - it's redundant. But the problem still persists.

hasayama
626
hasayama  

hasayama: You are right - it's redundant. But the problem still persists.

Well, you are using ArrayResize for buf but not for MacdBuffer. If you don't use CopyBuffer, you should resize it manualy, I believe.

Use smth like:

 

ArrayResize( MacdBuffer, count );
for ...
mqltools
25
mqltools  

From Help

"The function can be applied only to dynamic arrays. Please note that you can't change the size for dynamic arrays set as indicator buffers by the function SetIndexBuffer(). " 

They are supposed to automatically resize themselves...

Documentation on MQL5: Standard Constants, Enumerations and Structures / Indicator Constants / Indicators Lines
  • www.mql5.com
Standard Constants, Enumerations and Structures / Indicator Constants / Indicators Lines - Documentation on MQL5
hasayama
626
hasayama  

Then my suggestion is not an option.

Any way, array must have size before you try to write data into it. Otherwise you'll get an unpredictable result.

mqltools
25
mqltools  

"Solved". It seems that all indicator buffers are cleared after each new tick.

This is in contrast to mql4.

Now, it's not a bug if this is written in the manual and by design - I didn't see it, but I may have missed it. Regardless, old mql4 way was better. What's the point in erasing old data? I know that when resizing reallocations may occur, but old data should be copied...

#property copyright ""
#property link      ""
#property version   "1.00"
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_plots 1
#property  indicator_color1  Silver
#property  indicator_width1  2

double     MacdBuffer[];
int        handle;

int OnInit()
  {
   SetIndexBuffer(0,MacdBuffer,INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_HISTOGRAM);
   handle=iMA(NULL,0,26,0,MODE_EMA,PRICE_CLOSE);
   return(0);
}
 
double x[];
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 count = rates_total - prev_calculated;
   Print("count = ", count);
   for(int i = 0; i < ArraySize(x); i++) MacdBuffer[i+count] = x[i];
   ArrayResize(x, rates_total);
  
   double buf[];
   ArrayResize(buf, count);
   CopyBuffer(handle, 0, 0, count, buf);
   for(int i = 0; i < count; i++) MacdBuffer[i] = buf[i];

   for(int i = 0; i < ArraySize(x); i++) x[i] = MacdBuffer[i];
   return(rates_total);
  }

Documentation on MQL5: Standard Constants, Enumerations and Structures / Indicator Constants / Indicators Lines
  • www.mql5.com
Standard Constants, Enumerations and Structures / Indicator Constants / Indicators Lines - Documentation on MQL5
To add comments, please log in or register