Discrepancy in calculation of iMA within an EA

 

Hi!

In the following EA code, I'm computing EMAs (fast and slow) at each new M5 bar. Though, as per the journal below it seems the [1] values computed at the current M5 bar can differ from the [0] values computed at the previous M5 bar.

This is an issue, as it can prevent detecting an EMA cross-under as calculated at 4:40am (at 04:35am the EMA fast is supposed to be above the EMA slow, and at 04:40am the EMA fast is supposed to be below the EMA slow).


Would you have any idea?


2023.07.28 09:01:50.552 2023.06.01 04:35:00   > Assess_signals_strategy_00_v2: ema_fast[0]: 1.0688488611109801

2023.07.28 09:01:50.552 2023.06.01 04:35:00   > Assess_signals_strategy_00_v2: ema_slow[0]: 1.0688371711698432

2023.07.28 09:01:50.552 2023.06.01 04:35:00   > Assess_signals_strategy_00_v2: ema_fast[1]: 1.0688813728068727

2023.07.28 09:01:50.552 2023.06.01 04:35:00   > Assess_signals_strategy_00_v2: ema_slow[1]: 1.0688493006053470


2023.07.28 09:01:53.970 2023.06.01 04:40:00   > Assess_signals_strategy_00_v2: ema_fast[0]: 1.0687786747920205

2023.07.28 09:01:53.970 2023.06.01 04:40:00   > Assess_signals_strategy_00_v2: ema_slow[0]: 1.0688082240497649

2023.07.28 09:01:53.970 2023.06.01 04:40:00   > Assess_signals_strategy_00_v2: ema_fast[1]: 1.0688269563490753

2023.07.28 09:01:53.970 2023.06.01 04:40:00   > Assess_signals_strategy_00_v2: ema_slow[1]: 1.0688281515620002

 
// with the related code (I have issue to give it a proper format): #include <Trade\SymbolInfo.mqh>
CSymbolInfo m_symbol;
input uint prm_MA_period_fast = 20;
input uint prm_MA_period_slow = 50; input ENUM_TIMEFRAMES prm_MA_timeframe = PERIOD_CURRENT;
input ENUM_MA_METHOD prm_MA_method = MODE_EMA;
input ENUM_APPLIED_PRICE prm_MA_applied_price = PRICE_CLOSE;
string
symbol="EURUSD"; //+----------------------------+ //|  Initialization function   | //+----------------------------+ int OnInit()   {        //--- define new CSymbolInfo object        m_symbol= new CSymbolInfo;        //--- define name and refresh rates        if(m_symbol!=NULL)        {            if(!m_symbol.Name(symbol))             return(INIT_FAILED);          m_symbol.RefreshRates()        }        else        {            Print("> ",__FUNCTION__," ERROR: Object CSymbolInfo is NULL");            return(INIT_FAILED);        }        /// create handles        handle_iMA_fast=iMA(m_symbol.Name(), prm_MA_timeframe, prm_MA_period_fast, 0, prm_MA_method, prm_MA_applied_price);        handle_iMA_slow=iMA(m_symbol.Name(), prm_MA_timeframe, prm_MA_period_slow, 0, prm_MA_method, prm_MA_applied_price);        // datetime PrevBar        PrevBar=0;        //--- return status        return INIT_SUCCEEDED;      } void OnTick()   {            //--- check this is a new bar, otherwise continue             datetime time_0=iTime(symbol, Period(), 0);             if(time_0==PrevBar)                 continue;             PrevBar=time_0;             if(!m_symbol.RefreshRates())             {                 PrevBar=0;                 continue;             }             //--- get data from the indicator             double ema_fast[];             double ema_slow[];             ArraySetAsSeries(ema_fast,true);             ArraySetAsSeries(ema_slow,true);             int start_pos=0;             uint count=prm_MA_period_fast+1; // or 3             if(!iGetArray(handle_iMA_fast,0,start_pos,count,ema_fast))             {                 PrevBar=0;                 continue;             }             count=prm_MA_period_slow+1; // or 3 above             if(!iGetArray(handle_iMA_slow,0,start_pos,count,ema_slow))             {                 PrevBar=0;                 continue;             }             Print("> ",__FUNCTION__,": ema_fast[0]: ",DoubleToString(ema_fast[0],16));             Print("> ",__FUNCTION__,": ema_slow[0]: ",DoubleToString(ema_slow[0],16));             Print("> ",__FUNCTION__,": ema_fast[1]: ",DoubleToString(ema_fast[1],16));             Print("> ",__FUNCTION__,": ema_slow[1]: ",DoubleToString(ema_slow[1],16)); } //+------------------------------------------------------------------+ //| Get value of buffers                                                 | //+------------------------------------------------------------------+ double iGetArray(const int handle,const int buffer,const int start_pos,const int count,double &arr_buffer[])   {    bool result=true;    ArrayFree(arr_buffer);    ResetLastError();    int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);    if(copied!=count)      {       PrintFormat("> ",__FUNCTION__,": failed to copy data from the indicator, error code %d",GetLastError());       return(false);      }    return(result);   }
 
Thomas110: This is an issue, as it can prevent detecting an EMA cross-under as calculated at 4:40am (at 04:35am the EMA fast is supposed to be above the EMA slow, and at 04:40am the EMA fast is supposed to be below the EMA slow).


Would you have any idea?

  1. Your print shows exactly what you think it should be.
  2. Stop looking at bar zero. That value will change every tick. Look for a cross between bar 1 and 2 at the start of a new bar.
 
William Roeder #:
  1. Your print shows exactly what you think it should be.
  2. Stop looking at bar zero. That value will change every tick. Look for a cross between bar 1 and 2 at the start of a new bar.

Ok, I better understand, thank you William. Sorry for the basic question this is my first EA