Ehler's Deviation-Scaled Fisher Transform Oscillator
Forums › ProRealTime English forum › ProBuilder support › Ehler's Deviation-Scaled Fisher Transform Oscillator
- This topic has 12 replies, 2 voices, and was last updated 6 years ago by Nicolas.
Tagged: fisher, fisher transform
-
-
09/22/2018 at 5:43 PM #81066
Hi,
I’m wondering if someone would like to take a look at coding John Ehlers’ recently created/released new indicator called the Deviated Scaled Oscillator with the Fisher Transform for mean reversion swing traders. The oscillator was featured in this October’s Stocks and Commodities Magazine. For a full explanation please see the 5 screenshots I took of the article including the code.
The theory behind the indicator is to remove the fat tails of a distribution to give a more perfect bell shaped Gaussian distribution which is necessary to trade low probability events at the extreme ends of the oscillator. This allows a price series to be placed into a probability distribution so that the probabilities of extreme moves corresponds to a normal standard deviation bell curve (distribution) which allows the prediction, in percentage terms, for the odds of a +2/-2 standard deviation move away from the mean price (centre of the bell curve).
I also found the code today on https://www.tradingview.com/script/DdLQBt87-Ehlers-Fisherized-Deviation-Scaled-Oscillator/
The code is as follows:
Ehler’s Deviation Scaled Inverse Fisher Transform Oscillator12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364//@version=3// Copyright (c) 2018-present, Alex Orekhov (everget)// Ehlers Fisherized Deviation-Scaled Oscillator script may be freely distributed under the MIT license.study("Ehlers Fisherized Deviation-Scaled Oscillator", shorttitle="EFDSO")length = input(title="Length", type=integer, defval=40, minval=1)ssfLength = input(title="Super Smoother Filter Length", type=integer, defval=20, minval=1)numberOfPoles = input(title="Number of Poles", type=integer, defval=2, options=[2, 3])overboughtLevel = input(title="Overbought Level", type=float, defval=2, step=0.1)oversoldLevel = input(title="Oversold Level", type=float, defval=-2, step=0.1)src = input(title="Source", type=source, defval=close)PI = 2 * asin(1)twoPoleSuperSmootherFilter(src, length) =>arg = sqrt(2) * PI / lengtha1 = exp(-arg)b1 = 2 * a1 * cos(arg)c2 = b1c3 = -pow(a1, 2)c1 = 1 - c2 - c3ssf = 0.0ssf := c1 * src + c2 * nz(ssf[1]) + c3 * nz(ssf[2])threePoleSuperSmootherFilter(src, length) =>arg = PI / lengtha1 = exp(-arg)b1 = 2 * a1 * cos(1.738 * arg)c1 = pow(a1, 2)coef2 = b1 + c1coef3 = -(c1 + b1 * c1)coef4 = pow(c1, 2)coef1 = 1 - coef2 - coef3 - coef4ssf = 0.0ssf := coef1 * src + coef2 * nz(ssf[1]) + coef3 * nz(ssf[2]) + coef4 * nz(ssf[3])zeros = src - nz(src[2])// Ehlers Super Smoother Filteressf = numberOfPoles == 2? twoPoleSuperSmootherFilter((zeros + zeros[1]) / 2, ssfLength): threePoleSuperSmootherFilter((zeros + zeros[1]) / 2, ssfLength)// Rescale filter in terms of Standard DeviationsscaledFilter = 0.0scaledFilter := stdev(essf, length) != 0? essf / stdev(essf, length): nz(scaledFilter[1])// Apply Fisher Transform to establish real Gaussian Probability Distributionefdso = 0.0efdso := abs(scaledFilter) < 2? 0.5 * log((1 + scaledFilter / 2) / (1 - scaledFilter / 2)): nz(efdso[1])efdsoColor = efdso > overboughtLevel ? #0ebb23 : efdso < oversoldLevel ? #cc0000 : #674ea7plot(efdso, title="EFDSO", linewidth=2, color=efdsoColor, transp=0)hline(overboughtLevel, title="Overbought Level", linestyle=dotted, color=#e69138)hline(0, title="Zero Level", linestyle=dotted, color=#989898)hline(oversoldLevel, title="Oversold Level", linestyle=dotted, color=#e69138)Looks interesting and the article is definitely worth the read. The last two article images with the code will be posted separately.
09/22/2018 at 5:49 PM #81071This short article gives a good overview of the Fisher Transform Oscillator:
http://www.trade-robots.com/blog/the-fisher-transform-oscillator
(hopefully the last 2 images from the article “Probability – Probably a Good Thing to Know, ” with the code, will upload on this second attempt)
10/05/2018 at 1:08 PM #82040I’ve lifted John Ehler’s Fisherized Deviation-Scaled Oscillator code from the last image above from October’s Stocks and Commodities Magazine and “translated” it into PRT although it’s non functioning at the moment due to my lack of coding skills. It’d be great if anyone can take a look at it and get it to work and explain what I missed (I wondered about the arrays at the top of the magazine article code)?
Cheers
BardEhler's Deviation-Scaled Fisher Transform Oscillator123456789101112131415161718192021222324252627282930313233Period = 40If Barindex=1 then// Super Smoother Filtera1= Exp(-1.414 * 3.14159 / (0.5*Period))b1= 2*a1 * Cos(1.414*180 / (0.5*Period))c2= b1c3= -a1 * a1c1= 1 - c2 - c3Endif// Produce nominal zero mean with zeros in the transfer response at DC & Nyquist with no spectral distortion// Nominally whitens the spectrum because 6db per octave rolloffZeros= Close-Close[2]// Super Smoother FilterFilt= c1*(Zeros+Zeros[1])/2 + c2*Filt[1] + c3*Filt[2]// Compute Standard DeviationRMS= 0 //Root Mean SqrFor Count=0 to Period-1RMS= RMS + Filt[Count]*Filt[Count]NextRMS=SQRT(RMS/Period)// Rescale Filter in terms of Standard DeviationsIf RMS<>0 Then ScaledFilt= Filt/RMS// Apply Fisher Transform to Establish Real Gaussian Prob Dist’n.If Abs(ScaledFilt) < 2 Then FisherFilt= 0.5*Log((1 + ScaledFilt/2) / (1-ScaledFilt/2))Return FisherFilt coloured (66,66,255) as “Fisher Filter", 0 style(dottedline) as "0"10/05/2018 at 1:14 PM #82042You were not too far to make it works! 🙂
I think I get it sorted from your code:
123456789101112131415161718192021222324252627282930313233343536Period = 40If Barindex>Period then// Super Smoother Filtera1= Exp(-1.414 * 3.14159 / (0.5*Period))b1= 2*a1 * Cos(1.414*180 / (0.5*Period))c2= b1c3= -a1 * a1c1= 1 - c2 - c3// Produce nominal zero mean with zeros in the transfer response at DC & Nyquist with no spectral distortion// Nominally whitens the spectrum because 6db per octave rolloffZeros= Close-Close[2]// Super Smoother FilterFilt= c1*(Zeros+Zeros[1])/2 + c2*Filt[1] + c3*Filt[2]// Compute Standard DeviationRMS= 0 //Root Mean SqrFor Count=0 to Period-1RMS= RMS + Filt[Count]*Filt[Count]NextRMS=SQRT(RMS/Period)// Rescale Filter in terms of Standard DeviationsIf RMS<>0 ThenScaledFilt= Filt/RMSendif// Apply Fisher Transform to Establish Real Gaussian Prob Dist’n.If Abs(ScaledFilt) < 2 ThenFisherFilt= 0.5*Log((1 + ScaledFilt/2) / (1-ScaledFilt/2))EndifendifReturn FisherFilt coloured (66,66,255) as "Fisher Filter", 0 style(dottedline) as "0"1 user thanked author for this post.
10/05/2018 at 3:29 PM #82077Great! Nice one @nicolas, I bolted different parts of your John Ehler’s indicator codes together. 😄
I’m wondering why is the barindex “greater” than 40? I thought the Super Smoother Filter was being applied to data under 40 periods not over 40 periods?
And Ehler’s wrote “endif” where I placed it (on line 10), yet by moving that first “endif” to the very end of the calculations it now uses all the different components of the indicator to give that final output of FisherFilt,… so why is Ehler’s code not written with the “endif” moved to the very bottom?
Also is there a way of normalising the output to only values between -3 and +3 std deviations?
Cheers
Bard10/05/2018 at 3:41 PM #82078I did not confirm that the code you wrote is the same as the original. I just solved the issue of why it was not displaying anything. About the barindex>period, it is necessary because otherwise the platform will not calculate it. We obviously need to have read at least more than the desired period to calculate it.
Normalization is an easy process, I’m sure you’ll be able to make it 🙂
1 user thanked author for this post.
10/05/2018 at 4:11 PM #82085Not too shabby results either, no optimisation, just bought on a crossover of -1 std deviation (and a cross under of 1 std dev to short it) and used the zero line as an exit.
I then stuck it on a 2 year test on mean reverting currencies from Jan 2016 to Dec 2017 Daily:
GBP/USD, EUR/HUF, GBP/EUR, & USD/CHF. (The USD/JPY had a 105% return but a 46% Drawdown). Pls See Screens.Obviously it can get you in on the wrong side of a trend but I don’t know if I’d ever be comfortable leaving an automated system on “autopilot!”
10/05/2018 at 7:52 PM #82119I appreciate the “vote of confidence” lol, I tried using Ehler’s code from the third and last screenshot in this RocketRSI post: #6978 from https://www.prorealcode.com/topic/john-ehlers-rocket-rsi/
but it’d didn’t accept the “Then FisherFilt” part, particularly: FisherFilt was highlighted in red in the indicator code window:
Limit FisherFilt output to +/-3 Standard Deviations1234If FisherFilt > 0.999 Then FisherFilt = 0.999EndifIf FisherFilt < -0.999 Then FisherFilt = -0.999EndifI also saw @Despairs (Rocket RSI) version of code using “closes up” and “closes down:”
Limit FisherFilt output to +/-3 Standard Deviations1234567891011121314151617//Accumulate "Closes Up" and "Closes Down"CU = 0CD = 0for count = 0 to Period -1 doif Filt[count] - Filt[count + 1] > 0 thenCU = CU + Filt[count] - Filt[count + 1]endifif Filt[count] - Filt[count + 1] < 0 thenCD = CD + Filt[count + 1] - Filt[count]endifnextif CU + CD <> 0 thenFisherFilt = ( CU - CD ) / ( CU + CD )endifFisherFilt = min(max(FisherFilt,-0.999),0.999)But that didn’t work either as I saw some std deviations of -3.5 and +4.0.
Conceptually the idea is to take those FisherFilt output results and normalise them to the new range parameters. My first thought though is if 99.7% of values lie between -3 and +3 std deviations then how would you express 4.0, or even 6.0, std deviation moves on an oscillators right hand range scale?Actually I just refreshed my memory and looked this up: A 3-sigma event occurs 99.73 percent of the time under a normal distribution bell curve, a 4-sigma event: 99.999968 percent of the time and a 5-sigma outlier: 99.9999997 percent. (0.0000003 percent of the time). I’d like an oscillator scale with a 6 std deviation scale please and — assuming it’s not the end of the world — I’d take a largish bet on a reversion to the mean for that event. Double lol… Wait why am I laughing? I’ve seen a Kase 7.5 Dev Stop exceeded a few times! 😄
https://www.sixsigma-institute.org/Six_Sigma_DMAIC_Process_Measure_Phase_Process_Capability.php
10/08/2018 at 9:01 AM #82237You can try this below version, where +100 or -100 state for 3 standard deviations:
123456789101112131415161718192021222324252627282930313233343536373839Period = 40If Barindex>Period then// Super Smoother Filtera1= Exp(-1.414 * 3.14159 / (0.5*Period))b1= 2*a1 * Cos(1.414*180 / (0.5*Period))c2= b1c3= -a1 * a1c1= 1 - c2 - c3// Produce nominal zero mean with zeros in the transfer response at DC & Nyquist with no spectral distortion// Nominally whitens the spectrum because 6db per octave rolloffZeros= Close-Close[2]// Super Smoother FilterFilt= c1*(Zeros+Zeros[1])/2 + c2*Filt[1] + c3*Filt[2]// Compute Standard DeviationRMS= 0 //Root Mean SqrFor Count=0 to Period-1RMS= RMS + Filt[Count]*Filt[Count]NextRMS=SQRT(RMS/Period)// Rescale Filter in terms of Standard DeviationsIf RMS<>0 ThenScaledFilt= Filt/RMSendif// Apply Fisher Transform to Establish Real Gaussian Prob Dist’n.If Abs(ScaledFilt) < 2 ThenFisherFilt= 0.5*Log((1 + ScaledFilt/2) / (1-ScaledFilt/2))Endifresult = (fisherfilt*100)/(rms*3)endifReturn result coloured (66,66,255) as "Fisher Filter", 0 style(dottedline) as "0"10/08/2018 at 1:39 PM #82277Thanks @nicolas, I see now that rms = the std deviation when there is a zero mean and the math looks right but the oscillator scale is not how I was expecting it? Pls see screens of the original code and the 3 std deviation code, cheers.
10/08/2018 at 3:42 PM #8228810/08/2018 at 5:16 PM #82296Thanks for the screenshot, if it’s bounded by +/-100 why do the results go as high as 200, (it’s a 100% (covering 3 std devs)?
I used the copy icon in the top right here on PRC and pasted as normal into PRT, yet I get this on the Swissy:10/10/2018 at 8:45 AM #82425 -
AuthorPosts
Find exclusive trading pro-tools on