Understanding CopyBuffer memory allocation

 

I am using the following EMA set up.

emaFastCloseHandle = iMA(_Symbol, _Period, emaFastPeriod, 0, MODE_EMA, PRICE_CLOSE);
emaSlowCloseHandle = iMA(_Symbol, _Period, emaSlowPeriod, 0, MODE_EMA, PRICE_CLOSE);

My initial thoughts were doing the following

double fastEma[2];

CopyBuffer(emaFastCloseHandle, 0, 0, 2, fastEma);

would mean

double ema = fastEma[0];  // latest value
double ema1 = fastEma[1]; // previous value

After testing this and seeing some unexpected behaviour and then reading this https://www.mql5.com/en/docs/series/copybuffer, I am thinking my initial were incorrect and in fact it is

double ema = fastEma[
1 ];  // latest value
double ema1 = fastEma[
0 ]; // previous value

Can someone please confirm this to make sure I am not going mad!?!?

Also, I have written the following two functions and wanted someone to just clarify that the following conditions are correct for the function names? 

bool isFastEmaCrossingUnderSlow() {
   double fastEma[2], slowEma[2];

   if (CopyBuffer(emaFastCloseHandle, 0, 1, 2, fastEma) <= 0) return false;
   if (CopyBuffer(emaSlowCloseHandle, 0, 1, 2, slowEma) <= 0) return false;

   return (fastEma[1] < slowEma[1]) && (fastEma[0] > slowEma[0]);
}

bool isFastEmaCrossingOverSlow() {
   double fastEma[2], slowEma[2];

   if (CopyBuffer(emaFastCloseHandle, 0, 1, 2, fastEma) <= 0) return false;
   if (CopyBuffer(emaSlowCloseHandle, 0, 1, 2, slowEma) <= 0) return false;

   return (fastEma[1] > slowEma[1]) && (fastEma[0] < slowEma[0]);
}
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
Gets data of a specified buffer of a certain indicator in the necessary quantity. Counting of elements of copied data (indicator buffer with the...
 
pbMoney:

I am using the following EMA set up.

My initial thoughts were doing the following

would mean

After testing this and seeing some unexpected behaviour and then reading this https://www.mql5.com/en/docs/series/copybuffer, I am thinking my initial were incorrect and in fact it is

Can someone please confirm this to make sure I am not going mad!?!?

Yes, exact. 

Also, I have written the following two functions and wanted someone to just clarify that the following conditions are correct for the function names? 

Yes correct. Though you should manage the '=' condition, it happens !

 

since an exact touch (fastEma[1] == slowEma[1]) currently falls through both functions as false, meaning it's silently treated as no crossover at all.

bool isFastEmaCrossingUnderSlow() {
   double fastEma[2], slowEma[2];
   if (CopyBuffer(emaFastCloseHandle, 0, 1, 2, fastEma) <= 0) return false;
   if (CopyBuffer(emaSlowCloseHandle, 0, 1, 2, slowEma) <= 0) return false;
   return (fastEma[1] <= slowEma[1]) && (fastEma[0] > slowEma[0]);
}

Switching the prior-bar comparison to <= (or >= for the other function) means a bar that lands exactly on the other line still counts as having crossed from that side, rather than getting skipped.

 
pbMoneyCan someone please confirm this to make sure I am not going mad!?!?
  1. In MT4, buffers and MT4 predefined arrays are all ordered AsSeries. There is a difference between the arrays passed to OnCalculate (e.g., low[]) and the MT4 predefined variables (e.g., Low[].) The passed arrays have no default direction, just like MT5.

    To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[] arrays, call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
              Event Handling Functions - Functions - Language Basics - MQL4 Reference

  2. In MT5, you must set the direction.

    To define the indexing direction in the time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[] and other arrays (copyXXXX functions), call the ArrayGetAsSeries() function. In order not to depend on defaults, call the ArraySetAsSeries() function for the arrays to work with.
              Event Handling / OnCalculate - Reference on algorithmic/automated trading language for MetaTrader 5