Using EMA on ATR values in MQL5

Hi all,

I am trying to add EMA to ATR in MQL5 EA.


ATR line (Blue)

EMA line (Red)

Please tell me how to get it done in MQL5.


Use MovingAverages.mqh and then use ExponentialMAOnBuffer() function from that file on the buffer where you stored atr values

Hi hgreenroad9,

thanks for your reply… I used the mentioned function in my code however unable to get the desired result. the moving average is being draw in chart window not in ART window. following is my code, please tell me what am I doing wrong.

void CalculateATR_EMA(string symbol)
   double myPriceArray[];
   int averageTrueRangeDefination = iATR(symbol, Period(), 14);
   ArraySetAsSeries(myPriceArray, true);
   CopyBuffer(averageTrueRangeDefination, 0, 0, 3, myPriceArray);
   MqlRates priceInfo[];
   ArraySetAsSeries(priceInfo, true);
   int data = CopyRates(symbol, _Period, 0, 3, priceInfo);
   double myMovingAverageArray[];
   int movingAverageDefinatin = iMA(symbol, _Period, 14, 0, MODE_EMA, PRICE_CLOSE);
   ArraySetAsSeries(myMovingAverageArray, true);
   CopyBuffer(movingAverageDefinatin, 0, 0, 3, myMovingAverageArray);
   ExponentialMAOnBuffer(4, 0,   0, 14, myPriceArray, myMovingAverageArray);
   //double averageTrueRangeValue = NormalizeDouble(myPriceArray[0], 5);


Here is an “as simple as it gets” example

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
#include <MovingAverages.mqh>

input int AtrPeriod = 14; // ATR period
input int EmaPeriod = 14; // EMA period

double atrBuffer[],emaBuffer[];


void OnInit()
   SetIndexBuffer(0,atrBuffer,INDICATOR_DATA); PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrDodgerBlue);
   SetIndexBuffer(1,emaBuffer,INDICATOR_DATA); PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); PlotIndexSetInteger(1,PLOT_LINE_COLOR,clrRed);
void OnDeinit(const int reason) { }
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[])
   static int _atrHandle =  INVALID_HANDLE; 
          if (_atrHandle == INVALID_HANDLE)
              _atrHandle  = iATR(_Symbol,_Period,14);
          if (_atrHandle == INVALID_HANDLE || BarsCalculated(_atrHandle)<rates_total) return(prev_calculated);

      int to_copy = (prev_calculated>rates_total || prev_calculated<=0) ? rates_total : rates_total-prev_calculated+1;  
         if(CopyBuffer(_atrHandle,0,0,to_copy,atrBuffer)<=0) return(0);

Use that code as a sample. But trying to calculate ema on only 4 values (as you have tried) might lead to highly misleading results. Ema needs more past data (unlike some other average types) for a “stable” result. In any case, replace the value assigned to to_copy with your desired fixed number of bars, and it should work for you in an EA code as well

Bundle of thanks for your reply,

I have put the above provided code in custom indicator and it compiled successfully, I used it via iCustom(…) function. the issue is that when I run the expert advisor, the expert attach the indicator again and again. Please refer to the following snapshot:


following is the block of code where I used iCustom(…) method to add this indicator:

void OnTick()
   int emaATRDefination = iCustom(_Symbol, _Period, "ATR_EMA");

   if(emaATRDefination == INVALID_HANDLE)
      Print("Handle invalid for ... error= ", GetLastError());

Moreover, please tell me how to get buffer values out of indicator.


Please check here :