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 !
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 !
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.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use

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?