Skip to content

Instantly share code, notes, and snippets.

@flare9x
Created December 18, 2018 12:18
Show Gist options
  • Save flare9x/089be64732079134faa0a50332e4437b to your computer and use it in GitHub Desktop.
Save flare9x/089be64732079134faa0a50332e4437b to your computer and use it in GitHub Desktop.
John Ehlers Market Cycles
##############################
# TO DO
# 5-2. Dominant Cycle Measured by Zero Crossings of the Band-Pass Filter - Validated against TS up to DC portion
# 8-3. Autocorrelation Periodogram - Validated against TS up to Normalization
# Outstanding
# 9-1 onwards
##############################
using Statistics
@doc """
SuperSmoother(x::Array{Float64}; n::Int64=10)::Array{Float64}
Super Smoother - Equation 3-3
"""
function SuperSmoother(x::Array{Float64}; n::Int64=10)::Array{Float64}
@assert n<size(x,1) && n>0 "Argument n out of bounds."
a = exp(-1.414*3.14159 / n)
b = 2 * a * cosd(1.414 * 180 / n)
c2 = b
c3 = -a * a
c1 = 1 - c2 - c3
Super = zeros(size(x,1))
@inbounds for i = 3:length(x)
Super[i] = c1 * (x[i] + x[i-1]) / 2 + c2 * Super[i-1] + c3 * Super[i-2]
end
return Super
end
@doc """
Decycler(x::Array{Float64}; n::Int64=60)::Array{Float64}
Decycler - Equation 4-1
"""
function Decycler(x::Array{Float64}; n::Int64=60)::Array{Float64}
@assert n<size(x,1) && n>0 "Argument n out of bounds."
#Highpass filter cyclic components whose periods are shorter than “cutoff” bars
alpha1 = ((cosd(360 / n) + sind(360 / n) - 1)) / (cosd(360 / n))
Decycle = zeros(size(x,1))
@inbounds for i in 2:length(x)
Decycle[i] = (alpha1 / 2)*(x[i] + x[i-1]) + (1- alpha1)*Decycle[i-1]
end
return Decycle
end
@doc """
Decycle_OSC(x::Array{Float64}; LPPeriod::Int64=30, HPPeriod::Int64=60)::Array{Float64}
Decycle Oscillator - Equation 4-2
"""
function Decycle_OSC(x::Array{Float64}; LPPeriod::Int64=30, HPPeriod::Int64=60)::Array{Float64}
@assert HPPeriod<size(x,1) && HPPeriod>0 "Argument HPPeriod out of bounds."
alpha1 = (cosd(.707*360 / LPPeriod) + sind(.707*360 / LPPeriod) - 1) / cosd(.707*360 / LPPeriod)
alpha2 = (cosd(.707*360 / HPPeriod) + sind(.707*360 / HPPeriod) - 1) / cosd(.707*360 / HPPeriod)
HP1 = zeros(size(x,1))
HP2 = zeros(size(x,1))
Decycle_OSC = zeros(size(x,1))
@inbounds for i in 3:length(x)
HP1[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] + x[i-2]) + 2*(1 - alpha1)*HP1[i-1] - (1 - alpha1)* (1 - alpha1)*HP1[i-2]
HP2[i] = (1 - alpha2 / 2)*(1 - alpha2 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha2)*HP2[i-1] - (1 - alpha2)*(1 - alpha2)*HP2[i-2]
end
Decycle_OSC .= HP2 .- HP1
return Decycle_OSC
end
@doc """
BandPassFilter(x::Array{Float64}; n::Int64=30, bandwidth::Float64=.3)::Array{Float64}
Band Pass Filter - Equation 5-1
"""
function BandPassFilter(x::Array{Float64}; n::Int64=30, bandwidth::Float64=.3)::Array{Float64}
@assert n<size(x,1) && n>0 "Argument n out of bounds."
alpha2 = (cosd(.25*bandwidth*360 / n) + sind(.25*bandwidth*360 / n) - 1) / cosd(.25*bandwidth*360 /n)
beta1 = cosd(360 / n);
gamma1 = 1 / cosd(360*bandwidth / n)
alpha1 = gamma1 - sqrt(gamma1*gamma1 - 1)
HP = zeros(size(x,1))
BP = zeros(size(x,1))
@inbounds for i in 3:length(x)
HP[i] = (1 + alpha2 / 2)*(x[i] - x[i-1]) + (1- alpha2)*HP[i-1]
BP[i] = .5*(1 - alpha1)*(HP[i] - HP[i-2]) + beta1*(1 + alpha1)*BP[i-1] - alpha1*BP[i-2]
end
# Signal
Signal = zeros(size(x,1))
Peak = zeros(size(x,1))
@inbounds for i in 2:length(BP)
Peak[i] = .991*Peak[i-1]
if abs(BP[i]) > Peak[i]
Peak[i] = abs(BP[i])
if Peak[i] != 0
Signal[i] = BP[i] / Peak[i]
end
else
Signal[i] = BP[i] / Peak[i]
end
end
# Replace Nan to 0
@inbounds for i in 1:length(Signal)
if isnan(Signal[i]) == 1
Signal[i] = 0.0
else
Signal[i] = Signal[i]
end
end
# Trigger
alpha2 = (cosd(1.5*bandwidth*360 / n) + sind(1.5*bandwidth*360 / n) - 1) / cosd(1.5*bandwidth*360 /n)
BP_Trigger = zeros(size(x,1))
i=1
@inbounds for i = 2:length(x)
BP_Trigger[i] = (1 + alpha2 / 2)*(Signal[i] - Signal[i-1]) +(1 -alpha2)*BP_Trigger[i-1]
end
return BP_Trigger
end
#="""
TO DO - Help Wanted - DC Portion of Calculation
Zero Crossings of the Band-Pass Filter - Equation 5-2
"""
=#
@doc """
HurstCoefficient(x::Array{Float64}; n::Int64=30, LPPeriod::Int64=20)::Array{Float64}
Hurst Coefficient - Equation 6-1
"""
function HurstCoefficient(x::Array{Float64}; n::Int64=30, LPPeriod::Int64=20)::Array{Float64}
@assert n<size(x,1) && n>0 "Argument n out of bounds."
@assert iseven(n) "n must be an even number."
# Smooth with a Super Smoother Filter from equation 3-3
half_n = Int64(n/2)
a1 = exp(-1.414*3.14159 / LPPeriod)
b1 = 2*a1*cosd(1.414*180 / LPPeriod)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
# Find rolling maximum and minimum
HH = zeros(size(x,1))
LL = zeros(size(x,1))
N3 = zeros(size(x,1))
@inbounds for i = n:size(x,1)
HH[i] = maximum(x[i-n+1:i])
LL[i] = minimum(x[i-n+1:i])
N3[i] = (HH[i] - LL[i]) / n
end
# Rolling min and max half of n
HH = zeros(size(x,1))
LL = zeros(size(x,1))
N1 = zeros(size(x,1))
@inbounds for i = half_n:size(x,1)
HH[i] = maximum(x[i-half_n+1:i])
LL[i] = minimum(x[i-half_n+1:i])
N1[i] = (HH[i] - LL[i]) / half_n
end
# Set trailing close half of n
HH = [fill(0,half_n); x[1:length(x)-half_n]]
LL = [fill(0,half_n); x[1:length(x)-half_n]]
HH_out = zeros(size(x,1))
LL_out = zeros(size(x,1))
N2 = zeros(size(x,1))
@inbounds for i = half_n:size(x,1)
HH_out[i] = maximum(HH[i-half_n+1:i])
LL_out[i] = minimum(LL[i-half_n+1:i])
N2[i] = (HH_out[i] - LL_out[i])/(half_n)
end
# Hurst
Dimen = zeros(size(x,1))
Hurst = zeros(size(x,1))
SmoothHurst = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
if N1[i] > 0 && N2[i] > 0 && N3[i] > 0
Dimen[i] = .5*((log(N1[i]+ N2[i]) - log(N3[i])) / log(2) + Dimen[i-1])
Hurst[i] = 2 - Dimen[i]
SmoothHurst[i] = c1*(Hurst[i] + Hurst[i-1]) / 2 + c2*SmoothHurst[i-1]+ c3*SmoothHurst[i-2];
end
end
return SmoothHurst
end
@doc """
HPLPRoofingFilter(x::Array{Float64}; HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
HP LP Roofing Filter - Equation 7-1
"""
function HPLPRoofingFilter(x::Array{Float64}; HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
@assert HPPeriod<size(x,1) && HPPeriod>0 "Argument HPPeriod out of bounds."
# Highpass filter cyclic components whose periods are shorter than 48 bars
alpha1 = (cosd(360 / HPPeriod) + sind(360 / HPPeriod) - 1) / cosd(360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 2:size(x,1)
HP[i] = (1 - alpha1 / 2)*(x[i] - x[i-1]) + (1 - alpha1)*HP[i-1]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPPeriod) # may wish to make this an argument in function
b1 = 2*a1*cosd(1.414*180 / LPPeriod) # may wish to make this an argument in function
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
LP_HP_Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
LP_HP_Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*LP_HP_Filt[i-1] + c3*LP_HP_Filt[i-2]
end
return LP_HP_Filt
end
@doc """
ZeroMeanRoofingFilterK0(x::Array{Float64}; HPPeriod::Int64=48, Smooth::Int64=10)::Array{Float64}
Zero Mean Roofing Filter - Lag 0 - Equation 7-2
K0 = Lag 0
# Lag 0 Is Most Responsive
# Ehlers describes using Lag 0 and Lag 1 cross overs/unders as a signal trigger for buying / selling
"""
function ZeroMeanRoofingFilterK0(x::Array{Float64}; HPPeriod::Int64=48, Smooth::Int64=10)::Array{Float64}
@assert HPPeriod<size(x,1) && HPPeriod>0 "Argument HPPeriod out of bounds."
# Highpass filter cyclic components whose periods are shorter than 48 bars
alpha1 = (cosd(360 / HPPeriod) + sind(360 / HPPeriod) - 1) /cosd(360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 2:size(x,1)
HP[i] = (1 - alpha1 / 2)*(x[i] - x[i-1]) +(1 - alpha1)*HP[i-1]
end
#Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / Smooth)
b1 = 2*a1*cosd(1.414*180 / Smooth)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Zero_Mean_Filt = zeros(size(x,1))
Zero_Mean_Filt2 = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Zero_Mean_Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Zero_Mean_Filt[i-1] + c3*Zero_Mean_Filt[i-2]
Zero_Mean_Filt2[i] = (1 - alpha1 / 2)*(Zero_Mean_Filt[i] - Zero_Mean_Filt[i-1]) + (1 - alpha1)*Zero_Mean_Filt2[i-1]
end
return Zero_Mean_Filt
end
ZeroMeanRoofingFilterK0(x=signal,HPPeriod=48, smooth=10)
@doc """
ZeroMeanRoofingFilterK1(x::Array{Float64}; HPPeriod::Int64=48, Smooth::Int64=10)::Array{Float64}
Zero Mean Roofing Filter - Lag 1 - Equation 7-2
K1 = Lag 1
"""
function ZeroMeanRoofingFilterK1(x::Array{Float64}; HPPeriod::Int64=48, Smooth::Int64=10)::Array{Float64}
@assert HPPeriod<size(x,1) && HPPeriod>0 "Argument HPPeriod out of bounds."
# Highpass filter cyclic components whose periods are shorter than 48 bars
alpha1 = (cosd(360 / HPPeriod) + sind(360 / HPPeriod) - 1) /cosd(360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 2:size(x,1)
HP[i] = (1 - alpha1 / 2)*(x[i] - x[i-1]) +(1 - alpha1)*HP[i-1]
end
#Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / Smooth)
b1 = 2*a1*cosd(1.414*180 / Smooth)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Zero_Mean_Filt = zeros(size(x,1))
Zero_Mean_Filt2 = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Zero_Mean_Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Zero_Mean_Filt[i-1] + c3*Zero_Mean_Filt[i-2]
Zero_Mean_Filt2[i] = (1 - alpha1 / 2)*(Zero_Mean_Filt[i] - Zero_Mean_Filt[i-1]) + (1 - alpha1)*Zero_Mean_Filt2[i-1]
end
return Zero_Mean_Filt2
end
@doc """
RoofingFilterIndicator(x::Array{Float64}; LPPeriod::Int64=40,HPPeriod::Int64=80)::Array{Float64}
Roofing Filter As Indicator - Equation 7-3
"""
function RoofingFilterIndicator(x::Array{Float64}; LPPeriod::Int64=40,HPPeriod::Int64=80)::Array{Float64}
@assert HPPeriod<size(x,1) && HPPeriod>0 "Argument HPPeriod out of bounds."
# Highpass filter cyclic components whose periods are shorter than 48 (n) bars
alpha1 = (cosd(.707*360 / HPPeriod) + sind(.707*360 /HPPeriod) - 1) / cosd(.707*360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 3:length(x)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] + x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
#Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPPeriod)
b1 = 2*a1*cosd(1.414*180 / LPPeriod)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Roof_filt_Indicator = zeros(size(x,1))
@inbounds for i = 3:length(x)
Roof_filt_Indicator[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Roof_filt_Indicator[i-1] + c3*Roof_filt_Indicator[i-2]
end
return Roof_filt_Indicator
end
@doc """
ModifiedStochastic(x::Array{Float64}; n::Int64=20, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
Modified Stochastic - Equation 7-4
"""
function ModifiedStochastic(x::Array{Float64}; n::Int64=20, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
@assert n<size(x,1) && n>0 "Argument n out of bounds."
#Highpass filter cyclic components whose periods are shorter than 48 bars
alpha1 = (cosd(.707*360 / HPPeriod) + sind(.707*360 / HPPeriod) - 1) /cosd(.707*360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1]+ x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 -alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPPeriod)
b1 = 2*a1*cosd(1.414*180 / LPPeriod)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Highest and lowest filt over n width
HighestC = zeros(size(x,1))
LowestC = zeros(size(x,1))
Stoc = zeros(size(x,1))
MyStochastic = zeros(size(x,1))
@inbounds for i = n:size(x,1)
HighestC[i] = maximum(Filt[i-n+1:i])
LowestC[i] = minimum(Filt[i-n+1:i])
Stoc[i] = (Filt[i] - LowestC[i]) / (HighestC[i] - LowestC[i])
MyStochastic[i] = c1*(Stoc[i] + Stoc[i-1]) / 2 + c2*MyStochastic[i-1] + c3*MyStochastic[i-2]
end
return MyStochastic
end
@doc """
ModifiedRSI(x::Array{Float64}; n::Int64=10, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
Modified RSI - Equation 7-5
"""
function ModifiedRSI(x::Array{Float64}; n::Int64=10, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
@assert n<size(x,1) && n>0 "Argument n out of bounds."
# Highpass filter cyclic components whose periods areshorter than 48 bars
alpha1 = (cosd(.707*360 / HPPeriod) + sind(.707*360 / HPPeriod) - 1) /cosd(.707*360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i =3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 -alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPPeriod)
b1 = 2*a1*cosd(1.414*180 / LPPeriod)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
ClosesUp = zeros(size(x,1))
ClosesDn = zeros(size(x,1))
filtdiff = zeros(size(x,1))
posDiff= zeros(size(x,1))
negDiff= zeros(size(x,1))
# pos and neg diffs
@inbounds for i = 2:size(x,1)
# difference
filtdiff[i] = Filt[i] - Filt[i-1]
if filtdiff[i] > 0
posDiff[i] = filtdiff[i]
elseif filtdiff[i] < 0
negDiff[i] = abs(filtdiff[i])
end
end
# Running Sums of Filt
posSum = zeros(size(x,1))
negSum = zeros(size(x,1))
denom = zeros(size(x,1))
rsi = zeros(size(x,1))
@inbounds for i = n:size(x,1)
posSum[i] = sum(posDiff[i-n+1:i])
negSum[i] = sum(negDiff[i-n+1:i])
denom[i] = posSum[i]+negSum[i]
end
# RSI
MyRSI = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
if denom != 0 && denom[i-1] != 0
MyRSI[i] = c1*(posSum[i] /denom[i] + posSum[i-1] / denom[i-1]) / 2 + c2*MyRSI[i-1] +c3*MyRSI[i-2]
end
end
return MyRSI
end
@doc """
AutoCorrelationIndicator(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
Autocorrelation Indicator - Equation 8-2
"""
function AutoCorrelationIndicator(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
@assert max_lag<size(x,1) && max_lag>0 "Argument max_lag out of bounds."
# Highpass filter cyclic components whose periods areshorter than 48 bars
alpha1 = (cosd(.707*360 / HPPeriod) + sind(.707*360 / HPPeriod) - 1) / cosd(.707*360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPPeriod)
b1 = 2*a1*cosd(1.414*180 / LPPeriod)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Pearson correlation for each value of lag
lags = min_lag:max_lag
AutoCorrOut = zeros(size(x,1), max_lag)
@inbounds for j = lags
# Lag series
lagged = [fill(0,j); Filt[1:length(Filt)-j]]
# Roll correlation width of lag and lagged version of itself
@inbounds for i = 96:size(x,1)
AutoCorrOut[i,j] = cor(lagged[i-j+1:i], Filt[i-j+1:i])
# Scale each correlation to range between 0 and 1
AutoCorrOut[i,j]= .5*(AutoCorrOut[i,j] + 1)
end
end
return AutoCorrOut
end
@doc """
SingleLagAutoCorrelationIndicator(x::Array{Float64}; lag::Int64=10, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
Single Lag Autocorrelation Indicator - Equation 8-2
"""
function SingleLagAutoCorrelationIndicator(x::Array{Float64}; lag::Int64=10, HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
@assert lag<size(x,1) && lag>0 "Argument n out of bounds."
# Highpass filter cyclic components whose periods areshorter than 48 bars
alpha1 = (cosd(.707*360 / HPPeriod) + sind(.707*360 / HPPeriod) - 1) / cosd(.707*360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPPeriod)
b1 = 2*a1*cosd(1.414*180 / LPPeriod)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Pearson correlation for specified lag
AutoCorrOut = zeros(size(x,1))
# Lag series
lagged = [fill(0,lag); Filt[1:length(Filt)-lag]]
# Roll correlation width of lag and lagged version of itself
@inbounds for i = lag:size(x,1)
AutoCorrOut[i] = cor(lagged[i-lag+1:i], Filt[i-lag+1:i])
#Scale each correlation to range between 0 and 1
AutoCorrOut[i]= .5*(AutoCorrOut[i] + 1)
end
return AutoCorrOut
end
@doc """
AutoCorrelationPeriodogram(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48,HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
Autocorrelation Periodogram- Equation 8-3
"""
function AutoCorrelationPeriodogram(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48,HPPeriod::Int64=48, LPPeriod::Int64=10)::Array{Float64}
@assert max_lag<size(x,1) && max_lag>0 "Argument max_lag out of bounds."
alpha1 = (cosd(.707*360 / 48) + sind(.707*360 / 48) - 1) / cosd(.707*360 / 48)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / 10)
b1 = 2*a1*cosd(1.414*180 / 10)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Pearson correlation for each value of lag
# Initialize correlation sums
lags = min_lag:max_lag
avglength = 3
temp = zeros(size(x,1))
Avg_Corr_Out = zeros(size(x,1), max_lag)
@inbounds for j = lags
# Lag series
lagged = [fill(0,j); Filt[1:length(Filt)-j]]
# Roll correlation width of lag and lagged version of itself
@inbounds for i = 96:size(x,1)
Avg_Corr_Out[i,j] = cor(lagged[i-avglength+1:i], Filt[i-avglength+1:i])
end
end
# Calcualte sine and cosine part
cosinePart = zeros(size(x,1), max_lag)
sinePart = zeros(size(x,1), max_lag)
sqSum = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
for k = 3:48
cosinePart[:,j] .= cosinePart[:,j] .+ Avg_Corr_Out[:,k] .* cosd(370 * k / j)
sinePart[:,j] .= sinePart[:,j] .+ Avg_Corr_Out[:,k] .* sind(370 * k / j)
sqSum[:,j] .= cosinePart[:,j].^2 .+ sinePart[:,j].^2
end
end
# Iterate over every i in j and smooth R by the .2 and .8 factors
R = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for i = 2:size(x,1)
R[i,j] = (.2*sqSum[i,j]) * (sqSum[i,j]) + (.8 *R[i-1,j])
end
end
#### validated against TS above ^^^^^ ###############
## although followed logic for normalization as below could not reproduce same result = revisit.
# Find Maximum Power Level for Normalization
# need to validate this and below!
MaxPwr = zeros(size(x,1), max_lag)
#MaxPwr = 0
@inbounds for j = min_lag:max_lag
@inbounds for i = 2:size(x,1)
MaxPwr[i,j] = .995*MaxPwr[i-1,j]
if R[i,j] > MaxPwr[i,j]
MaxPwr[i,j]= R[i,j]
end
end
end
Pwr = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for i = 1:size(x,1)
Pwr[i,j] = R[i,j] / MaxPwr[i,j]
end
end
# Replace Nan to 0
@inbounds for j = 1:max_lag
@inbounds for i = 1:size(x,1)
if isnan(Pwr[i,j]) == 1
Pwr[i,j] = 0.0
else
Pwr[i,j] = Pwr[i,j]
end
end
end
# Compute the dominant cycle using the CG of the spectrum
Spx = zeros(size(x,1))
Sp = zeros(size(x,1))
for j = 10:48
Spx .= ifelse.(Pwr[:,j] .>= 0.5, Spx .+ j .* Pwr[:,j],Spx)
Sp .= ifelse.(Pwr[:,j] .>= 0.5,Sp .+ Pwr[:,j],Sp)
end
DominantCycle = zeros(size(x,1))
for i = 1:size(x,1)
if Sp[i] != 0
DominantCycle[i] = Spx[i] / Sp[i]
end
end
return DominantCycle
end
@doc """
AutoCorrelationReversals(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48, LPPeriod::Int64=10, HPPeriod::Int64=48, AvgLength::Int64=3)::Array{Float64}
Autocorrelation Reversals - Equation 8-4
The indicated reversals are very sensitive to the smoothing of the price data.
LPLength is made available as an indicator input to decrease or increase the number of indicated reversals as desired.
The AvgLength parameter is also made available as an indicator because this averaging also impacts the number of indicated reversals.
Care should be taken when increasing the value of this input because the lag of the indicator increases in direct proportion to the increase of the value of the AvgLength.
Typical delay of the indicator will be about three bars when the AvgLength parameter is set to a value of 3.
"""
function AutoCorrelationReversals(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48, LPPeriod::Int64=10, HPPeriod::Int64=48, AvgLength::Int64=3)::Array{Float64}
@assert max_lag<size(x,1) && max_lag>0 "Argument n out of bounds."
# Highpass filter cyclic components whose periods are shorter than 48 bars
alpha1 = (cosd(.707*360 / HPPeriod) + sind(.707*360 / HPPeriod) - 1) / cosd(.707*360 / HPPeriod)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPPeriod)
b1 = 2*a1*cosd(1.414*180 / LPPeriod)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Pearson correlation for each value of lag
lags = min_lag:max_lag
Avg_Corr_Rev_Out = zeros(size(x,1), max_lag)
@inbounds for j = lags
# Lag series
lagged = [fill(0,j); Filt[1:length(Filt)-j]]
# Roll correlation width of lag and lagged version of itself
@inbounds for i = 96:size(x,1)
Avg_Corr_Rev_Out[i,j] = cor(lagged[i-AvgLength+1:i], Filt[i-AvgLength+1:i])
# Scale each correlation to range between 0 and 1
Avg_Corr_Rev_Out[i,j] = .5*(Avg_Corr_Rev_Out[i,j] + 1)
end
end
# mark all > .5 and <.5 crossings
SumDeltas = zeros(size(x,1), max_lag)
@inbounds for j = lags
@inbounds for i = 96:size(x,1)
if (Avg_Corr_Rev_Out[i,j] > 0.5) && (Avg_Corr_Rev_Out[i-1,j] < 0.5) || (Avg_Corr_Rev_Out[i,j] < 0.5) && (Avg_Corr_Rev_Out[i-1,j] > 0.5)
SumDeltas[i,j] = 1.0
else
SumDeltas[i,j] = 0.0
end
end
end
# Sum across the matrix of all correlation 0.5 crossings
Reversal = zeros(size(x,1))
test_sum = zeros(size(x,1))
@inbounds for i = 1:size(x,1)
test_sum[i] = sum(SumDeltas[i,:])
if sum(SumDeltas[i,:]) > 24
Reversal[i] = 1
else Reversal[i] = 0
end
end
return Reversal
end
@doc """
DFTS(x::Array{Float64}; LPLength::Int64=10, HPLength::Int64=48)::Array{Float64}
Discrete Fourier Transform Sprectral Estimate - Equation 9-1
"""
function DFTS(x::Array{Float64}; LPLength::Int64=10, HPLength::Int64=48)::Array{Float64}
@assert HPLength<size(x,1) && HPLength>0 "Argument n out of bounds."
# Highpass filter cyclic components whose periods are shorter than 48 bars
alpha1 = (cosd(.707*360 / HPLength) + sind(.707*360 / HPLength) - 1) / cosd(.707*360 / HPLength)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPLength)
b1 = 2*a1*cosd(1.414*180 / LPLength)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Initialize matrix
CosinePart = zeros(size(x,1), HPLength)
SinePart = zeros(size(x,1), HPLength)
Pwr = zeros(size(x,1), HPLength)
# This is the DFT
@inbounds for j = 10:48
@inbounds for k = 0:47
lagged_filt = [fill(0,k); Filt[1:length(Filt)-k]]
CosinePart[:,j] .= CosinePart[:,j] .+ lagged_filt .* cosd(360 * k / j) / j
SinePart[:,j] .= SinePart[:,j] .+ lagged_filt .* sind(360 * k / j) / j
Pwr[:,j] .= CosinePart[:,j] .* CosinePart[:,j] .+ SinePart[:,j] .* SinePart[:,j]
end
end
# Find Maximum Power Level for Normalization
# Note difers from TS output
MaxPwr = zeros(size(x,1), max_lag)
@inbounds for j = 8:48
@inbounds for i = 2:size(x,1)
MaxPwr[i,j] = .995*MaxPwr[i-1,j]
if Pwr[i,j] > MaxPwr[i,j]
MaxPwr[i,j] = Pwr[i,j]
end
end
end
#+_+_+_+_+_+_+_+_+_+_+_+_ unable to validate the below against TS
#Normalize Power Levels and Convert to Decibels
@inbounds for j = 10:48
@inbounds for i = 1:size(x,1)
if MaxPwr[i,j] != 0
Pwr[i,j] = Pwr[i,j] / MaxPwr[i,j]
end
end
end
# Compute the dominant cycle using the CG of the spectrum
Spx = zeros(size(x,1))
Sp = zeros(size(x,1))
for j = 10:48
Spx .= ifelse.(Pwr[:,j] .>= 0.5, Spx .+ j .* Pwr[:,j],Spx)
Sp .= ifelse.(Pwr[:,j] .>= 0.5,Sp .+ Pwr[:,j],Sp)
end
DominantCycle = zeros(size(x,1))
for i = 2:size(x,1)
if Sp[i] != 0
DominantCycle[i] = Spx[i] / Sp[i]
else
DominantCycle[i] = DominantCycle[i-1] # if its zero carry forwrd previous value
end
end
return DominantCycle
end
#="""
TO DO
Comb Filter Spectral Estimate - Equation 10-1
This spectral estimate may be used to adust other indicators such as RSI, Stochastic and CCI
For example of how the indicator adjustments are made see Adaptive Indicators in equation 11-*
"""
=#
@doc """
AdaptiveRSI(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48,LPLength::Int64=10, HPLength::Int64=48, AvgLength::Int64=3)::Array{Float64}
Adaptive RSI - Equation 11-1
Adjust the RSI by a lookback period half the length of the dominant cycle
"""
function AdaptiveRSI(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48,LPLength::Int64=10, HPLength::Int64=48, AvgLength::Int64=3)::Array{Float64}
@assert max_lag<size(x,1) && max_lag>0 "Argument max_lag is out of bounds."
#@assert max_lag<size(x,1) && max_lag>0 "Argument n is out of bounds."
alpha1 = (cosd(.707*360 / HPLength) + sind(.707*360 / HPLength) - 1) / cosd(.707*360 / HPLength)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPLength)
b1 = 2*a1*cosd(1.414*180 / LPLength)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Pearson correlation for each value of lag
# Initialize correlation sums
lags = min_lag:max_lag
temp = zeros(size(x,1))
Avg_Corr_Out = zeros(size(x,1), max_lag)
@inbounds for j = lags
# Lag series
lagged = [fill(0,j); Filt[1:length(Filt)-j]]
# Roll correlation width of lag and lagged version of itself
@inbounds for i = 96:size(x,1)
Avg_Corr_Out[i,j] = cor(lagged[i-AvgLength+1:i], Filt[i-AvgLength+1:i])
end
end
# Calcualte sine and cosine part
cosinePart = zeros(size(x,1), max_lag)
sinePart = zeros(size(x,1), max_lag)
sqSum = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for k = 3:max_lag
cosinePart[:,j] .= cosinePart[:,j] .+ Avg_Corr_Out[:,k] .* cosd(370 * k / j)
sinePart[:,j] .= sinePart[:,j] .+ Avg_Corr_Out[:,k] .* sind(370 * k / j)
sqSum[:,j] .= cosinePart[:,j].^2 .+ sinePart[:,j].^2
end
end
# Iterate over every i in j and smooth R by the .2 and .8 factors
R = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for i = 2:size(x,1)
R[i,j] = (.2*sqSum[i,j]) * (sqSum[i,j]) + (.8 *R[i-1,j])
end
end
#### validated ^^^^^ ###############
# Find Maximum Power Level for Normalization
# need to validate this and below!
MaxPwr = zeros(size(x,1), max_lag)
#MaxPwr = 0
@inbounds for j = min_lag:max_lag
@inbounds for i = 2:size(x,1)
MaxPwr[i,j] = .995*MaxPwr[i-1,j]
if R[i,j] > MaxPwr[i,j]
MaxPwr[i,j]= R[i,j]
end
end
end
Pwr = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for i = 1:size(x,1)
Pwr[i,j] = R[i,j] / MaxPwr[i,j]
end
end
# Replace Nan to 0
@inbounds for j = 1:max_lag
@inbounds for i = 1:size(x,1)
if isnan(Pwr[i,j]) == 1
Pwr[i,j] = 0.0
else
Pwr[i,j] = Pwr[i,j]
end
end
end
# Compute the dominant cycle using the CG of the spectrum
Spx = zeros(size(x,1))
Sp = zeros(size(x,1))
for j = 5:max_lag
Spx .= ifelse.(Pwr[:,j] .>= 0.5, Spx .+ j .* Pwr[:,j],Spx)
Sp .= ifelse.(Pwr[:,j] .>= 0.5,Sp .+ Pwr[:,j],Sp)
end
DominantCycle = zeros(size(x,1))
for i = 1:size(x,1)
if Sp[i] != 0
DominantCycle[i] = Spx[i] / Sp[i]
end
if DominantCycle[i] < 5
DominantCycle[i] = 5
end
if DominantCycle[i] > max_lag
DominantCycle[i] = max_lag
end
end
# Adaptive RSI starts here, using half the measured dominant
ClosesUp = zeros(size(x,1))
ClosesDn = zeros(size(x,1))
filtdiff = zeros(size(x,1))
posDiff= zeros(size(x,1))
negDiff= zeros(size(x,1))
# pos and neg diffs
@inbounds for i = 2:size(x,1)
# difference
filtdiff[i] = Filt[i] - Filt[i-1]
if filtdiff[i] > 0
posDiff[i] = filtdiff[i]
elseif filtdiff[i] < 0
negDiff[i] = abs(filtdiff[i])
end
end
# Running Sums of Filt
posSum = zeros(size(x,1))
negSum = zeros(size(x,1))
denom = zeros(size(x,1))
rsi= zeros(size(x,1))
# Set width of look back 50% of the dominant cycle
n = round.(DominantCycle ./ 2;digits = 0)
for i = 1:size(n,1)
if isnan(n[i]) == 1
n[i] = 2.0
else
n[i] == n[i]
end
end
n = Int64.(n)
i=1
@inbounds for i = n[1]:size(x,1)
k = n[i]
posSum[i] = sum(posDiff[i-k+1:i])
negSum[i] = sum(negDiff[i-k+1:i])
denom[i] = posSum[i]+negSum[i]
end
# RSI
MyRSI = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
if denom != 0 && denom[i-1] != 0
MyRSI[i] = c1*(posSum[i] /denom[i] + posSum[i-1] / denom[i-1]) / 2 + c2*MyRSI[i-1] +c3*MyRSI[i-2]
end
end
return MyRSI
end
@doc """
AdaptiveStochastic(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48,LPLength::Int64=10, HPLength::Int64=48, AvgLength::Int64=3)::Array{Float64}
Adaptive Stochastic - Equation 11-2
Adjust the stochastic lookback period by the same value as the dominant cycle
"""
function AdaptiveStochastic(x::Array{Float64}; min_lag::Int64=1, max_lag::Int64=48,LPLength::Int64=10, HPLength::Int64=48, AvgLength::Int64=3)::Array{Float64}
@assert max_lag<size(x,1) && max_lag>0 "Argument n out of bounds."
alpha1 = (cosd(.707*360 / HPLength) + sind(.707*360 / HPLength) - 1) / cosd(.707*360 / HPLength)
HP = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
HP[i] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*(x[i] - 2*x[i-1] +x[i-2]) + 2*(1 - alpha1)*HP[i-1] - (1 - alpha1)*(1 - alpha1)*HP[i-2]
end
# Smooth with a Super Smoother Filter from equation 3-3
a1 = exp(-1.414*3.14159 / LPLength)
b1 = 2*a1*cosd(1.414*180 / LPLength)
c2 = b1
c3 = -a1*a1
c1 = 1 - c2 - c3
Filt = zeros(size(x,1))
@inbounds for i = 3:size(x,1)
Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2]
end
# Pearson correlation for each value of lag
# Initialize correlation sums
lags = min_lag:max_lag
temp = zeros(size(x,1))
Avg_Corr_Out = zeros(size(x,1), max_lag)
@inbounds for j = lags
# Lag series
lagged = [fill(0,j); Filt[1:length(Filt)-j]]
# Roll correlation width of lag and lagged version of itself
@inbounds for i = 96:size(x,1)
Avg_Corr_Out[i,j] = cor(lagged[i-AvgLength+1:i], Filt[i-AvgLength+1:i])
end
end
# Calcualte sine and cosine part
cosinePart = zeros(size(x,1), max_lag)
sinePart = zeros(size(x,1), max_lag)
sqSum = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for k = 3:max_lag
cosinePart[:,j] .= cosinePart[:,j] .+ Avg_Corr_Out[:,k] .* cosd(370 * k / j)
sinePart[:,j] .= sinePart[:,j] .+ Avg_Corr_Out[:,k] .* sind(370 * k / j)
sqSum[:,j] .= cosinePart[:,j].^2 .+ sinePart[:,j].^2
end
end
# Iterate over every i in j and smooth R by the .2 and .8 factors
R = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for i = 2:size(x,1)
R[i,j] = (.2*sqSum[i,j]) * (sqSum[i,j]) + (.8 *R[i-1,j])
end
end
#### validated ^^^^^ ###############
# Find Maximum Power Level for Normalization
# need to validate this and below!
MaxPwr = zeros(size(x,1), max_lag)
#MaxPwr = 0
@inbounds for j = min_lag:max_lag
@inbounds for i = 2:size(x,1)
MaxPwr[i,j] = .995*MaxPwr[i-1,j]
if R[i,j] > MaxPwr[i,j]
MaxPwr[i,j]= R[i,j]
end
end
end
Pwr = zeros(size(x,1), max_lag)
@inbounds for j = min_lag:max_lag
@inbounds for i = 1:size(x,1)
Pwr[i,j] = R[i,j] / MaxPwr[i,j]
end
end
# Replace Nan to 0
@inbounds for j = 1:max_lag
@inbounds for i = 1:size(x,1)
if isnan(Pwr[i,j]) == 1
Pwr[i,j] = 0.0
else
Pwr[i,j] = Pwr[i,j]
end
end
end
# Compute the dominant cycle using the CG of the spectrum
Spx = zeros(size(x,1))
Sp = zeros(size(x,1))
for j = 10:48
Spx .= ifelse.(Pwr[:,j] .>= 0.5, Spx .+ j .* Pwr[:,j],Spx)
Sp .= ifelse.(Pwr[:,j] .>= 0.5,Sp .+ Pwr[:,j],Sp)
end
DominantCycle = zeros(size(x,1))
for i = 1:size(x,1)
if Sp[i] != 0
DominantCycle[i] = Spx[i] / Sp[i]
end
if DominantCycle[i] < 10
DominantCycle[i] = 10
end
if DominantCycle[i] > max_lag
DominantCycle[i] = max_lag
end
end
# Stochastic Computation starts here
# Highest and lowest filt over same period as dominant cycle
HighestC = zeros(size(x,1))
LowestC = zeros(size(x,1))
Stoc = zeros(size(x,1))
AdaptiveStochastic = zeros(size(x,1))
n = Int64.(round.(DominantCycle);digits=0)
@inbounds for i = n[1]:size(x,1)
k = n[i]
HighestC[i] = maximum(Filt[i-k+1:i])
LowestC[i] = minimum(Filt[i-k+1:i])
Stoc[i] = (Filt[i] - LowestC[i]) / (HighestC[i] - LowestC[i])
AdaptiveStochastic[i] = c1*(Stoc[i] + Stoc[i-1]) / 2 + c2*AdaptiveStochastic[i-1] + c3*AdaptiveStochastic[i-2]
end
return AdaptiveStochastic
end
@doc """
PFish(h::Array{Float64}, l::Array{Float64}; n::Int64=10)::Array{Float64}
- Fisher Transform - Equation 15-2 (Variation of)
- Price Normalization
- n = length of normalization period
"""
function PFish(h::Array{Float64}, l::Array{Float64}; n::Int64=10)::Array{Float64}
@assert n<size(x,1) && n>0 "Argument n out of bounds."
# Fisher Transform Calculation
price_input = zeros(size(h,1))
price_input .= (h .+ l) ./ 2
MaxH = zeros(size(price_input,1))
MinL = zeros(size(price_input,1))
@inbounds for i =n:size(price_input,1)
MaxH[i] = maximum(price_input[i-n+1:i])
MinL[i] = minimum(price_input[i-n+1:i])
end
Value1 = zeros(size(price_input,1))
Fish_out = zeros(size(price_input,1))
@inbounds for i = n:size(price_input,1)
Value1[i] = .33*2*((price_input[i] - MinL[i])/(MaxH[i] - MinL[i]) - .5) + .67*Value1[i-1]
if Value1[i] > .99
Value1[i] = .999
else
Value1[i] = Value1[i]
end
if Value1[i] < -.99
Value1[i] = -.999
else
Value1[i] = Value1[i]
end
Fish_out[i] = .5*log((1 + Value1[i])/(1 - Value1[i])) + .5*Fish_out[i-1]
end
return Fish_out
end
#=
@doc """
Fish(x::Array{Float64})::Array{Float64}
- Fisher Transform - Equation 15-2
"""
function Fish(x::Array{Float64})::Array{Float64}
# Fisher Transform Calculation
Fish_out = zeros(size(x,1))
Translated = zeros(size(x,1))
Amplified = zeros(size(x,1))
Translated .= 2 .*(x .- .5);
Amplified .= 1.5.*Translated
@inbounds for i = 1:size(x,1)
if x[i] != NaN
Fish_out[i] = .5*log(abs(((1 + Amplified[i])/(1 - Amplified[i])))) # + .5*Fish[i-1]
elseif x[i] == NaN
Fish_out[i] = 0.0
end
if Fish_out[i] > .999
Fish_out[i] = .999
end
if Fish_out[i] < -.999
Fish_out[i] = -.999
end
end
return Fish_out
end
#=
# Help Wanted
##### DC portion needs to be completed correctly ###
## Data validation vs TS passes with exception of DC
# 5-2. Dominant Cycle Measured by Zero Crossings of the Band-Pass Filter
#function DominantCycle(x::Array{Float64}; n::Int64=20, bandwidth::Float64=.7)::Array{Float64}
#alpha2 = (cosd(.25*bandwidth*360 / n) + sind(.25*bandwidth*360 / n) - 1) / cosd(.25*bandwidth*360 /n)
#HP = zeros(size(x,1))
#@inbounds for i = 2:length(x)
#HP[i] = (1 + alpha2 / 2)*(x[i] - x[i-1]) + (1- alpha2)*HP[i-1]
#end
#beta1 = cosd(360 / n)
#gamma1 = 1 / cosd(360*bandwidth / n)
#alpha1 = gamma1 - sqrt(gamma1*gamma1 - 1)
#BP = zeros(size(x,1))
#@inbounds for i = 3:length(x)
# if i == 3
# BP[i-1] = 0
# BP[i-2] = 0
# else
#BP[i] = .5*(1 - alpha1)*(HP[i] - HP[i-2]) + beta1*(1 + alpha1)*BP[i-1] -alpha1*BP[i-2]
#end
#end
#peak = 0.0
#peak_save = zero(x)
#DC = zeros(size(x,1))
#Real = zeros(size(x,1))
#@inbounds for i = 1:length(BP)
# peak = .991*peak
# peak_save[i] = .991*peak
# if abs(BP[i]) > peak
# peak = abs(BP[i])
# peak_save[i] = peak
# elseif peak != 0.0
# Real[i] = BP[i] / peak
# peak_save[i] = peak
# end
#end
#DC = fill(6.0,length(x))
# mark all 0 crossings
# co_cu = zeros(BP)
#@inbounds for i = 2:length(BP)
# if (Real[i] > 0.0) && (Real[i-1] < 0.0) || (Real[i] < 0.0) && (Real[i-1] > 0.0)# cross over
# co_cu[i] = 1.0
# else
# co_cu[i] = 0.0
# end
# end
# Count until each cross over or cross under
#function co_cu_count(x::Array{Float64})::Array{Float64}
# count_save = zero(x)
# count = 0
# for i = 2:length(x)
# if x[i] == 1.0 && x[i-1] == 0.0
# count = 1.0 + count
# count_save[i] = count
# end
# if x[i] == 0.0 && x[i-1] == 1.0
# count = 1.0
# #count_save[i] = count
# end
# if x[i] == 0.0 && x[i-1] == 1.0
# count = 1.0
# elseif x[i] == 0.0
# count = count + 1.0
# #count_save[i] = count
# end
#end
# return count_save
#end
#count = co_cu_count(x)
#function locf(x::Array{Float64})
# dx = zeros(size(x,1))
# for i in 2:length(x)
# if i == 2
# # fill index 1
# dx[i-1] = x[i-1]
# end
# if (x[i] == 0.0 && x[i-1] != 0.0)
# dx[i] = x[i-1]
# else
# dx[i] = x[i]
# end
# if (x[i] == 0.0 && x[i-1] == 0.0)
# dx[i] = dx[i-1]
# end
#end
# return dx
#end
# run na locf function
#count = locf(count)
#i=67400 - 13
#count = co_cu_count(co_cu)
#DC .= 2 .* count
#DC = fill(6.0,length(x))
#@inbounds for i = 2:length(count)
# DC[i] = 2*count[i]
# if (2*count[i]) > (1.25*DC[i-1])
# DC[i] = 1.25*DC[i-1]
# elseif (2*count[i]) < (.8*DC[i-1])
# DC[i] = .8*DC[i-1]
# end
#end
# return DC
# end
#=
@doc """
Reverse EMA
"""
Inputs:
AA( numericsimple ) ;
Vars:
CC( 0 ),EMA( 0 ),RE1( 0 ),RE2( 0 ),
RE3( 0 ),RE4( 0 ),RE5( 0 ),RE6( 0 ),
RE7( 0 ),RE8( 0 ),Wave( 0 ) ;
//Classic EMA
CC = 1 - AA ;
EMA = AA * Close + CC * EMA[1] ;
//Compute Reverse EMA
# obtain the power TS code
RE1 = CC * EMA + EMA[1] ;
RE2 = Power( CC, 2 ) * RE1 + RE1[1] ;
RE3 = Power( CC, 4 ) * RE2 + RE2[1] ;
RE4 = Power( CC, 8 ) * RE3 + RE3[1] ;
RE5 = Power( CC, 16 ) * RE4 + RE4[1] ;
RE6 = Power( CC, 32 ) * RE5 + RE5[1] ;
RE7 = Power( CC, 64 ) * RE6 + RE6[1] ;
RE8 = Power( CC, 128 ) * RE7 + RE7[1] ;
//Indicator as difference
Wave = EMA - AA * RE8 ;
_ReverseEMA = Wave ;
Indicator: ReverseEMA
{
Reverse EMA Indicator
(C) 2017 John F. Ehlers
TASC Sep 2017
}
inputs:
Trend( .05 ),
Cycle( .3 ) ;
variables:
CycleRevEMA( 0 ),
TrendRevEMA( 0 ),
AvgTrend( 0 ) ;
TrendRevEMA = _ReverseEMA( Trend ) ;
CycleRevEMA = _ReverseEMA( Cycle ) ;
AvgTrend = Average( TrendRevEMA, 10 ) ;
Plot1( TrendRevEMA, "Trend", Green ) ;
Plot2( CycleRevEMA, "Cycle", Red ) ;
Plot3( 0, "ZL", Blue ) ;
alpha:= 0.1;
ca:= 1-alpha;
ma:= (alpha * C) + (ca*PREV);
re1:= ca*ma + Ref(ma, -1);
re2:= Power(ca,2)*re1 + Ref(re1,-1);
re3:= Power(ca,4)*re2 + Ref(re2,-1);
re4:= Power(ca,8)*re3 + Ref(re3,-1);
re5:= Power(ca,16)*re4 + Ref(re4,-1);
re6:= Power(ca,32)*re5 + Ref(re5,-1);
re7:= Power(ca,64)*re6 + Ref(re6,-1);
re8:= Power(ca,128)*re7 + Ref(re7,-1);
ma - (alpha*re8);
0
—Wil
=#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment