CopyBuffer() getting wrong in dynamic array with SetIndexBuffer() !!!

 
CopyBuffer() can not used in Indicator with "shift != 0" or "start_pos >0" in dynamic array with SetIndexBuffer().
//--- indicator settings
#property indicator_buffers 3


//--- indicator buffers
double Buffer0[], Buffer1[], Buffer2[];

//--- handles for MAs
int    SMAHandle0, SMAHandle1, SMAHandle2;
//--- MA periods
input int FAST_PERIOD = 20;

int mashift_0 = 0, mashift_1 = 3, mashift_2 = 0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
 {
//--- indicator buffers mapping
  SetIndexBuffer(0, Buffer0, INDICATOR_DATA);
  SetIndexBuffer(1, Buffer1, INDICATOR_DATA);
  SetIndexBuffer(2, Buffer2, INDICATOR_DATA);

  SMAHandle0 = iMA(_Symbol, _Period, FAST_PERIOD, mashift_0, MODE_SMA, PRICE_CLOSE);
  SMAHandle1 = iMA(_Symbol, _Period, FAST_PERIOD, mashift_1, MODE_SMA, PRICE_CLOSE);
  SMAHandle2 = iMA(_Symbol, _Period, FAST_PERIOD, mashift_2, MODE_SMA, PRICE_CLOSE);
 }
//+------------------------------------------------------------------+
//|  Accelerator/Decelerator Oscillator                              |
//+------------------------------------------------------------------+
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[])
 {
//--- we can copy not all data
  if(prev_calculated == 0)
   {
    
    Print(ArraySize(Buffer0), " ", ArraySize(Buffer1), " ", ArraySize(Buffer2));
    int start_pos;
    int size;

    //---
    start_pos = 0;
    Print("---shift_0=", mashift_0, " start_pos=", start_pos);
    size = CopyBuffer(SMAHandle0, 0, start_pos, 100, Buffer0);
    Print(size, " ", ArraySize(Buffer0));
    Print(Buffer0[ArraySize(Buffer0) - 2], " ", Buffer0[ArraySize(Buffer0) - 1]);
    //---
    start_pos = 0;
    Print("---shift_1=", mashift_1, " start_pos=", start_pos);
    size = CopyBuffer(SMAHandle1, 0, start_pos, 100, Buffer1);
    Print(size, " ", ArraySize(Buffer1));
    Print(Buffer1[ArraySize(Buffer1) - 2], " ", Buffer1[ArraySize(Buffer1) - 1]);
    //---
    start_pos = 3;
    Print("---shift_2=", mashift_2, " start_pos=", start_pos);
    size = CopyBuffer(SMAHandle2, 0, start_pos, 100, Buffer2);
    Print(size, " ", ArraySize(Buffer2));
    Print(Buffer2[ArraySize(Buffer2) - 2], " ", Buffer2[ArraySize(Buffer2) - 1]);

   }
//--- return value of prev_calculated for next call
  return(rates_total);
 }
/*
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	5900 5900 5900
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	---shift_0=0 start_pos=0   
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	100 5900
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	1.159491499999989 1.159514999999989   --> correct
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	---shift_1=3 start_pos=0
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	100 5900
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	1.159491499999989 1.159514999999989   --> wrong
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	---shift_2=0 start_pos=3
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	100 5900
2021.10.27 09:29:56.054	CopyBuffer()指标中测试 (EURUSD,D1)	2.02222644196533e-33 4.260811099041657e+29  --> wrong
*/
 

MQL5 CopyBuffer is working correctly, but you are making a calculation error.

1. Remember that you have linked arrays with 'INDICATOR_DATA'

2. You can see your error if you run the code in debug mode, like this:

After copying the data, expand the array down ...

 
In short your made your buffers fixed yo a size of 100. 
 
Vladimir Karputov #:

MQL5 CopyBuffer is working correctly, but you are making a calculation error.

1. Remember that you have linked arrays with 'INDICATOR_DATA'

2. You can see your error if you run the code in debug mode, like this:

After copying the data, expand the array down ...

Thanks, I found the result like pic:

No matter shift=3 or start_pos=3, the buffer omitted the latest three values.

This is not like MQL5 Reference pic show:


the array set "INDICATOR_DATA",  it is not omitted values on the left side, it is on the right side.

 
Yu Zhang # :

Thanks, I found the result like pic:

No matter shift=3 or start_pos=3, the buffer  omitted t he latest three values.

This is not like MQL5 Reference pic show:


the array set " INDICATOR_DATA ",  it is not omitted values on the left side, it is on the right side.

There is no mistake - but there is your mistake. Please: read the Documentation, strictly control from which number you are copying - if you are not copying from number # 0 - you must clearly understand why you are doing this.

Keep reading the Documentation and to get started: read the example for the iMA indicator.

Documentation on MQL5: Technical Indicators / iMA
Documentation on MQL5: Technical Indicators / iMA
  • www.mql5.com
iMA - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

I found another wrong:

If we set buffer to "INDICATOR_DATA",  shift =-3 is equal to array with shift=3.

//--- indicator settings
#property indicator_buffers 2

//--- indicator buffers
double Buffer0[], Buffer1[];
double Array0[], Array1[];

//--- handles for MAs
int    Buffer_Handle0, Buffer_Handle1;
int    Array_Handle0, Array_Handle1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
 {
//--- Only Two Buffer
  SetIndexBuffer(0, Buffer0, INDICATOR_DATA);
  SetIndexBuffer(1, Buffer1, INDICATOR_DATA);
  
  Buffer_Handle0 = iMA(_Symbol, _Period, 20, 3, MODE_SMA, PRICE_CLOSE);
  Buffer_Handle1 = iMA(_Symbol, _Period, 20, -3, MODE_SMA, PRICE_CLOSE);
  Array_Handle0 = iMA(_Symbol, _Period, 20, 3, MODE_SMA, PRICE_CLOSE);
  Array_Handle1 = iMA(_Symbol, _Period, 20, -3, MODE_SMA, PRICE_CLOSE);
 }
//+------------------------------------------------------------------+
//|  Accelerator/Decelerator Oscillator                              |
//+------------------------------------------------------------------+
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[])
 {
//--- we can copy not all data
  if(prev_calculated == 0)
   {
    ArrayInitialize(Buffer0,0);
    ArrayInitialize(Buffer1,0);

    int size;
    
    //---
    Print("=== All start_pos is 0 ===");
    Print("---Buffer0_Shift=", 3);
    size = CopyBuffer(Buffer_Handle0, 0, 0, 100, Buffer0);
    Print(size, " ", ArraySize(Buffer0));
    Print(Buffer0[ArraySize(Buffer0) - 2], " ", Buffer0[ArraySize(Buffer0) - 1]);
    //---
    Print("---Buffer1_Shift=", -3);
    size = CopyBuffer(Buffer_Handle1, 0, 0, 100, Buffer1);
    Print(size, " ", ArraySize(Buffer1));
    Print(Buffer1[ArraySize(Buffer1) - 2], " ", Buffer1[ArraySize(Buffer1) - 1]);
    //---
    Print("---Array0_Shift=", 3);
    size = CopyBuffer(Array_Handle0, 0, 0, 100, Array0);
    Print(size, " ", ArraySize(Array0));
    Print(Array0[ArraySize(Array0) - 2], " ", Array0[ArraySize(Array0) - 1]);
    //---
    Print("---Array1_Shift=", -3);
    size = CopyBuffer(Array_Handle1, 0, 0, 100, Array1);
    Print(size, " ", ArraySize(Array1));
    Print(Array1[ArraySize(Array1) - 2], " ", Array1[ArraySize(Array1) - 1]);
    

   }
//--- return value of prev_calculated for next call
  return(rates_total);
 }
/*
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   === All start_pos is 0 ===
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Buffer0_Shift=3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   100 5900
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   0.0 0.0
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Buffer1_Shift=-3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   97 5900
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   1.160745499999989 1.160360999999989
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Array0_Shift=3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   100 100
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   1.160745499999989 1.160360999999989
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Array1_Shift=-3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   97 97
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   1.159491499999989 1.159546999999989
*/

Look at the result : iMA() shift=-3 on buffer with "INDICATOR_DATA" is equal to shift=3 on array!!!

 

1. Read the help: iMA  

2. Draw a chart and indicator

3. Look at the indicator data from the chart.

4. Read help on 'INDICATOR_DATA'

Documentation on MQL5: Technical Indicators / iMA
Documentation on MQL5: Technical Indicators / iMA
  • www.mql5.com
iMA - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

An example of an indicator - the indicator receives data from three iMAs and displays this data in three buffers:  Three MA Arrow

Three MA Arrow
Three MA Arrow
  • www.mql5.com
Индикатор тренда на основе трёх iMA (Movinag Averga, MA).
 
Vladimir Karputov #:

1. Read the help: iMA  

2. Draw a chart and indicator

3. Look at the indicator data from the chart.

4. Read help on 'INDICATOR_DATA'

Yes, I know it.  MA shift =3 means chart move 3 bars to the right,and shift = -3 means move 3 bar to the left. And the requested indicator data also has a corresponding offset.

But used my code, and i plot the chart, the built-in MA Shift =3 overlaps with buffer shift =-3.

buffer[] even set to  'INDICATOR_DATA',  but it is also array data.

Why buffer[] set to "INDICATOR_DATA and shift=-3",  is equal to array[] only set shift=3 ?

I read the Documentation, but i can not find answer.

Documentation on MQL5: Technical Indicators / iMA
Documentation on MQL5: Technical Indicators / iMA
  • www.mql5.com
iMA - Technical Indicators - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
      Buffer0 Vladimir Karputov #:

An example of an indicator - the indicator receives data from three iMAs and displays this data in three buffers:  Three MA Arrow

iMA() shift=3 , if I want to get all MA data , i should CopyBuffer() start_pos =-3.I know it .

my question is not about " CopyBuffer() start_pos ",  all the indicator data is  start_pos=0.

my question is :

Buffer_Handle0 = iMA(_Symbol, _Period, 20, 3, MODE_SMA, PRICE_CLOSE); // move ma right 3 bar
Array_Handle0 = iMA(_Symbol, _Period, 20, 3, MODE_SMA, PRICE_CLOSE);  // move ma right 3 bar

the Handle is same.

but if I set Buffer0 to INDICATOR_DATA, not set Array0.

SetIndexBuffer(0, Buffer0, INDICATOR_DATA);
CopyBuffer(Buffer_Handle0, 0, 0, 100, Buffer0);
CopyBuffer(Array_Handle0, 0, 0, 100, Array0);

The result is different!

But if i Set:

Buffer_Handle0 = iMA(_Symbol, _Period, 20, -3, MODE_SMA, PRICE_CLOSE);  // move ma left 3 bar

Buffer0 last value is equal to Array0 last value.

Please take a look at the code I released for the second time.

SetIndexBuffer(0, Buffer0, INDICATOR_DATA); 
// Even Buffer0 Set INDICATOR_DATA, Buffer0 is also array data.
 
I am a correct example for you - an example that is correctly formatted. Study my example, study the documentation (especially carefully read what a timeseries array is, what happens when you bind an array using 'INDICATOR_DATA') /
Reason: