After one successful copy buffer, following ones fail unintentionally

 

My intention of the code below is to display 3 periods of moving average lines for the range of bars specified by chart window width.

Although first period of line is drawn properly, succeeding 2 period lines fail to draw due to CopyBuffer error (4806 : Requested data not found).

I cannot figure out the cause of this error, thus no fix at the moment. Could anyone help with this?

//+------------------------------------------------------------------+
//|                                          MovingAverage_Light.mq5 |
//|                             Copyright 2026, Dreaming Donkey Ltd. |
//|                                           scott_5409jp@nifty.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Dreaming Donkey Ltd."
#property link      "scott_5409jp@nifty.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3
//--- plot ma1
#property indicator_type1   DRAW_LINE
#property indicator_color1  C'159,227,105'
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot ma2
//#property indicator_type2   DRAW_LINE
#property indicator_color2  C'170,0,170'
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot ma3
//#property indicator_type3   DRAW_LINE
#property indicator_color3  C'2,104,196'
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

input int chartWindowN = 2;   // drawing range by chart window (0 : whole)
int bars = 0;
int maxBar = 0;
int period1, period2, period3;
//--- indicator buffers
double MA1Buffer[];
double MA2Buffer[];
double MA3Buffer[];
int MA1Handle;
int MA2Handle;
int MA3Handle;
int to_copy1 = 0;
int to_copy2 = 0;
int to_copy3 = 0;
int bars_calculated1 = 0;
int bars_calculated2 = 0;
int bars_calculated3 = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping ---
   SetIndexBuffer(0, MA1Buffer, INDICATOR_DATA);
   SetIndexBuffer(1, MA2Buffer, INDICATOR_DATA);
   SetIndexBuffer(2, MA3Buffer, INDICATOR_DATA);
   ArraySetAsSeries(MA1Buffer, true);
   ArraySetAsSeries(MA2Buffer, true);
   ArraySetAsSeries(MA3Buffer, true);
// set averaging period base on chart period
   period1 = 20;
   period2 = 80;
   period3 = 200;
   bars = Bars(_Symbol, _Period);
   if(chartWindowN == 0)
      maxBar = bars;
   else
      maxBar = (int)MathMin(ChartGetInteger(0, CHART_WIDTH_IN_BARS) * chartWindowN, bars);
   MA1Handle = iMA(_Symbol, _Period, period1, 0, MODE_LWMA, PRICE_CLOSE);
   if(MA1Handle == INVALID_HANDLE)
     {
      Print(__LINE__, "Failed to create handle of the iMA Indicator");
      return(INIT_FAILED);
     }
   MA2Handle = iMA(_Symbol, _Period, period2, 0, MODE_LWMA, PRICE_CLOSE);
   if(MA2Handle == INVALID_HANDLE)
     {
      Print(__LINE__, "Failed to create handle of the iMA Indicator");
      return(INIT_FAILED);
     }
   MA3Handle = iMA(_Symbol, _Period, period3, 0, MODE_LWMA, PRICE_CLOSE);
   if(MA3Handle == INVALID_HANDLE)
     {
      Print(__LINE__, "Failed to create handle of the iMA Indicator");
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(MA1Handle != INVALID_HANDLE)
      IndicatorRelease(MA1Handle);
   if(MA2Handle != INVALID_HANDLE)
      IndicatorRelease(MA2Handle);
   if(MA3Handle != INVALID_HANDLE)
      IndicatorRelease(MA3Handle);
   return;
  }

//+------------------------------------------------------------------+
//| 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 calculated1 = BarsCalculated(MA1Handle);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, calculated1 - maxBar + 1);
   int calculated2 = BarsCalculated(MA2Handle);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, calculated2 - maxBar + 1);
   int calculated3 = BarsCalculated(MA3Handle);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, calculated3 - maxBar + 1);
   PrintFormat("rates_total = %d  prev_calculated = %d  calculated1 = %d  calculated2 = %d  calculated3 = %d", rates_total, prev_calculated, calculated1, calculated2, calculated3);
//--- for period1 ---
   if(calculated1 != bars_calculated1 || calculated1 > 0)
      to_copy1 = calculated1;
   else
      to_copy1 = calculated1 - bars_calculated1 + 1;
   if(CopyBuffer(MA1Handle, 0, 0, MathMin(to_copy1, maxBar), MA1Buffer) < 0)
      PrintFormat("1 : Failed to copy data count = %d  error code %d", MathMin(to_copy1, maxBar), GetLastError());
//--- for period2 ---
   if(calculated2 != bars_calculated2 || calculated2 > 0)
      to_copy2 = calculated2;
   else
      to_copy2 = calculated2 - bars_calculated2 + 1;
   if(CopyBuffer(MA2Handle, 1, 0, MathMin(to_copy2, maxBar), MA2Buffer) < 0)
      PrintFormat("2 : Failed to copy data count = %d  error code %d", MathMin(to_copy2, maxBar), GetLastError());
//--- for period3 ---
   if(calculated3 != bars_calculated3 || calculated3 > 0)
      to_copy3 = calculated3;
   else
      to_copy3 = calculated3 - bars_calculated3 + 1;
   if(CopyBuffer(MA3Handle, 2, 0, MathMin(to_copy3, maxBar), MA3Buffer) < 0)
      PrintFormat("3 : Failed to copy data count = %d  error code %d", MathMin(to_copy3, maxBar), GetLastError());
   bars_calculated1 = calculated1;
   bars_calculated2 = calculated2;
   bars_calculated3 = calculated3;
   return(rates_total);
  }
//+------------------------------------------------------------------+

 

Only one MA line(period1) is displayed.  Other two lines(period2 and 3) are failed to be displayed due to error 4806.


 

Unless I'm missing something, there are no index buffers numbered 1 nor 2 in any iMA call.

   if(CopyBuffer(MA2Handle, 1, 0, MathMin(to_copy2, maxBar), MA2Buffer) < 0)
   if(CopyBuffer(MA3Handle, 2, 0, MathMin(to_copy3, maxBar), MA3Buffer) < 0)
 

Like said, you are using buffer 1 and 2, but it should always be 0 when using iMA

You change that buffer number in EAs usually when using iCustom for custom indicators, not when using iMA.

U also commented out properties for indicator type 2 and 3.

//+------------------------------------------------------------------+
//|                                          MovingAverage_Light.mq5 |
//|                             Copyright 2026, Dreaming Donkey Ltd. |
//|                                           scott_5409jp@nifty.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Dreaming Donkey Ltd."
#property link      "scott_5409jp@nifty.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3
//--- plot ma1
#property indicator_type1   DRAW_LINE
#property indicator_color1  C'159,227,105'
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot ma2
#property indicator_type2   DRAW_LINE
#property indicator_color2  C'170,0,170'
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot ma3
#property indicator_type3   DRAW_LINE
#property indicator_color3  C'2,104,196'
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

input int chartWindowN = 2;   // drawing range by chart window (0 : whole)
int bars = 0;
int maxBar = 0;
int period1, period2, period3;
//--- indicator buffers
double MA1Buffer[];
double MA2Buffer[];
double MA3Buffer[];
int MA1Handle;
int MA2Handle;
int MA3Handle;
int to_copy1 = 0;
int to_copy2 = 0;
int to_copy3 = 0;
int bars_calculated1 = 0;
int bars_calculated2 = 0;
int bars_calculated3 = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping ---
   SetIndexBuffer(0, MA1Buffer, INDICATOR_DATA);
   SetIndexBuffer(1, MA2Buffer, INDICATOR_DATA);
   SetIndexBuffer(2, MA3Buffer, INDICATOR_DATA);
   ArraySetAsSeries(MA1Buffer, true);
   ArraySetAsSeries(MA2Buffer, true);
   ArraySetAsSeries(MA3Buffer, true);
// set averaging period base on chart period
   period1 = 20;
   period2 = 80;
   period3 = 200;
   bars = Bars(_Symbol, _Period);
   if(chartWindowN == 0)
      maxBar = bars;
   else
      maxBar = (int)MathMin(ChartGetInteger(0, CHART_WIDTH_IN_BARS) * chartWindowN, bars);
   MA1Handle = iMA(_Symbol, _Period, period1, 0, MODE_LWMA, PRICE_CLOSE);
   if(MA1Handle == INVALID_HANDLE)
     {
      Print(__LINE__, "Failed to create handle of the iMA Indicator");
      return(INIT_FAILED);
     }
   MA2Handle = iMA(_Symbol, _Period, period2, 0, MODE_LWMA, PRICE_CLOSE);
   if(MA2Handle == INVALID_HANDLE)
     {
      Print(__LINE__, "Failed to create handle of the iMA Indicator");
      return(INIT_FAILED);
     }
   MA3Handle = iMA(_Symbol, _Period, period3, 0, MODE_LWMA, PRICE_CLOSE);
   if(MA3Handle == INVALID_HANDLE)
     {
      Print(__LINE__, "Failed to create handle of the iMA Indicator");
      return(INIT_FAILED);
     }
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(MA1Handle != INVALID_HANDLE)
      IndicatorRelease(MA1Handle);
   if(MA2Handle != INVALID_HANDLE)
      IndicatorRelease(MA2Handle);
   if(MA3Handle != INVALID_HANDLE)
      IndicatorRelease(MA3Handle);
   return;
  }

//+------------------------------------------------------------------+
//| 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 calculated1 = BarsCalculated(MA1Handle);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, calculated1 - maxBar + 1);
   int calculated2 = BarsCalculated(MA2Handle);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, calculated2 - maxBar + 1);
   int calculated3 = BarsCalculated(MA3Handle);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, calculated3 - maxBar + 1);
   PrintFormat("rates_total = %d  prev_calculated = %d  calculated1 = %d  calculated2 = %d  calculated3 = %d", rates_total, prev_calculated, calculated1, calculated2, calculated3); 

//--- for period1 ---
   if(calculated1 != bars_calculated1 || calculated1 > 0)
      to_copy1 = calculated1;
   else
      to_copy1 = calculated1 - bars_calculated1 + 1;
   if(CopyBuffer(MA1Handle, 0, 0, MathMin(to_copy1, maxBar), MA1Buffer) < 0)
      PrintFormat("1 : Failed to copy data count = %d  error code %d", MathMin(to_copy1, maxBar), GetLastError());
//--- for period2 ---
   if(calculated2 != bars_calculated2 || calculated2 > 0)
      to_copy2 = calculated2;
   else
      to_copy2 = calculated2 - bars_calculated2 + 1;
   if(CopyBuffer(MA2Handle, 0, 0, MathMin(to_copy2, maxBar), MA2Buffer) < 0)
      PrintFormat("2 : Failed to copy data count = %d  error code %d", MathMin(to_copy2, maxBar), GetLastError());
//--- for period3 ---
   if(calculated3 != bars_calculated3 || calculated3 > 0)
      to_copy3 = calculated3;
   else
      to_copy3 = calculated3 - bars_calculated3 + 1;
   if(CopyBuffer(MA3Handle, 0, 0, MathMin(to_copy3, maxBar), MA3Buffer) < 0)
      PrintFormat("3 : Failed to copy data count = %d  error code %d", MathMin(to_copy3, maxBar), GetLastError());
 

   bars_calculated1 = calculated1;
   bars_calculated2 = calculated2;
   bars_calculated3 = calculated3;  
    
   return(rates_total);
  }
//+------------------------------------------------------------------+


I recommend copying bars using the standardized way:

   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0)
      to_copy=rates_total;
   else
     {
      to_copy=(rates_total-prev_calculated)+1;
      if(to_copy > rates_total)
         to_copy = rates_total;
     }


You don't need "to_copy1", "to_copy2" and so on... because the three indicators are using the same amount of bars in the single timeframe

 

Ryan and Conor,

From your comments I realize that I was confused the indicator buffer number in CopyBuffer with the buffer index in SetIndexBuffer. I should have carefully read MQL5 help file.

Thank you for your help !

 
cloudwandering #:

Ryan and Conor,

From your comments I realize that I was confused the indicator buffer number in CopyBuffer with the buffer index in SetIndexBuffer. I should have carefully read MQL5 help file.

Thank you for your help !

You're welcome. Don't feel bad about it. Single character typo's frequently cause bugs/errors in almost everyone's code. When I have a stack of code between my 2 ears, my 10 fingers sometimes hammer away faster than my eyes can keep up.
 
cloudwandering #:

Ryan and Conor,

From your comments I realize that I was confused the indicator buffer number in CopyBuffer with the buffer index in SetIndexBuffer. I should have carefully read MQL5 help file.

Thank you for your help !

It wasn't something you could easily gauge from any help file or documentation because they never explicitly gave any example codes using multiple iMA handles in one indicator. That's what this forum section is for. Nothing wrong with asking for help or insight as long as it's not 1000 lines of code.

Now here's the irony... that buffer number does link to the buffer number in SetIndexBuffer, but only when you're using CopyBuffer in an EA for a custom indicator.