Adaptive, Zero lag Schaff Trend Cycle [Loxx]
//@version=5
indicator('Adaptive, Zero lag Schaff Trend Cycle [Loxx]', shorttitle='AZLSTC [Loxx]', timeframe="", timeframe_gaps=true, max_bars_back = 5000)
RMA(x, t) =>
EMA1 = x
EMA1 := na(EMA1[1]) ? x : (x - nz(EMA1[1])) * (1/t) + nz(EMA1[1])
EMA1
EMA(x, t) =>
EMA1 = x
EMA1 := na(EMA1[1]) ? x : (x - nz(EMA1[1])) * (2 / (t + 1)) + nz(EMA1[1])
EMA1
_bpDom(len, bpw, mult) =>
HP = 0.0
BP = 0.0
Peak = 0.0
Real = 0.0
counter = 0.0
DC = 0.0
alpha2 = (math.cos(0.25 * bpw * 2 * math.pi / len) + math.sin(0.25 * bpw * 2 * math.pi / len) - 1) / math.cos(0.25 * bpw * 2 * math.pi / len)
HP := (1 + alpha2 / 2) * (close - nz(close[1])) + (1 - alpha2) * nz(HP[1])
beta1 = math.cos(2 * math.pi / len)
gamma1 = 1 / math.cos(2 * math.pi * bpw / len)
alpha1 = gamma1 - math.sqrt(gamma1 * gamma1 - 1)
BP := 0.5 * (1 - alpha1) * (HP - nz(HP[2])) + beta1 * (1 + alpha1) * nz(BP[1]) - alpha1 * nz(BP[2])
BP := bar_index == 1 or bar_index == 2 ? 0 : BP
Peak := 0.991 * Peak
Peak := math.abs(BP) > Peak ? math.abs(BP) : Peak
Real := Peak != 0 ? BP / Peak : Real
DC := nz(DC[1])
DC := DC < 6 ? 6 : DC
counter := counter[1] + 1
if ta.crossover(Real, 0) or ta.crossunder(Real, 0)
DC := 2 * counter
if 2 * counter > 1.25 * nz(DC[1])
DC := 1.25 * DC[1]
if 2 * counter < 0.8 * nz(DC[1])
DC := 0.8 * nz(DC[1])
counter := 0
temp_out = mult * DC
temp_out
zlagin = "Zero lag"
reg = "Regular"
iszLag = input.string(reg, title = "MACD Calculation Type", options =[zlagin, reg], group = "Basic Settings")
calc_type = input.string("Fixed", title='Calculation Type', options=["Band-pass Dominant Cycle", "Fixed"], group='Basic Settings')
src_in = input.source(title='Source', defval=close, group = "Basic Settings")
sm_type = input.string('EMA', title='MACD Smoothing Type', options=["ALMA", "DEMA", "EMA", "LSMA", "RMA", "SMA", "TEMA", "TRIMA", "VWMA", "WMA"], group = "Basic Settings")
cycleLength = input.int(title='Schaff Trend Cycle Length', defval=10, group = "Basic Settings")
fastLength = input.int(title='MACD Fast Length', defval=23, group = "Basic Settings")
slowLength = input.int(title='MACD Slow Length', defval=50, group = "Basic Settings")
sigPer = input.int(defval=3, title='Signal Period', minval = 1, group = "Basic Settings")
bp_period = input.int(13, "Band-pass Period", minval = 1, group = "Band-pass")
bp_width = input.float(0.20, "Band-pass Width", step = 0.1, group = "Band-pass")
cycle_len = input.float(200, "MACD Percent of Dominant Cycle (%)", step = 1.0, group = "Band-pass")/100
slMult = input.float(2.0, "MACD Slow-to-Fast Multiple", step = 0.1, group = "Band-pass")
efi_reduction = input.float(100, "Cycle Percent of Dominant Cycle (%) ", step = 1.0, group = "Band-pass")/100
upper_b = input.int(title='Upper Band', defval=85, group = "Thresholds")
lower_b = input.int(title='Lower Band', defval=15, group = "Thresholds")
alma_offset = input.float(defval=0.85, title="* Arnaud Legoux Moving Average (ALMA) Only - Offset", group = "Moving Average Inputs")
alma_sigma = input.int(defval=6, title="* Arnaud Legoux Moving Average (ALMA) Only - Sigma", group = "Moving Average Inputs")
lsma_offset = input.int(defval=0, title="* Least Squares Moving Average (LSMA) Only - Offset", group = "Moving Average Inputs")
greencolor = color.lime
redcolor = color.red
variant(type, src, len) =>
sig = 0.0
if type == "ALMA"
sig := ta.alma(src, len, alma_offset, alma_sigma)
else if type == "SMA"
sig := ta.sma(src, len)
else if type == "EMA"
sig := EMA(src, len)
else if type == "DEMA"
sig := 2 * EMA(src, len) - EMA(EMA(src, len), len)
else if type == "TEMA"
sig := 3 * (EMA(src, len) - EMA(EMA(src, len), len)) + EMA(EMA(EMA(src, len), len), len)
else if type == "WMA"
sig := ta.wma(src, len)
else if type == "TRIMA"
sig := ta.sma(ta.sma(src, math.ceil(len / 2)), math.floor(len / 2) + 1)
else if type == "RMA"
sig := RMA(src, len)
else if type == "VWMA"
sig := ta.vwma(src, len)
else if type == "LSMA"
sig := ta.linreg(src, len, lsma_offset)
sig
_macd(src, m_type, ma_type, f_len, s_len) =>
fast_MA1 = variant(ma_type, src, f_len)
fast_MA2 = variant(ma_type, fast_MA1, f_len)
diff_fast = fast_MA1 - fast_MA2
zlag_fast= fast_MA1 + diff_fast
slow_MA1 = variant(ma_type, src, s_len)
slow_MA2 = variant(ma_type, slow_MA1, s_len)
diff_slow = slow_MA1 - slow_MA2
zlag_slow= slow_MA1 + diff_slow
macd = 0.0
if (m_type == zlagin)
macd := zlag_fast - zlag_slow
else
macd := fast_MA1 - slow_MA1
macd
_stc(src, ma_type, cl, fl, sl, alpha, zlag) =>
fastK = 0.0, fastD = 0.0, fastKK = 0.0, stcReturn = 0.0
macd = _macd(src, zlag, ma_type, fl, sl)
lowMACD = ta.lowest(macd, cl)
highMACD = ta.highest(macd, cl) - lowMACD
fastK := highMACD > 0 ? (macd - lowMACD) / highMACD * 100 : nz(fastK[1])
fastD := na(fastD[1]) ? fastK : fastD[1] + alpha * (fastK - fastD[1])
lowStoch = ta.lowest(fastD, cl)
highStoch = ta.highest(fastD, cl) - lowStoch
fastKK := highStoch > 0 ? ((fastD - lowStoch) / highStoch) * 100 : nz(fastKK[1])
stcReturn := na(stcReturn[1]) ? fastKK : stcReturn[1] + alpha * (fastKK - stcReturn[1])
stcReturn
alpha_in = 2.0/(1.0+sigPer)
len_out_macd = int(nz(_bpDom(bp_period, bp_width, cycle_len), 1)) < 1 ? 1 : int(nz(_bpDom(bp_period, bp_width, cycle_len), 1))
len_out_cycle = int(nz(_bpDom(bp_period, bp_width, efi_reduction), 1)) < 1 ? 1 : int(nz(_bpDom(bp_period, bp_width, efi_reduction), 1))
specFL = calc_type == "Band-pass Dominant Cycle" ? len_out_macd: fastLength
specSL = calc_type == "Band-pass Dominant Cycle" ? int(len_out_macd * slMult) : slowLength
specCycle = calc_type == "Band-pass Dominant Cycle" ? len_out_cycle : cycleLength
stc = _stc(src_in, sm_type, specCycle, specFL, specSL, alpha_in, iszLag)
signal = stc[1]
middle = 50
goLong = ta.crossover(stc, middle)
goShort = ta.crossunder(stc, middle)
l_cont = stc > middle and ta.crossover(stc, signal) and not goLong
s_cont = stc < middle and ta.crossunder(stc, signal) and not goShort
color_out =
(stc >= 0 and stc > signal ? greencolor :
stc < 0 and stc < signal ? redcolor : color.gray)
stcColor1 = stc > stc[1] ? greencolor : redcolor
plot(stc, title='STC', color=stcColor1, linewidth = 3)
plot(upper_b, title='Upper', color=color.new(color.gray, 50))
plot(lower_b, title='Lower', color=color.new(color.gray, 50))
plot(50, color=color.new(color.gray, 30), linewidth=1, style=plot.style_circles, title = "Zero")
plotchar(len_out_macd, title = "MACD Fast BP Cycle Length", char = "", location = location.top)
plotchar(int(len_out_macd * slMult) , title = "MACD Slow BP Cycle Length", char = "", location = location.top)
plotchar(len_out_cycle, title = "Cycle BP Cycle Length", char = "", location = location.top)