iMA + CopyBuffer Wrong way around?

 

I feel stupid.

The Copy Buffer is the wrong way around.. But why? 
In Copy Buffer.png Attachment , you can see  the Moving Average for the second last candle , should be [2].
In the top left corner , you see the comment. The first, which is the same value, is the array position [0]. 

Code:

int OnInit(){
    ArrayResize(ama,4);
    ArrayResize(ama_off,4);
    
    ma = iMA(_Symbol, PERIOD_M5, 6, 0, MODE_SMA, PRICE_CLOSE);
    ma_off = iMA(_Symbol, PERIOD_M5, 6, 6, MODE_SMA, PRICE_CLOSE);

   return(INIT_SUCCEEDED);
  }
void OnTick() {

   int bars = iBars(_Symbol,timeframe); // With every new bar
   if(barsTotal != bars ){
         barsTotal = bars; 

    CopyBuffer(ma,0,0,3,ama);
    CopyBuffer(ma_off,0,0,3,ama_off);      
 
         }
          
      Comment("\n Sma        ", ama[0],    "\t Sma+1      ", ama[1], "\t Sma+2      ", ama[2],
                     "\n sma offset ",ama_off[0], "\t sma off +1 ",ama_off[1], "\t sma off +1 ",ama_off[2],
                     "\n Reset == ", reset);       

      }
   
     
  }
Files:
CopyBuffer.png  55 kb
 
RundesZweieck:

I feel stupid.

The Copy Buffer is the wrong way around.. But why? 
In Copy Buffer.png Attachment , you can see  the Moving Average for the second last candle , should be [2].
In the top left corner , you see the comment. The first, which is the same value, is the array position [0]. 

Code:

Have you ever used MT4?

The order of data is reversed between MT4 and MT5.

You need to apply ArraySetAsSeries(ama, true) to get the same order as MT4.

 
Nagisa Unada #:
ArraySetAsSeries
Hi !
Yes ... Is the complete Candle / Bar Reverse or just the Array index (Array[n,..,3,2,1,0]) ? 
And is it just for the Copy Buffer or for all arrays?

I am confused...
 
RundesZweieck #:
Hi !
Yes ... Is the complete Candle / Bar Reverse or just the Array index (Array[n,..,3,2,1,0]) ? 
And is it just for the Copy Buffer or for all arrays?

I am confused...

The order of the array indexes is different.

MT4 array[n], .... array[2], array[1], array[0]

MT5 array[0], array[1], array[2], .... array[n].

This order can be changed with the ArraySetAsSeries function.

Try the following program.

double ama[];
double ama_off[];
int  ma, ma_off;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   ArrayResize(ama, 3);
   ArrayResize(ama_off, 3);
   ArraySetAsSeries(ama, true);
   ArraySetAsSeries(ama_off, false);

   ma     = iMA(_Symbol, PERIOD_M5, 6, 0, MODE_SMA, PRICE_CLOSE);
   ma_off = iMA(_Symbol, PERIOD_M5, 6, 0, MODE_SMA, PRICE_CLOSE);
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   CopyBuffer(ma,     0, 0, 3, ama);
   CopyBuffer(ma_off, 0, 0, 3, ama_off);

   Comment("\n ama[2]      ", ama[2],     "\t ama[1]       ", ama[1],     "\t ama[0]      ", ama[0],
           "\n ama_off[0] ", ama_off[0], "\t ama_off[1] ", ama_off[1], "\t ama_off[2] ", ama_off[2]);
}
//+------------------------------------------------------------------+

ArraySetAsSeries(ama, true) is applied to ama[]. All other conditions are the same.

ama[]       ----> ama[2],       ama[1],        ama[0]

ama_off[] ----> ama_off[0], ama_off[1], ama_off[2]

 
Shino Unada's two replies give the correct fix — `ArraySetAsSeries()` — and a clear before/after of the index order, but neither says why the array came out that way, and neither links the documentation. The asker's follow-up asks precisely that (whether the reversal is the data or just the indexing, and whether it applies to all arrays or only `CopyBuffer`) and the answer it got demonstrates the call rather than explaining the mechanism. Confirmed still uncovered on 2026-08-22: the page contains zero occurrences of "physical memory", "as_series", "regardless" or "no matter what", and zero links to `mql5.com/en/docs`. The mechanism is that `CopyBuffer` writes oldest-element-first into the array's physical memory regardless of the destination's as_series property, so as_series is an access overlay applied after the copy, not a switch that changes the copy. Nothing in the thread covers how quietly this fails when it reaches an EA rather than a chart.

Shino Unada's fix is the one to use, and on the follow-up question — whether it's the data that's reversed or just the indexing, and whether it applies to every array or only `CopyBuffer` — it's the indexing, and it applies to any array you index. That's worth pinning down, because the "MT5 indexes the other way round" mental model will bite you again later. `CopyBuffer` doesn't have a direction setting — the documentation is explicit that no matter what the target array's as_series property is, data gets copied so the oldest element sits at the start of the physical memory allocated for the array. `ArraySetAsSeries(arr, true)` doesn't change how the copy is performed; it changes how your indices map onto memory that was already filled oldest-first, so index 0 resolves to the newest element instead of the oldest. That distinction matters the moment you copy into a fresh array somewhere else in your code and forget the call, because the array's contents are identical either way — only your reads move. If you came from MQL4, where the predefined series were as-series for you, the habit of treating index 1 as "the previous bar" is the thing to unlearn, not the platform's ordering.