Adaptive Schaff Trend Cycle (STC) [AlgoAlpha] For ThinkOrSwim

QUIKTDR1

Active member
VIP
The author states:
The Adaptive Schaff Trend Cycle by AlgoAlpha introduces a dynamic approach to market analysis, refining traditional indicators through adaptive logic to align with fluctuating market conditions. Here's a concise overview of its operation:

🔄Adaptive MACD Adjustment: The foundation of the indicator is an enhanced MACD calculation, which dynamically adjusts its parameters based on real-time market trends and momentum. This algorithmic adjustment aims to ensure the MACD's responsiveness to market changes, adapting its sensitivity to offer timely insights .
🌟Integration of Schaff Trend Cycle (STC): After adjusting the MACD, the indicator calculates STC values to provide a smoothed representation of market trends. By normalizing and smoothing the MACD values on a scale from 0 to 100, the STC method helps in identifying market phases with a clear visualization. The smoothing process is designed to mitigate noise and focus on significant market movements .
📊Visualization and Alerts: To aid in the interpretation of these insights, the Adaptive Schaff Trend Cycle employs color gradients and customizable visual settings to indicate momentum shifts. These visual cues, combined with alert functionalities, are structured to assist traders in monitoring market developments, enabling them to make informed decisions based on the presented data .
JMsscCV.png


Here is the original Tradingview code:
https://www.tradingview.com/script/yOxili7R-Adaptive-Schaff-Trend-Cycle-STC-AlgoAlpha/

Must scroll down to the next post for the new ThinkOrSwim code.
 
Last edited by a moderator:
Please convert to TOS
https://www.tradingview.com/script/yOxili7R-Adaptive-Schaff-Trend-Cycle-STC-AlgoAlpha/

Code:
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)

post subject different from the posted code. Anyway, below the code for the subject post:

CSS:
# Indicator for TOS
#https://www.tradingview.com/v/yOxili7R/
#//@AlgoAlpha
#indicator(title='Adaptive Schaff Trend Cycle (STC) [AlgoAlpha]', shorttitle='AlgoAlpha - Adaptive ???',
# Converted by Sam4Cok@Samer800 - 12 / 2024
Declare Lower;

input timeframe = AggregationPeriod.MIN;
input AdaptiveLogicLength = 55;       # 'Adaptive Logic Length', minval = 1
input StcLength = 12;                 # 'STC Length', minval = 1
input StcSensitivity = 0.45;          # 'STC Sensitivity', minval = 0.0001, maxval = 1)
input macdFastLength = 26;            # 'MACD Fast Length', minval = 1)
input macdSlowLength = 50;            # 'MACD Slow Length', minval = 1)

def na = Double.NaN;
def last = isNaN(close);
def cap = GetAggregationPeriod();
def tf = Max(cap, timeframe);
def cond = cap >= timeframe;
#-- functions
Script calculateMACD {
input fastLength = 26;
input slowLength = 50;
input length = 55;
input tf = 300000;
    def bar = if close(Period = tf) then bar[1] + 1 else bar[1];
    def a1   = 2 / (fastLength + 1);
    def a2   = 2 / (slowLength + 1);
    def r2 = 0.5 * Sqr(Correlation(close(Period = tf), bar, length)) + 0.5;
    def K = r2 * ((1 - a1) * (1 - a2)) + (1 - r2) * ((1 - a1) / (1 - a2));
    def macd = if isNaN(macd[1]) then 0 else
               (close(Period = tf) - close(Period = tf)[1]) * (a1 - a2) + (-a2 - a1 + 2) * macd[1] - K *
                if(isNaN(macd[2]), macd[1], macd[2]);
    plot out = macd;
}
Script calculateSTC {
input lengthInput = 12;
input MACDValue = close;
input length = 55;
input smoothingFactor = 0.45;
    def lowestMACD = lowest(MACDValue, lengthInput);
    def highestMACD = highest(MACDValue, lengthInput) - lowestMACD;
    def normalizedMACD = if isNaN(normalizedMACD[1]) then 0 else
                         if highestMACD > 0 then (MACDValue - lowestMACD) / highestMACD * 100 else normalizedMACD[1];
    def smoothedMACD = if isNaN(smoothedMACD[1]) then normalizedMACD else
                       smoothedMACD[1] + smoothingFactor * (normalizedMACD - smoothedMACD[1]);
    def lowestSmoothedMACD = lowest(smoothedMACD, lengthInput);
    def highestSmoothedMACD = highest(smoothedMACD, lengthInput) - lowestSmoothedMACD;
    def smoothedNormalizedMACD = if highestSmoothedMACD > 0 then (smoothedMACD - lowestSmoothedMACD) / highestSmoothedMACD * 100
                                 else smoothedNormalizedMACD[1];
    def STCValue = if isNaN(STCValue[1]) then smoothedNormalizedMACD else
                   STCValue[1] + smoothingFactor * (smoothedNormalizedMACD - STCValue[1]);
    plot stc = if isNaN(STCValue) then 0 else STCValue - 50;
    plot macd = if isNaN(MACDValue) then 0 else MACDValue;
}
def MACDSrc = calculateMACD(macdFastLength, macdSlowLength, AdaptiveLogicLength, tf);
def STCValue = calculateSTC(StcLength, MACDSrc, AdaptiveLogicLength, StcSensitivity).stc;
def MACDVal0 = calculateSTC(StcLength, MACDSrc, AdaptiveLogicLength, StcSensitivity).macd;
def MACDVal1 = (MACDVal0) / (ExpAverage(high(Period = tf) - low(Period = tf), macdSlowLength)) * 100;
def MACDValue = (MACDVal1 - ExpAverage(MACDVal1, 9))/2;
def STCValue1 = if last then na else STCValue[1];
#-- Color
def col = if (MACDValue > MACDValue[1] and MACDValue > 0) then  2 else
          if (MACDValue < MACDValue[1] and MACDValue < 0) then -2 else
          if MACDValue < 0 then -1 else 1;
def STCCol = if STCValue > STCValue1 then
             if STCValue*2 > 100 then 100 else
             if STCValue < 0 then 0 else STCValue * 2 else
             if STCValue*2 < -100 then 100 else
             if STCValue > 0 then 0 else STCValue *-2;
def nCol = 100 - STCCol;
def eCol = STCCol * 2.54 + nCol;
def col2 = if STCValue > STCValue1 then if STCValue >= 50 then 255 else
                                        if STCValue < 10 then 53 else STCValue * 5 else
                                        if STCValue > -10 then 53 else
                                        if STCValue <= -50 then 255 else - STCValue * 5;
#-- Crosses
def crossUp = (STCValue > STCValue1) and (STCValue[1] <= STCValue1[1]);
def crossDn = (STCValue < STCValue1) and (STCValue[1] >= STCValue1[1]);

plot shiftUp = if cond and crossUp then STCValue1 else na; # "STC Trend Shift"
plot shiftDn = if cond and crossDn then STCValue1 else na; # "STC Trend Shift"
shiftUp.SetLineWeight(2);
shiftUp.SetPaintingStrategy(PaintingStrategy.POINTS);
shiftUp.SetDefaultColor(Color.GREEN);
shiftDn.SetLineWeight(2);
shiftDn.SetPaintingStrategy(PaintingStrategy.POINTS);
shiftDn.SetDefaultColor(Color.RED);
#-- STC Line
plot STC = if last then na else STCValue; # STC
STC.SetLineWeight(2);
STC.AssignValueColor(if STCValue > STCValue1 then CreateColor(57, col2, col2) else CreateColor(col2, 57, col2));

#-- Histogram
plot macdHist = MACDValue; # 'Histogram'
macdHist.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
macdHist.AssignValueColor(if col== 2 then Color.LIGHT_GREEN else
                          if col== 1 then Color.GRAY else
                          if col==-2 then Color.RED else
                          if col==-1 then Color.PINK else Color.GRAY);

AddCloud(STC , STCValue1, Color.CYAN, Color.MAGENTA);

#-- Levels
plot midLine = if last then na else 0;
plot upperLine = if last then na else -25;
plot lowerLine = if last then na else 25;
plot overboughtLine = if last then na else 60;
plot oversoldLine = if last then na else -60;
midLine.SetDefaultColor(Color.DARK_GRAY);
upperLine.SetDefaultColor(Color.DARK_GRAY);
lowerLine.SetDefaultColor(Color.DARK_GRAY);
overboughtLine.SetPaintingStrategy(PaintingStrategy.SQUARES);
oversoldLine.SetPaintingStrategy(PaintingStrategy.SQUARES);
overboughtLine.AssignValueColor(if STCValue > STCValue1 then CreateColor(col2, 0, 0) else CreateColor(57, 0, 0));
oversoldLine.AssignValueColor(if STCValue > STCValue1 then CreateColor(0, 57, 0) else CreateColor(0, col2, 0));

AddCloud(overboughtLine , 40, Color.DARK_RED);
AddCloud(-40 , oversoldLine, Color.DARK_GREEN);

AssignPriceColor(
                 if STCValue > STCValue1 then CreateColor(57, col2, 57) else CreateColor(col2, 57, 57));

#-- END of CODE
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
399 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top