EMA function, what am I doing wrong?

 

halp

double EMA(ENUM_APPLIED_PRICE source, int length, int curBar,const double &_close[],const double &_open[],const double &_SMAbuffer[])
{
   if(source == PRICE_CLOSE || source == PRICE_HIGH)
   {
      
   }
   else
   {
      Print("ERROR, price applied needs to be close or open.");
      return 0.0;
   }
   
   double alpha = 2/(length + 1);
   double sum = 0.0;
   
   if(curBar == length + 1)
   {
      sum = SMA(source, length, curBar, _close, _open);
   }
   else
   {        
      if(source == PRICE_CLOSE)
      {
         sum = (alpha * _close[curBar]) + ((1 - alpha) * _SMAbuffer[curBar - 1]);

      }
      else
      {
         sum = (alpha * _open[curBar]) + ((1 - alpha) * _SMAbuffer[curBar - 1]);
      }         
   }   

   return sum;
}




double SMA(ENUM_APPLIED_PRICE source, int length, int curBar,const double &_close[],const double &_open[])
{

   if(source == PRICE_CLOSE || source == PRICE_HIGH)
   {
      
   }
   else
   {
      Print("ERROR, price applied needs to be close or open.");
      return 0.0;
   }
   double sum = 0.0;
   
   for(int i=0;i<length;i++)
     {         
         if(source == PRICE_CLOSE)
         {
            sum += (_close[curBar - i] / length);
         }
         else
         {
            sum += (_open[curBar - i] / length);
         }      
     }
   
   return sum;
}
 
Michael Lopez:

halp

You don't need to send the price directive you can just receive the array with the data , one array .

Try these , it works on both series and non series (for indicators)

ema code for indicator mql


//ema only 
double ema(const double &data[],//the array with the data you want to calculate ema of
                 double &ma[],//the moving average array - where you store the MA
         const datetime &time[],//the time array of the indicator 
                    int period,//ema period
                    int from,//where to start 
                 double empty_value=0.0){
//is there data ?
if(ArraySize(data)>period&&ArraySize(data)==ArraySize(time))
  {
  /* first determine if its series or not 
     If item-1 time is > than item time then its series
  */
  bool isSeries=(time[0]>time[1]);
  /* now we need to check if the calculation is possible 
     If its series then from can be at most TotalItems in data - period - 1
     If its non series then from can be at least period
  */
  bool canCalc=isSeries?(from<=(ArraySize(data)-period-1)):(from>=period);
  if(canCalc){
       //set the step , if its series the step is one otherwise its -1
  int  step=isSeries?1:-1;
  /* if this is the first value send it to the sma
     How do we know its the first value , the previous index is empty_value
     The previous value is ? from+step
     So if in the array of the moving average (where we store the mas or the emas)
     the previous to "from" item is empty then calculate the sma
  */
  if(ma[from+step]==empty_value){
    return(sma(data,ma,time,period,from));
    }
  /* if the previous value is not empty we can ema */
  else{
    double w=2.00/((double)period+1.0);
    ma[from]=data[from]*w+ma[from+step]*(1-w);    
    return(ma[from]);
    }
   }//canCalc ends here
  }//isThere data ends here
return(0.0);
}

//sma only
double sma(const double &data[],//array with the data you want
                 double &ma[],//the moving average array - where you store the MA
         const datetime &time[],//the time array of the indicator 
                    int period,//ema period
                    int from){//where to start   

//is there data ?
if(ArraySize(data)>period&&ArraySize(data)==ArraySize(time))
  {
  /* determine if its series or not 
     If item-1 time is > than item time then its series
  */
  bool isSeries=(time[0]>time[1]);
  /* now we need to check if the calculation is possible 
     If its series then from can be at most TotalItems in data - period - 1
     If its non series then from can be at least period
  */
  bool canCalc=isSeries?(from<=(ArraySize(data)-period-1)):(from>=period);
  if(canCalc){  
       //set the step , if its series the step is one otherwise its -1
  int  step=isSeries?1:-1;
  int  co=from;
  double sum=0.0;
  for(int i=0;i<period;i++){
     sum+=data[co];
     co+=step;
     } 
  ma[from]=sum/((double)period);
  return(ma[from]);
   }//canCalc Ends here
  }//has data ends here
return(0.0);
}               
 
Lorentzos Roussos #:

You don't need to send the price directive you can just receive the array with the data , one array .

Try these , it works on both series and non series (for indicators)

Works perfectly thank you.
 
Michael Lopez #:
Works perfectly thank you.

great

 

 
        sum = (alpha * _close[curBar]) + ((1 - alpha) * _SMAbuffer[curBar - 1]);

Never use the equation c=(1-a)p + (a)v as it amplifies round off errors. Use the rewritten and simpler equation c=p + a(v-p)