This is an implementation of John Ehlers’ Instantaneous Trendline, as described in Market Mode Strategies (1999-10-19).
The code has been slightly enhanced to return a Zero Lag exponential moving average, like it was done here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
// Instantaneous Trendline // Market Mode Strategies // 1999-10-19 John F. Ehlers // http://www.jamesgoulding.com/Research_II/Ehlers/Ehlers%20(Market%20Mode%20Strategies).doc Price = (high+low)/2 Imult = .635 Qmult = .338 If BarIndex > 6 then // Detrend Price Value3 = Price - Price[7] // Compute InPhase and Quadrature components Inphase = 1.25*(Value3[4] - Imult*Value3[2]) + Imult*InPhase[3] Quadrature = Value3[2] - Qmult*Value3 + Qmult*Quadrature[2] // Use ArcTangent to compute the current phase If ABS(InPhase + InPhase[1]) > 0 then a = ABS((Quadrature+Quadrature[1]) / (InPhase+InPhase[1])) Phase = ATAN(a) Endif // Resolve the ArcTangent ambiguity If InPhase < 0 and Quadrature > 0 then Phase = 180 - Phase Endif If InPhase < 0 and Quadrature < 0 then Phase = 180 + Phase Endif If InPhase > 0 and Quadrature < 0 then Phase = 360 - Phase Endif // Compute a differential phase, resolve phase wraparound, and limit delta phase errors DeltaPhase = Phase[1] - Phase If Phase[1] < 90 and Phase > 270 then DeltaPhase = 360 + Phase[1] - Phase Endif If DeltaPhase < 7 then DeltaPhase = 7 Endif If DeltaPhase > 60 then DeltaPhase = 60 Endif // Sum DeltaPhases to reach 360 degrees. The sum is the instantaneous period. InstPeriod = 0 Value4 = 0 For count = 0 to 40 do Value4 = Value4 + DeltaPhase[count] If Value4 > 360 and InstPeriod = 0 then InstPeriod = count Endif Next // Resolve Instantaneous Period errors and smooth If InstPeriod = 0 then InstPeriod = InstPeriod[1] Endif Value5 = .25*InstPeriod + .75*Value5[1] // Compute Trendline as simple average over the measured dominant cycle period Period = ROUND(Value5) Trendline = 0 For count = 0 to Period + 1 do Trendline = Trendline + Price[count] Next If Period > 0 then Trendline = Trendline / (Period + 2) Endif Value11 = .33*(Price + .5*(Price - Price[3])) + .67*Value11[1] If barindex < 26 then Trendline = Price Value11 = Price Endif Endif Return Trendline as "TR", Value11 as "ZL" |
A more recent formula of Hilbert Transform, described in Squelch those Whipsaws (2000-24-03), can be used, by replacing the beginning of the code with:
1 2 3 4 5 6 7 8 |
If BarIndex > 5 then // Compute InPhase and Quadrature components Value1 = Price - Price[6] Value2 = Value1[3] Value3 = .75*(Value1 - Value1[6]) + .25*(Value1[2] - Value1[4]) InPhase = .33*Value2 + .67*InPhase[1] Quadrature = .2*Value3 + .8*Quadrature[1] |
The attached screenshot shows the Instantaneous Trendline using original description (top) of and the alternative Hilbert Transform formula (bottom).
Share this
No information on this site is investment advice or a solicitation to buy or sell any financial instrument. Past performance is not indicative of future results. Trading may expose you to risk of loss greater than your deposits and is only suitable for experienced investors who have sufficient financial means to bear such risk.
ProRealTime ITF files and other attachments :PRC is also on YouTube, subscribe to our channel for exclusive content and tutorials
Thanks a lot for this new valuable addition to our library. I changed line 76 with “barindex” instead of “currentbar”.
Thanks. I’ve noticed this leftover after submission, but it was too late for editing. BTW, I think it would be nice to add the ability to edit our own posts.
Thanks Horance for porting this code to PRT.
I would like to bring some speedup to your code. I’ve been willing to use it some strategies, but the computation time is disastrous when backtesting.
I optimized some parts of the code. The resulting figures are unchanged, but it the code is 4 time quicker to compute.
I did 2 optimizations :
1/ sum of deltaPhases can be computed more quickly if you observe that the current InstPeriod is close to the previous one. (which by the way is functionaly quite intutive).
Therefore, we reuse the previous InstPeriod to compute the summation[InstPeriod](DeltaPhase) .Then we check if we went above or below 360, then we adjust the current InstPeriod with a few loops…
On my machine, the code is twice faster on this part…
2/ averaging using the calculated period
In PRT, loops are slow, very slow. We are much better off, if we use native function like average…
The gain in speedup is approx a ratio of 4 on this part…
I’m providing the full code below.
Thanks again
// Instantaneous Trendline
// Market Mode Strategies
// 1999-10-19 John F. Ehlers
// http://www.jamesgoulding.com/Research_II/Ehlers/Ehlers%20(Market%20Mode%20Strategies).doc
Price = (high+low)/2
Imult = .635
Qmult = .338
If BarIndex > 6 then
// Detrend Price
Value3 = Price – Price[7]
// Compute InPhase and Quadrature components
Inphase = 1.25*(Value3[4] – Imult*Value3[2]) + Imult*InPhase[3]
Quadrature = Value3[2] – Qmult*Value3 + Qmult*Quadrature[2]
// Use ArcTangent to compute the current phase
If ABS(InPhase + InPhase[1]) > 0 then
a = ABS((Quadrature+Quadrature[1]) / (InPhase+InPhase[1]))
Phase = ATAN(a)
Endif
// Resolve the ArcTangent ambiguity
If InPhase 0 then
Phase = 180 – Phase
Endif
If InPhase < 0 and Quadrature 0 and Quadrature < 0 then
Phase = 360 – Phase
Endif
// Compute a differential phase, resolve phase wraparound, and limit delta phase errors
DeltaPhase = Phase[1] – Phase
If Phase[1] 270 then
DeltaPhase = 360 + Phase[1] – Phase
Endif
If DeltaPhase 60 then
DeltaPhase = 60
Endif
// Sum DeltaPhases to reach 360 degrees. The sum is the instantaneous period.
InstPeriod = InstPeriod[1]+1
Value4 = summation[InstPeriod](DeltaPhase)
if Value4 360 then
if Value4 > 360 then
while Value4 > 360 do
InstPeriod = InstPeriod -1
Value4 = Value4 – DeltaPhase[InstPeriod]
wend
else
while Value4 < 360 do
Value4 = Value4 + DeltaPhase[InstPeriod]
InstPeriod = InstPeriod + 1
wend
InstPeriod = InstPeriod -1
endif
endif
// Resolve Instantaneous Period errors and smooth
If InstPeriod = 0 then
InstPeriod = InstPeriod[1]
Endif
SmoothPeriod = .25*InstPeriod + .75*SmoothPeriod[1]
// Compute Trendline as simple average over the measured dominant cycle period
Period = ROUND(SmoothPeriod)
Trendline= average [Period + 2](Price)
Value11 = .33*(Price + .5*(Price – Price[3])) + .67*Value11[1]
If barindex < 26 then
Trendline = Price
Value11 = Price
Endif
Endif
Return Trendline as "TR", Value11 as "ZL"