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

Re: ELA Request - Hilbert Period



PureBytes Links

Trading Reference Links

ndtrader wrote
>Could somebody send me this function?
>I must have misplaced it.

Here it is.  If anybody comes up with a decent signal or system
using it, please tell me how you did it.  Except for one other
person on this list who showed me his equity curves, I haven't been
able myself to determine that using HilbertPeriod is any better than
some other arbitrary lookback.


{----------------------------------------------------------------------
HilbertPeriod by John Ehlers (7/22/00)
ELA adapted from VBA macro by Alex Matulich (8/27/2001)
Calculate the dominant cycle period.
}

Variables: smoother(0), detrender(0), Q1(0), I1(0), pd(14), Q2(0),
I2(0), jI(0), jQ(0), Re(0), Im(0);

If currentbar < 4 Then
    smoother = (H+L+C)/3
Else begin

{ smoothed price has a lag of 1 bar }
smoother = (4*(H+L+C) + 3*(H[1]+L[1]+C[1]) + 2*(H[2]+L[2]+C[2]) + H[3]+L[3]+C[3]) / 30;

{ Detrend the signal and correct for the amplitude distortion
  introduced by the differenceing process used to detrend. }

detrender = (0.25*smoother[0] + 0.75*smoother[2] - 0.75*smoother[4] - 0.25*smoother[6]) * (0.046*pd[1] + 0.332);

{ Compute amplitude-compensated InPhase and Quadrature components.
  Quadrature is a difference, so we can apply the detrending computation
  again to the detrender signal to get quadrature Q1.  The Q1
  computation has a 3 bar lag, so we use bar 3 of the original
  detrended signal for the in-phase component I1. }

Q1 = (0.25*detrender[0] + 0.75*detrender[2] - 0.75*detrender[4] - 0.25*detrender[6]) * (0.046*pd[1] + 0.332);
I1 = detrender[3];

{ That's it, the Hilbert transform is complete.

  We accomplish the first smoothing step without introducing phase
  error by advancing the phase of I1 and Q1 by 90 degrees. }

jI = 0.25 * I1 + 0.75 * I1[2] - 0.75 * I1[4] - 0.25 * I1[6];
jQ = 0.25 * Q1 + 0.75 * Q1[2] - 0.75 * Q1[4] - 0.25 * Q1[6];

{ Phasor addition to equalize amplitude due to quadrature calculations
  (and 3 bar averaging) }
I2 = I1 - jQ;
Q2 = Q1 + jI;

{ Smooth the I and Q components before applying the discriminator.
  This is a fairly strong exponential moving average (EMA).  We can
  use it because we are only interested in the RELATIVE phase distortion
  between two components (yesterday's and today's phase), not the
  absolute distortion which the EMA would destroy. }

I2 = 0.15 * I2 + 0.85 * I2[1];
Q2 = 0.15 * Q2 + 0.85 * Q2[1];

{ Smoothing was crucial because the next step involves multiplication
  and it is imperative to remove any noise component before performing
  the multiplication.  We do a complex multiplication of the complex
  conjugate of the current signal with the signal delayed one bar.

  Apply a homodyne discriminator (which works well in low signal-to-noise
  environments).  Homodyne means use the signal multiplied by itself one
  bar ago to produce a zero-frequency beat note, which carries the phase
  angle of the one-bar change.  This one-bar rate of change in phase is
  exactly the cycle period. }

{ complex conjugate multiplication: (I2(0) - i*Q2(0)) * (I2(1) + i*Q2(1)) }
Re = I2 * I2[1] + Q2 * Q2[1];
Im = I2 * Q2[1] - Q2 * I2[1];

{ Smooth to remove undesired cross products. }

Re = 0.2 * Re + 0.8 * Re[1];
Im = 0.2 * Im + 0.8 * Im[1];

{ Compute Cycle Period. }

If Im <> 0 And Re <> 0 Then pd = 360 / ArcTangent(Im / Re);
If pd > 1.5 * pd[1] Then pd = 1.5 * pd[1];
If pd < 0.6666667 * pd[1] Then pd = 0.6666667 * pd[1];
If pd < 6 Then pd = 6;
If pd > 50 Then pd = 50;
pd = 0.2 * pd + 0.8 * pd[1];  { smooth yet again }

end;

HilbertPeriod = pd;


-- 
  ,|___    Alex Matulich -- alex@xxxxxxxxxxxxxx
 // +__>   Director of Research and Development
 //  \ 
 //___)    Unicorn Research Corporation -- http://unicorn.us.com