Calculation of EMA

 

Hi,

In my learning of MQL4, I try to rewrite the exponential moving average (EMA).

For this I'm using the  rewritten version . EMA(i) = EMA(i-1) + alpha * [Price(i) - EMA(i-1)]

The problem is my ema is very different of MT4 ema.

Someone can tell me what is going wrong with my code please

//---- the indicator will be plotted in the main window
#property indicator_chart_window
//---- 46 buffer will be used for the calculations and plot of the indicator
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_type1   DRAW_LINE
#property indicator_width1  2


//--- input parameters
input ENUM_APPLIED_PRICE inpPrice  = PRICE_CLOSE; // Price
input double             inpPeriod = 14;           // Period
//--- indicator buffers
double val[];
double aEMA[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
void OnInit(void)
{
   IndicatorShortName("My indicator");
   IndicatorDigits(Digits);

   SetIndexBuffer(0, val);
}


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[])
{

if(Bars(_Symbol,_Period)<rates_total) return(prev_calculated);


// ArraySetAsSeries(val,false);
// ArraySetAsSeries(open,false);
// ArraySetAsSeries(high,false);
// ArraySetAsSeries(low,false);
// ArraySetAsSeries(close,false);

    if (ArrayRange(aEMA,0) != Bars) ArrayResize(aEMA,Bars);
    
    int i= prev_calculated-1; if (i<0) i=0; for (; i<rates_total && !_StopFlag; i++) {
    val[i] = iEMA(close[i], inpPeriod, i, rates_total);
    }
   return (rates_total);
}


double iEMA(double price, int period, int i, int bars) 
{
    double  length, alpha;

    length = (period>1) ? period:1;
    alpha = 2.0/(length + 1.0);


    if(i>0) {
        aEMA[i] = aEMA[i-1] + alpha*(price-aEMA[i-1]);
    } else {
        aEMA[i] = price;
    }

    return (aEMA[i]);
        
}

Moving average - Wikipedia
Moving average - Wikipedia
  • en.wikipedia.org
In statistics, a moving average ( rolling average or running average ) is a calculation to analyze data points by creating a series of averages of different subsets of the full data set. It is also called a moving mean ( MM ) [1] or rolling mean and is a type of finite impulse response filter. Variations include: simple, and cumulative, or...
 
double aEMA[];
⋮
aEMA[i] = aEMA[i-1] + alpha*(price-aEMA[i-1]);
  1. You are using an array; on each new bar, you will have to resize it and recompute all bars. Make it a buffer.
  2. Val is a buffer; which defaults to as-series. Yet your computation is non-series.
  3. close[] has no predefined direction (as-series or non-series). Always set it per the documentation.