Screwed up implementation of an indicator

 

Hi,

I tried to implement Ehler's Universal Oscillator which he described in his article "Whiter is Brighter", an implementation at TradingView can be seen here: https://www.tradingview.com/script/ieFYbVdC-Ehlers-Universal-Oscillator-LazyBear/ and implementations in various languages can be seen here: http://traders.com/Documentation/FEEDbk_docs/2015/01/TradersTips.html

 Something weird happens at the current bar and the bar before that which makes it useless for trading og backtesting.

 Would greatly appreciate it if someone could see what is wrong with my code! :)

 

Best regards,

Lokrull 

Files:
ehlershuo.mq4  3 kb
 
  1. double tempReal= MathArctan(1.0);
    double rad2Deg = 45.0 / tempReal;
    double deg2Rad = 1.0 / rad2Deg;
    You can only initialize global variables with constants. Set these inside init.
  2. int buffers=0;
    
       initBuffer(universal,"Universal",DRAW_LINE);
    
       SetIndexArrow(buffers,arrow);
       buffers++;
    
    Every time you change timeframes or symbol you go through a deinit/init cycle. Global variables are not reset. therefor buffers becomes 4, 8, 12...
  3.    int countedBars=IndicatorCounted();
       if(countedBars < 0) return (-1);
       if(countedBars>0) countedBars--;
       int i,limit=MathMin(Bars-countedBars-1,Bars-drawBegin);
    
    No need for the decrement. Contradictory information on IndicatorCounted() - MQL4 forum just do your lookback correctly
    // whiteNoise[i]=(Close[i]-Close[i+2])/2.0;      
    // filt[i]=c1*(whiteNoise[i]+whiteNoise[i+1])/2.0+c2*filt[i+1]+c3*filt[i+2];
    #define LOOKBACK 2
    
       int countedBars=IndicatorCounted();
       for(i=Bars - 1 - MathMax(LOOKBACK, countedBars; i>=0; i--)

  4.       if(i==limit) filt[i]=0.0;
          if(i==limit-1) filt[i] = c1*0*(Close[i]+Close[i+1])/2.0+c2*filt[i+1];
          if(i==limit-2) filt[i] = c1*0*(Close[i]+Close[i+1])/2.0+c2*filt[i+1]+c3*filt[i+2];
    
          if(i==limit)
            {
             peak[i]=0.0000001;
               }else
    
    This initialized correctly the first time, but after that limit will likely be one or zero and your hosed. Either replace limit with Bars-1, or drop these completely.
 

Thanks! This seems to have removed many of my issues, however, I still have exponentially less movement in the indicator early in the series:

 Do you guys know what might have caused this?

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 clrRed

#property indicator_level1 0

#define LOOKBACK 2

double universal[];
double filt[];
double whiteNoise[];
double peak[];

input int bandEdge=40;
input int k = 0;
int drawBegin=64;
int buffers;

double a1,b1,c1,c2,c3;
double alpha1;
double freq, hpFreq, deg2Rad;

int init()
  {
   buffers=0;
   double tempReal= MathArctan(1.0);
   double rad2Deg = 45.0 / tempReal;
   deg2Rad = 1.0 / rad2Deg;
   
   IndicatorBuffers(4);
   initBuffer(universal,"Universal",DRAW_LINE);
   initBuffer(filt);
   initBuffer(whiteNoise);
   initBuffer(peak);
   IndicatorShortName("Universal Oscillator ["+IntegerToString(bandEdge)+"]");
   return (0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   if(Bars <= drawBegin) return (0);
   int countedBars=IndicatorCounted();
   if(countedBars < 0) return (-1);
   int i,limit=MathMin(Bars-countedBars-1,Bars-drawBegin);
  
   a1 = MathExp(-MathSqrt(2.0)*M_PI/bandEdge);
   b1 = 2*a1*MathCos(deg2Rad*MathSqrt(2.0)*180.0/bandEdge);
   c2 = b1;
   c3 = -a1*a1;
   c1 = 1.0-c2-c3;
   for(i=Bars - 1 - MathMax(LOOKBACK, countedBars); i>=0; i--)
     {
      whiteNoise[i]=(Close[i]-Close[i+2])/2.0;
      filt[i]=c1*(whiteNoise[i]+whiteNoise[i+1])/2.0+c2*filt[i+1]+c3*filt[i+2];
      if(i==Bars-1) filt[i]=0.0;
      if(i==Bars-2) filt[i] = c1*0*(Close[i]+Close[i+1])/2.0+c2*filt[i+1];
      if(i==Bars-3) filt[i] = c1*0*(Close[i]+Close[i+1])/2.0+c2*filt[i+1]+c3*filt[i+2];

      if(i==Bars-1)
        {
         peak[i]=0.0000001;
           }else{
         peak[i]=0.991*peak[i+1];
        }

      if(MathAbs(filt[i])>peak[i]) peak[i]=MathAbs(filt[i]);

      if(peak[i]!=0)
        {
         universal[i]=filt[i]/peak[i];
        }
     }
   return (0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void initBuffer(double &array[],string label="",int type=DRAW_NONE,int arrow=0,int style=EMPTY,int width=EMPTY,color clr=CLR_NONE)
  {
   SetIndexBuffer(buffers,array);
   SetIndexLabel(buffers,label);
   SetIndexEmptyValue(buffers,EMPTY_VALUE);
   SetIndexDrawBegin(buffers,drawBegin);
   SetIndexShift(buffers,0);
   SetIndexStyle(buffers,type,style,width);
   SetIndexArrow(buffers,arrow);
   buffers++;
  }
//+------------------------------------------------------------------+

 

 Best regards,

Lokrull 

Reason: