PureBytes Links
Trading Reference Links
|
Hi Andy,
In Rocket Science, Ehlers shows 3 methods to compute the cycle period. Then he tests them against each other and determines that the Homodyne Discriminator method had the the best characteristics of the 3, so he uses that code as a basis for the indicators that follow. The 3 yeilded fairly similar results, so when my graph looked wrong, I figured the code from the library should give me a rough idea of what mine should look like even though it is created through a different technique. I still think there is something wrong with mine, it should look much more like the other one. Maybe I will be able to just substitute your code for mine and build from there. Is the one in Cybernetics supposed to be better? I ordered that book too, but it got delayed and I just found out that it shipped today. Thanks for the code!
Steve
----- Original Message -----
From: Andy Davidson
To: amibroker@xxxxxxxxxxxxxxx
Sent: Thursday, October 05, 2006 1:46 PM
Subject: Re: [amibroker] Ehlers Dominant Cycle
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 );
----------------------------------------------------------------------------
|