[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [amibroker] Ehlers Dominant Cycle



PureBytes Links

Trading Reference Links

Steve,
I think you're getting confused between Ehler's two books. As far as I 
recall (books not to hand right now) he makes the confusion easy as 
there is a "Dominant Cycle" indicator in both 'Rocket Science' and 
'Cybernetic', which are based on different methods. Looks to me like the 
top one on your plot is the former and the bottom is the latter. I 
personally have used the latter...the code is copied below, which is 
probably nearly identical to the posted AFL library version as I used 
that as a starting point when I worked through it myself.
Can't help you with the 'Rocket Science' version I'm afraid.
Andy


// Ehler's Dominant Cycle Period
// Cybernetic Analysis for Stocks and Futures
// Chapter 9, p. 107. Code on p. 111.

//Global Parameters
X = Param("MP[1] Close[2]",1,1,2,1);
Z1 = IIf(X==1, (H+L)/2 , C);
Z2 = Param("Alpha", .07, .01, 1, .01);

function CyclePeriod(price, alpha)
{
 instperiod = deltaphase = cycle = period = 0;
 Cycle = ( price[2] - 2*price[1] + price[0] )/4;   //initialise arrays
 smooth = ( price + 2*Ref(price,-1) + 2*Ref(price,-2) + Ref(price,-3) )/6;
 
 for (i=6 ; i<BarCount ; i++)
  { 
   Cycle[i] = (1-alpha/2)^2 * ( smooth[i] - 2*smooth[i-1] + smooth[i-2] ) +
              2*(1-alpha)*Cycle[i-1] - (1-alpha)^2*Cycle[i-2];

   Q1[i] = (.0962*cycle[i] + .5769*cycle[i-2] -.5769*cycle[i-4] - 
.0962*cycle[i-6])*(.5 + .08*InstPeriod[i-1]);
   I1[i] = cycle[i-3];

   if(Q1[i] != 0 AND Q1[i-1] != 0)
   DeltaPhase[i] = (I1[i]/Q1[i] - I1[i-1]/Q1[i-1])/(1 + 
I1[i]*I1[i-1]/(Q1[i]*Q1[i-1]));
   //limit Delta Phase High/Low (0.09rads = 69bars, 1.1rads = 
6bars...per page 117)
   if(DeltaPhase[i] < 0.09)
    DeltaPhase[i] = 0.09;
   if(DeltaPhase[i] > 1.1)
    DeltaPhase[i] = 1.1;
   
   //---Begin median calculation (placed inline for speed).
   //Hardcoded as length=5 as higher values would be out of range due to 
start-up period in main loop
   for(k=4; k>=0; k--) 
    { temparray[k] = DeltaPhase[i-k]; } //create new array with last 5 
values of DeltaPhase
   temp = 0;
   for(k=4; k>0; k--)  //this series of loops re-organises temparray 
into ascending order
   { for (j=4; j>0; j--) 
     { if (temparray[j-1] > temparray[j]) //swap values in array if 
previous value is greater
       { temp = temparray[j-1];
         temparray[j-1] = temparray[j];
         temparray[j] = temp;
   }}}
   MedianDelta[i] = temparray[2]; //returns the middle (third) element 
of temparray
   //---End median calculation

   DC[i] = Nz( 6.28318 / MedianDelta[i] + .5, 15 );

   InstPeriod[i] = .33*DC[i] + .67*InstPeriod[i-1];
   Period[i] = .15*InstPeriod[i] + .85*Period[i-1];
   }
 for (i=0; i<7; i++)
  { Period[i] = 1; }
 return Period;
}

Plot( CyclePeriod(Z1,Z2) , "CyberCycle", colorRed );



Steve Dugas wrote:
> Hi All,
>  
> I wonder if anyone has ever tried to code Ehlers Dominant Cycle - the 
> one based on the Homodyne Discriminator, pp. 68-69 in Rocket Science. 
> I have never used TradeStation and this is my first shot at 
> translating EasyLanguage. As far as I can see the code looks OK to me 
> but what do I know? Anyway, the graph it produces ( middle one ) looks 
> pretty bad. For comparison, I plotted the Dominant Cycle code from the 
> AFL library on the bottom ( but I believe this uses a different method 
> ).  I would like to go on and code the rest of the indicators in the 
> book but many are built on this so I need to get this right first. Any 
> thoughts or working code would be greatly appreciated. I have enclosed 
> my code below.Thank you!
>  
> Steve
>  
>
> // Dominant Cycle
>
> SetBarsRequired( 10000, 10000 );
>
> // USER DEFINED PARAMS
>
> Price = ( *High* + *Low* ) / 2;
>
> // FORMULA
>
> // initialize variables
>
> Smooth = Detrender = I1 = Q1 = jI = jQ = I2 = Q2 = Re = Im = Period = 
> SmoothPeriod = 0;
>
> // calculate dominant cycle period
>
> **
>
> *for* ( i = 6; i < *BarCount*; i++ )
>
> {
>
> // smooth price data with 4-bar WMA
>
> Smooth[i] = ( 4 * Price[i] + 3 * Price[i-1] + 2 * Price[i-2] + 
> Price[i-3] ) / 10;
>
> // compute amplitude correction
>
> AmpCorr[i] = 0.075 * Period[i-1] + 0.54;
>
> // compute detrended price data and Quadrature component with 7-bar 
> Hilbert Transform
>
> Detrender[i] = ( 0.0962 * Smooth[i] + 0.5769 * Smooth[i-2] - 0.5769 * 
> Smooth[i-4] - 0.0962 * Smooth[i-6] ) * AmpCorr[i];
>
> Q1[i] = ( 0.0962 * Detrender[i] + 0.5769 * Detrender[i-2] - 0.5769 * 
> Detrender[i-4] - 0.0962 * Detrender[i-6] ) * AmpCorr[i];
>
> // compute InPhase component by referencing center bar of Hilbert 
> Transformer ( 3 bars ago )
>
> I1[i] = Detrender[i-3];
>
> // advance the phase of I1 and Q1 by 90 degrees with 7-bar Hilbert 
> Transform
>
> jI[i] = ( 0.0962 * I1[i] + 0.5769 * I1[i-2] - 0.5769 * I1[i-4] - 
> 0.0962 * I1[i-6] ) * AmpCorr[i];
>
> jQ[i] = ( 0.0962 * Q1[i] + 0.5769 * Q1[i-2] - 0.5769 * Q1[i-4] - 
> 0.0962 * Q1[i-6] ) * AmpCorr[i];
>
> // perform Phasor addition for 3-bar averaging
>
> I2[i] = I1[i] - jQ[i];
>
> Q2[i] = Q1[i] + jI[i];
>
> // smooth the I and Q components
>
> I2[i] = 0.2 * I2[i] + 0.8 * I2[i-1];
>
> Q2[i] = 0.2 * Q2[i] + 0.8 * Q2[i-1];
>
> // apply the Homodyne Discriminator
>
> Re[i] = I2[i] * I2[i-1] + Q2[i] * Q2[i-1];
>
> Im[i] = I2[i] * Q2[i-1] - Q2[i] * I2[i-1];
>
> // smooth the Re and Im components
>
> Re[i] = 0.2 * Re[i] + 0.8 * Re[i-1];
>
> Im[i] = 0.2 * Im[i] + 0.8 * Im[i-1];
>
> // compute Dominant Cycle period
>
> *if* ( Im[i] != 0 *AND* Re[i] != 0 )
>
> Period[i] = 360 / atan( Im[i] / Re[i] );
>
> // limit ROC of the cycle period to +/- 50% of previous cycle period
>
> *if* ( Period[i] > 1.5 * Period[i-1] )
>
> Period[i] = 1.5 * Period[i-1];
>
> *if* ( Period[i] < 0.67 * Period[i-1] )
>
> Period[i] = 0.67 * Period[i-1];
>
> // limit the cycle period to be > 6 or < 50
>
> *if* ( Period[i] < 6 )
>
> Period[i] = 6;
>
> *if* ( Period[i] > 50 )
>
> Period[i] = 50;
>
> // smooth the cycle period
>
> Period[i] = 0.2 * Period[i] + 0.8 * Period[i-1];
>
> SmoothPeriod[i] = 0.33 * Period[i] + 0.67 * SmoothPeriod[i-1];
>
> }
>
> Plot( SmoothPeriod, "Dominant Cycle", *colorWhite*, 
> *styleLine*|*styleOwnScale* );
>
> //Plot( Re, "Re", colorBlue, styleLine|styleOwnScale );
>
> //Plot( Im, "Im", colorSkyblue, styleLine|styleOwnScale );
>
> //Plot( Im/Re, "Im/Re", colorDarkGreen, styleLine|styleOwnScale );
>
> //Plot( atan(Im/Re), "atan(Im/Re)", colorBrightGreen, 
> styleLine|styleOwnScale );
>
> //Plot( Period, "Period", colorYellow, styleLine|styleOwnScale );
>
> 
> ------------------------------------------------------------------------
>