DEMA is not working with backtest properly

 

Hi

I m working with DEMA indi but when i m using it on a backtest it does not display the same. Anyone knows why?

int start()
  {
   int limit=Bars-1-IndicatorCounted();
   
//----
   static double lastEMA, lastEMA_of_EMA;
   double weight=2.0/(1.0+PERIOD);
//set default var the first time
   if(IndicatorCounted()==0)
     {
      Buffer[limit]  =Close[limit];
      lastEMA        =Close[limit];
      lastEMA_of_EMA  =Close[limit];
      limit--;
     }
//----
   //   Calculate old bars (not the latest), if necessary
   for(int i=limit; i > 0; i--)
     {
      lastEMA        =weight*Close[i]   + (1.0-weight)*lastEMA;
      lastEMA_of_EMA  =weight*lastEMA   + (1.0-weight)*lastEMA_of_EMA;
      Buffer[i]=2.0*lastEMA - lastEMA_of_EMA;
     }
//----
   //   (Re)calculate current bar
   double EMA        =  weight*Close[0]   + (1.0-weight)*lastEMA,
   EMA_of_EMA        =  weight*EMA      + (1.0-weight)*lastEMA_of_EMA;
   Buffer[0]=  2.0   *  EMA - EMA_of_EMA;
//----
   return(0);
  }

I though it has to do with the static double but i dont think thats the case. Generally i cant find a solution on this. Very confused cause the code its quite straight...

 
athanfx m working with DEMA indi but
  1. Why not use the ones in the codebase Dema - MQL4 Code Base or AllAverages v2.5 - MQL4 Code Base
  2. After the first run, limit will normally be zero, so lastEMA and lastEMA_of_EMA will have the last calculated value. Which you reuse on the same bar. instead you need the lastEMA of the previous bar for the calculation. You need to make them buffers also.
  3. Don't use w * v + (1-w) * p as that magnifies roundoff error.
    EMA[i] = EMA[i+1] + weight * (close[i] - EMA[i+1]);
  4. Why are you calculating all bars except zero and then doing the same thing with zero?
 
WHRoeder:
  1. Why not use the ones in the codebase Dema - MQL4 Code Base or AllAverages v2.5 - MQL4 Code Base
  2. After the first run, limit will normally be zero, so lastEMA and lastEMA_of_EMA will have the last calculated value. Which you reuse on the same bar. instead you need the lastEMA of the previous bar for the calculation. You need to make them buffers also.
  3. Don't use w * v + (1-w) * p as that magnifies roundoff error.
  4. Why are you calculating all bars except zero and then doing the same thing with zero?

Well the code above is the Dema - MQL4 Code Base. I m gonna vheck as well the AllAverages 2.5 you suggested and the rest of changes.
 
WHRoeder:
  1. Why not use the ones in the codebase Dema - MQL4 Code Base or AllAverages v2.5 - MQL4 Code Base
  2. After the first run, limit will normally be zero, so lastEMA and lastEMA_of_EMA will have the last calculated value. Which you reuse on the same bar. instead you need the lastEMA of the previous bar for the calculation. You need to make them buffers also.
  3. Don't use w * v + (1-w) * p as that magnifies roundoff error.
  4. Why are you calculating all bars except zero and then doing the same thing with zero?

I think the orginal coder was avoiding using extra buffers so he calculated all the bars except zero then does zero in a separate loop so lastEMA would not be updated on every tick on the zero bar.

 
So do I, but it's still wrong in the presence of missed bars and the recalculation of the last tick of a bar.
 
WHRoeder:
So do I, but it's still wrong in the presence of missed bars and the recalculation of the last tick of a bar.

ok i ve triec AllAverages v2.5 - MQL4 Code Base and it works in the backtest fine at least for small periods value (i ve checked this up to 120). When i m trying it to high periods >1200 there is some difference between a backtest and a running chart with a DEMA indicator.

Here is the code of DEMA in AllAverages

 DEMA - Double Exponential Moving Average by Patrick Mulloy
double DEMA(int num,double price,int per,double v,int bar)
{
   if(bar == 2) {double dema = price; tmp[bar][num] = dema; tmp[bar][num+1] = dema;}
   else 
   if(bar > 2) 
   {
   tmp[bar][num] = tmp[bar-1][num] + 2.0/(1+per)*(price - tmp[bar-1][num]); 
   tmp[bar][num+1] = tmp[bar-1][num+1] + 2.0/(1+per)*(tmp[bar][num] - tmp[bar-1][num+1]); 
   dema = (1+v)*tmp[bar][num] - v*tmp[bar][num+1];
   }
   return(dema);
}
 
athanfx: When i m trying it to high periods >1200 there is some difference between a backtest and a running chart with a DEMA indicator.
tester only provides 100-1000 bars. An EMA requires 3.45(N+1) bars. So of course high periods are initially wrong.
 
WHRoeder:
tester only provides 100-1000 bars. An EMA requires 3.45(N+1) bars. So of course high periods are initially wrong.


Only 1000 bars!!!!!!!!! Didnt know that...! So far I though that i just had to add more years in my backtest in order to add more bars!

Thanks for letting me know! I ve lost so many days trying to find were was the bug!

PS. So does this means that if an indicator works up to 1000 period bars correctly it probably does >1000 as well?

 

The main thing you need to determine is does the indicator draw correctly on live prices, in my opinion the original indicator you posted works fine on both historical and live prices.

 
SDC:

The main thing you need to determine is does the indicator draw correctly on live prices, in my opinion the original indicator you posted works fine on both historical and live prices.


You re correct when you say "you need to determine is does the indicator draw correctly on live prices". But at least in theory the backtest should give the same results as the livetest in order for an indicator to be reliable. The original indicator i posted doesnt do that. Thats the Dema - MQL4 Code Base indicator to be more specific. On the other hand when i tried the AllAverages v2.5 - MQL4 Code Base DEMA it works fine both in tester and in live (charts are exactly the same).

The Dema - MQL4 Code Base is not the only indicator in the MQL4 Code Base that has this sort of problem with the tester. I ve found also other indicators with such problems when other versions are fine.
Anyway i m not a guru on mql programming or how mt4 tester and stuff works so i could be wrong on that. I d like to know if i m wrong on that and why as well so not to loose any more time trying to fix indicators.

 

i rewrote it with three buffers which is probably the way it should have been coded in the first place. If you get a chance, test it in your backtest and see what happens. You can make it NRP by changing Close to Open in the loop.

//+------------------------------------------------------------------+
//|                         Double Exponential Moving Average (DEMA) |
//|                                                         SDC 2013 |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//---- inputs
extern int MA_Period  = 14;
//--- buffers
double EMA[],EMAEMA[],DEMA[];
//+------------------------------------------------------------------+
int init()
{
 IndicatorBuffers(3);
 SetIndexBuffer(2,EMA);
 SetIndexBuffer(1,EMAEMA);
 SetIndexBuffer(0,DEMA);
 IndicatorShortName("DEMA ("+MA_Period+")");
 return(0);
}
//+------------------------------------------------------------------+
int start()
{
 int  i,  counted_bars=IndicatorCounted();
 int  limit=Bars-1,   begin=limit-1;
 double wt = 2.0/(MA_Period+1);
//----
 if(counted_bars==0)
 {
  EMA[limit]=Close[limit];
  EMAEMA[limit]=Close[limit];
  DEMA[limit]=Close[limit];
 }
//----
 i=Bars-1-counted_bars;
 if(i>=begin)i=begin;
 while(i>=0)
 {
  EMA[i] = Close[i]*wt+EMA[i+1]*(1-wt);
  EMAEMA[i] = EMA[i]*wt+EMAEMA[i+1]*(1-wt);
  DEMA[i]=2*EMA[i]-EMAEMA[i];
  i--;
 } 
 return(0);
}
//+------------------------------------------------------------------+
Reason: