Supertrend ANY INDICATOR (RSI, MFI, CCI, etc.) + Range Filter for ThinkOrSwim

samer800

Conversion Expert
VIP
Lifetime
kcAuFQQ.png

Author Message:
This indicator will generate a supertrend of your chosen configuration on any of the following indicators:
  • RSI
  • MFI
  • Accum/Dist
  • Momentum
  • On Balance Volume
  • CCI

There is also a RANGE FILTER built into the scripts so that you can smooth the indicators for the supertrend. This is an optional configuration in the settings. Also, you can change the oversold/overbought bounds in the settings (they are removed entirely for indicators without bounds).

CODE:
CSS:
#https://www.tradingview.com/v/GRMqFdJQ/
#// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © wbburgin
#indicator("Supertrend ANY INDICATOR (RSI, MFI, CCI, etc.) + Range Filter",shorttitle="ST ANY INDICATOR [wbburgin]"
# Converted by Sam4Cok@Samer800    - 04/2023
declare lower;
#// INPUTS _____
input Label     = yes;          # "Show Labels"
input selectIndicator = {default "RSI", "MFI", "Accum/Dist", "Momentum", "OB Volume", "CCI", "Stochastic", "High/Low"};
input indicator_length = 14;    # "Indicator Length (if applicable)
input atr_length = 10;          # "Supertrend ATR Length"
input atr_mult = 3.0;           # "Supertrend ATR Mult"
input use_range = no;           # "Use Range Filter of Indicator"
input sampling_period = 50;     # "Range Filter Sampling Period (if applicable)"
input range_mult = 3;           # "Range Filter Multiple (if applicable)"
input ShowSignal = yes;         # "Show Signals"
input highlighting = yes;       # "Display Highlighting"
input oversold = 30;            # "Oversold Level (if applicable)"
input overbought = 70;          # "Overbought Level (if applicable)"
input ShowZigZag = no;

AddLabel(Label, selectIndicator, Color.YELLOW);
def na = Double.NaN;
def last = IsNaN(close);
# stoch(source, high, low, length) =>
script stoch {
    input src = close;
    input h = high;
    input l = low;
    input len = 0;
    def stoch = 100 * (src - Lowest(l, len)) / (Highest(h, len) - Lowest(l, len));
    plot return = stoch;
}
#supertrend_anysource(float source, float factor, simple int atr_length) =>
script supertrend_anysource {
    input source = close;
    input factor = 2;
    input atr_length = 10;
    def lowerBand;
    def upperBand;
    def highest = Highest(source, atr_length);
    def lowest = Lowest(source, atr_length);
#    def trueRange = TrueRange(highest, source, lowest);
    def trueRange = if IsNaN(highest[1]) then highest - lowest  else
                    Max(Max(highest - lowest, AbsValue(highest - source[1])), AbsValue(lowest - source[1]));
    def rmaATR = WildersAverage(trueRange, atr_length);
    def atr = rmaATR;
    def up = source + factor * atr;
    def lo = source - factor * atr;
    def prevLowerBand = lowerBand[1];
    def prevUpperBand = upperBand[1];
    lowerBand = if lo > prevLowerBand or source[1] < prevLowerBand then lo else prevLowerBand;
    upperBand = if up < prevUpperBand or source[1] > prevUpperBand then up else prevUpperBand;
    def direction;# = na
    def superTrend;# = na
    def prevSuperTrend = superTrend[1];
    if IsNaN(atr[1]) {
        direction = 1;
    } else {
        if prevSuperTrend == prevUpperBand {
            direction = if source > upperBand then -1 else 1;
        } else {
            direction = if source < lowerBand then 1 else -1;
        }
    }
    superTrend = if direction == -1 then lowerBand else upperBand;
    plot ST = superTrend;
    plot dir = direction;
}
#filt(source,sampling_period,range_mult) =>
script filt {
    input source = close;
    input sampling_period = 50;
    input range_mult = 3;
    def wper      = (sampling_period * 2) - 1;
    def avrng     = ExpAverage(AbsValue(source - source[1]), sampling_period);
    def smoothrng = ExpAverage(avrng, wper) * range_mult;
    def rngfilt = CompoundValue(1, if source > rngfilt[1] then
                  if (source - smoothrng) < rngfilt[1] then rngfilt[1] else (source - smoothrng) else
                  if (source + smoothrng) > rngfilt[1] then rngfilt[1] else (source + smoothrng), source);
    plot out = rngfilt;
}
def nRSI = RSI(Price = close, Length = indicator_length);
def stoch = stoch(close, high, low, indicator_length);
def upper = Sum(volume * If((close - close[1]) <= 0, 0, close), indicator_length);
def lower = Sum(volume * If((close - close[1]) >= 0, 0, close), indicator_length);
def mfi = 100.0 - (100.0 / (1.0 + upper / lower));

def indicator;
switch (selectIndicator) {
case "RSI" :
    indicator = if !use_range then nRSI else
                filt(nRSI, sampling_period, range_mult);
case "MFI" :
    indicator = if !use_range then mfi else
                filt(mfi, sampling_period, range_mult);
case "Accum/Dist" :
    indicator = if !use_range then AccDist() else
                filt(AccDist(), sampling_period, range_mult);
case "Momentum" :
    indicator = if !use_range then (close - close[indicator_length]) else
                filt((close - close[indicator_length]), sampling_period, range_mult);
case "OB Volume" :
    indicator = if !use_range then OnBalanceVolume() else
                filt(OnBalanceVolume(), sampling_period, range_mult);
case "CCI" :
    indicator = if !use_range then CCI(Length = indicator_length) else
                filt(CCI(Length = indicator_length), sampling_period, range_mult);
case "Stochastic" :
    indicator = if !use_range then stoch else
                filt(stoch, sampling_period, range_mult);
case "High/Low" :
    indicator = if !use_range then hl2 else
                filt(hl2, sampling_period, range_mult);
}
def bound = selectIndicator == selectIndicator."RSI" or selectIndicator == selectIndicator."MFI";

def supertrend = supertrend_anysource(indicator, atr_mult, atr_length).ST;
def dir        = supertrend_anysource(indicator, atr_mult, atr_length).dir;
def supertrend_up = if dir == -1 then supertrend else na;
def supertrend_dn = if dir ==  1 then supertrend else na;
def supertrend_up_start = if dir == -1 and dir[1] ==  1 then supertrend else na;
def supertrend_dn_start = if dir ==  1 and dir[1] == -1 then supertrend else na;

#-- Plot
plot sup = supertrend_up;    # "Up Supertrend"
plot sdn = supertrend_dn;    # "Down Supertrend"
plot mid = indicator;
mid.SetLineWeight(2);
mid.SetDefaultColor(Color.WHITE);
sup.SetDefaultColor(Color.GREEN);
sdn.SetDefaultColor(Color.RED);

plot UpStart = supertrend_up_start;    # "Supertrend Up Start"
plot DnStart = supertrend_dn_start;    # "Supertrend Down Start"
UpStart.SetLineWeight(3);
DnStart.SetLineWeight(3);
UpStart.SetPaintingStrategy(PaintingStrategy.POINTS);
UpStart.SetDefaultColor(Color.GREEN);
DnStart.SetPaintingStrategy(PaintingStrategy.POINTS);
DnStart.SetDefaultColor(Color.RED);

AddCloud(if !highlighting then na else if dir < 0 then mid else na, sup , Color.DARK_GREEN);
AddCloud(if !highlighting then na else if dir > 0 then sdn else na, mid, Color.DARK_RED);

AddChartBubble(ShowSignal and supertrend_up_start,supertrend_up_start, "Buy", Color.GREEN, no);
AddChartBubble(ShowSignal and supertrend_dn_start,supertrend_dn_start, "Sell", Color.RED, yes);

plot hiPlot  = if !bound or last then na else oversold;    # "Oversold Level"
plot loPlot  = if !bound or last then na else overbought;  # "Overbought Level"
plot midPlot = (hiPlot+loPlot)/2;                          # "mid Level"

hiPlot.SetPaintingStrategy(PaintingStrategy.DASHES);
loPlot.SetPaintingStrategy(PaintingStrategy.DASHES);
midPlot.SetStyle(Curve.SHORT_DASH);
hiPlot.SetDefaultColor(Color.DARK_GRAY);
loPlot.SetDefaultColor(Color.DARK_GRAY);
midPlot.SetDefaultColor(Color.DARK_GRAY);

def LongTrigger  = dir!=dir[1] and dir<0;
def ShortTrigger = dir!=dir[1] and dir>0;

plot zigzag = if !ShowZigZag then na else
              if LongTrigger then supertrend else if ShortTrigger then supertrend else
              if IsNaN(close[-1]) then
              if  dir > 0 then Highest(indicator, atr_length) else Lowest(indicator, atr_length) else na;
zigzag.AssignValueColor(if dir[1] < 0 then Color.DARK_GREEN else Color.DARK_RED);
zigzag.EnableApproximation();


#--- END of CODE

Update -- Added more indicators, Bollinger and Sushi Trend options, smoothing, dynamic levels..etc.


CODE:

CSS:
#https://www.tradingview.com/v/GRMqFdJQ/
#// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © wbburgin
#indicator("Supertrend ANY INDICATOR (RSI, MFI, CCI, etc.) + Range Filter",shorttitle="ST ANY INDICATOR [wbburgin]"
# Converted and mod by Sam4Cok@Samer800    - 04/2023
# Sushi Trend code from @HoanGhetti -  https://www.tradingview.com/v/dfVzbU6r/
# SuperBollingerTrend code from @Zeiierman - https://www.tradingview.com/v/AjWfiZpw/
# Update.. added more indicators, dynamic levels and Super Trend to select from - 08 /2023
declare lower;
#// INPUTS _____
input ShowLabel     = yes;       # "Show Labels"
input smoothIndicator = yes;
input smoothingLength = 5;
input selectIndicator = {default "RSI", "MFI", "Accum/Dist", "Momentum", "OB Volume", "CCI", "Stochastic", "High/Low", "CMO", "Klinge", "DPO"};
input CalcMethod = {"ATR Trend", default "Bollinger Trend", "Sushi Trend"};
input BollingerMovAvg = AverageType.SIMPLE;
input indicator_length = 14;    # "Indicator Length (if applicable)
input atr_length = 10;          # "Supertrend ATR Length"
input SupertrendMulti = 3.0;    # "Supertrend ATR Mult"
input useRangeFilter = no;      # "Use Range Filter of Indicator"
input rangeFilterLookback = 50; # "Range Filter Sampling Period (if applicable)"
input rangeFilterMulti = 3;     # "Range Filter Multiple (if applicable)"
input ShowSignals = yes;        # "Show Signals"
input highlighting = yes;       # "Display Highlighting"
input ShowZigZag = no;

AddLabel(ShowLabel, "TrendType: " + CalcMethod, Color.WHITE);
AddLabel(ShowLabel, "Indicator: " + selectIndicator, Color.WHITE);
def na = Double.NaN;
def last = IsNaN(close);
def bar = BarNumber();
#-- Colors
DefineGlobalColor("up", CreateColor(76, 175, 80));
DefineGlobalColor("dn", CreateColor(255, 82, 82));
# stoch(source, high, low, length) =>
script stoch {
    input src = close;
    input h = high;
    input l = low;
    input len = 0;
    def hh = Highest(h, len);
    def ll = Lowest(l, len);
    def stoch = 100 * (src - ll) / (hh - ll);
    plot return = stoch;
}
#supertrend_anysource(float source, float factor, simple int atr_length) =>
script supertrend_anysource {
    input source = close;
#    input factor = 2;
    input atr_length = 10;
    input up = high;
    input lo = low;
    def lowerBand;
    def upperBand;
    def prevLowerBand = if IsNaN(lowerBand[1]) then lo else lowerBand[1];
    def prevUpperBand = if IsNaN(upperBand[1]) then up else upperBand[1];
    lowerBand = if lo > prevLowerBand or source[1] < prevLowerBand then lo else prevLowerBand;
    upperBand = if up < prevUpperBand or source[1] > prevUpperBand then up else prevUpperBand;
    def direction;# = na
    def superTrend;# = na
    def prevSuperTrend = superTrend[1];
    if (IsNaN(up[1]) or IsNaN(lo[1])) {
        direction = 1;
    } else {
        if prevSuperTrend == prevUpperBand {
            direction = if source > upperBand then -1 else 1;
        } else {
            direction = if source < lowerBand then 1 else -1;
        }
    }
    superTrend = if direction < 0 then lowerBand else upperBand;
    plot ST = superTrend;
    plot dir = direction;
}
#filt(source,sampling_period,range_mult) =>
script filt {
    input source = close;
    input sampling_period = 50;
    input range_mult = 3;
    def wper = (sampling_period * 2) - 1;
    def diff = AbsValue(source - source[1]);
    def avrng     = ExpAverage(wper, sampling_period);
    def smoothrng = ExpAverage(avrng, wper) * range_mult;
    def rngfilt = CompoundValue(1, if source > rngfilt[1] then
                  if (source - smoothrng) < rngfilt[1] then rngfilt[1] else (source - smoothrng) else
                  if (source + smoothrng) > rngfilt[1] then rngfilt[1] else (source + smoothrng), source);
    plot out = rngfilt;
}
def nRSI = RSI(Price = close, Length = indicator_length);
def stoch = stoch(close, high, low, indicator_length);
def upper = Sum(volume * If((close - close[1]) <= 0, 0, close), indicator_length);
def lower = Sum(volume * If((close - close[1]) >= 0, 0, close), indicator_length);
def mfi = 100.0 - (100.0 / (1.0 + upper / lower));
def accDist = AccDist();
def mom = close - close[indicator_length];
def obv = OnBalanceVolume();
def linDev = lindev(close, indicator_length);
def avgClo = Average(close, indicator_length);
def nCCI = if linDev == 0 then 0 else (close - avgClo) / linDev / 0.015;
def hl = (high + low) / 2;
def cmo = ChandeMomentumOscillator(Length = indicator_length);
def kling = KlingerOscillator(MALength = indicator_length);
def dpo = DetrendedPriceOsc(Length = indicator_length);
def rsiFilt   = filt(nRSI, rangeFilterLookback, rangeFilterMulti);
def stochFilt = filt(stoch, rangeFilterLookback, rangeFilterMulti);
def mfiFilt = filt(mfi, rangeFilterLookback, rangeFilterMulti);
def accFilt = filt(accDist, rangeFilterLookback, rangeFilterMulti);
def momFilt = filt(mom, rangeFilterLookback, rangeFilterMulti);
def obvFilt = filt(obv, rangeFilterLookback, rangeFilterMulti);
def cciFilt = filt(nCCI, rangeFilterLookback, rangeFilterMulti);
def hlFilt  = filt(hl, rangeFilterLookback, rangeFilterMulti);
def cmoFilt = filt(cmo, rangeFilterLookback, rangeFilterMulti);
def kcFilt = filt(kling, rangeFilterLookback, rangeFilterMulti);
def dpoFilt = filt(dpo, rangeFilterLookback, rangeFilterMulti);
def osc;
switch (selectIndicator) {
case "RSI" :
    osc = if !useRangeFilter then nRSI else rsiFilt;
case "MFI" :
    osc = if !useRangeFilter then mfi else mfiFilt;
case "Accum/Dist" :
    osc = if !useRangeFilter then accDist else accFilt;
case "Momentum" :
    osc = if !useRangeFilter then mom else momFilt;
case "OB Volume" :
    osc = if !useRangeFilter then obv else obvFilt;
case "CCI" :
    osc = if !useRangeFilter then nCCI else cciFilt;
case "Stochastic" :
    osc = if !useRangeFilter then stoch else stochFilt;
case "High/Low" :
    osc = if !useRangeFilter then hl else hlFilt;
case "CMO" :
    osc = if !useRangeFilter then cmo else cmoFilt;
case "Klinge" :
    osc = if !useRangeFilter then kling else kcFilt;
case "DPO" :
    osc = if !useRangeFilter then DPO else dpoFilt;
}
def smIndi = ExpAverage(osc, smoothingLength);
def indicator = if smoothIndicator then smIndi else osc;
def LoTwo = min(indicator, indicator[1]);
def hiTwo = max(indicator, indicator[1]);
def highest = Highest(LoTwo , atr_length);
def lowest  = Lowest(hiTwo, atr_length);

#--- Bollinger Trend
def stDevHi = StDev(highest, atr_length) * SupertrendMulti;
def stDevLo = StDev(lowest, atr_length) * SupertrendMulti;
def bbup = MovingAverage(BollingerMovAvg, highest, atr_length) + stDevHi;
def bbdn = MovingAverage(BollingerMovAvg, lowest, atr_length)  - stDevLo;
def bbST = supertrend_anysource(indicator, atr_length, bbup, bbdn).ST;
def bbDir = supertrend_anysource(indicator, atr_length, bbup, bbdn).dir;

#--- Atr Trend
def tr = TrueRange(highest, indicator, lowest);
def trueRange = if IsNaN(highest[1]) then highest - lowest  else tr;
def rmaATR = WildersAverage(trueRange, atr_length);
def atrup = indicator + SupertrendMulti * rmaATR;
def atrdn = indicator - SupertrendMulti * rmaATR;
def atrST = supertrend_anysource(indicator, atr_length, atrup, atrdn).ST;
def atrdir = supertrend_anysource(indicator, atr_length, atrup, atrdn).dir;

#-- Sushi Trend
def factor = Round(indicator_length / 2, 0) + 1;
def hh = Highest(indicator, factor);
def ll = Lowest(indicator, factor);
def stMatrixMax = Highest(indicator, factor * 2);
def stMatrixMin = Lowest(indicator, factor * 2);
def max = hh == stMatrixMax;
def min = ll == stMatrixMin;

def valid = max and min and ((stMatrixMin == indicator[factor - 1]) or (stMatrixMax == indicator[factor - 1]));
def barssince = if valid[1] then 0 else barssince[1] + 1;
def sushi = valid and barssince >= factor and !last[1];
def diff = (sushi - sushi[1]) != 0;
def condMax = bar and diff and sushi and max;
def condMin = bar and diff and sushi and min;
def lastMax = if condMax then stMatrixMax else lastMax[1];
def lastMin = if condMin then stMatrixMin else lastMin[1];
def crossUp = Crosses(indicator, lastMax, CrossingDirection.ABOVE);
def crossDn = Crosses(indicator, lastMin, CrossingDirection.BELOW);
def Sushidir;
if crossUp {
    SushiDir = 1;
} else
if crossDn {
    SushiDir = -1;
} else {
    SushiDir = SushiDir[1];
}
def sushiST = if last then na else if Sushidir>0 then lastMin else lastMax;

#-- swith calc Method
def dir; def supertrend;
Switch (CalcMethod) {
Case "ATR Trend" :
    supertrend = atrST;
    dir        = atrDir;
Case "Bollinger Trend" :
    supertrend = bbST;
    dir        = bbDir;
Case "Sushi Trend" :
    supertrend = sushiST;
    dir        = -SushiDir;
}

def supertrend_up = if dir < 0 then supertrend else na;
def supertrend_dn = if dir > 0 then supertrend else na;
def supertrend_up_start = if dir < 0 and dir[1] > 0 then supertrend else na;
def supertrend_dn_start = if dir > 0 and dir[1] < 0 then supertrend else na;

#-- Plot
plot oscLine = indicator;
plot sup = supertrend_up;    # "Up Supertrend"
plot sdn = supertrend_dn;    # "Down Supertrend"

oscLine.SetLineWeight(2);
oscLine.SetDefaultColor(Color.WHITE);
sup.SetDefaultColor(Color.GREEN);
sdn.SetDefaultColor(Color.RED);

plot UpStart = supertrend_up_start;    # "Supertrend Up Start"
plot DnStart = supertrend_dn_start;    # "Supertrend Down Start"
UpStart.SetLineWeight(3);
DnStart.SetLineWeight(3);
UpStart.SetPaintingStrategy(PaintingStrategy.POINTS);
UpStart.SetDefaultColor(Color.GREEN);
DnStart.SetPaintingStrategy(PaintingStrategy.POINTS);
DnStart.SetDefaultColor(Color.RED);

AddCloud(if !highlighting then na else if dir < 0 then oscLine else na, sup , Color.DARK_GREEN);
AddCloud(if !highlighting then na else if dir > 0 then sdn else na, oscLine, Color.DARK_RED);

AddChartBubble(ShowSignals and supertrend_up_start, supertrend_up_start, "Buy", Color.GREEN, no);
AddChartBubble(ShowSignals and supertrend_dn_start, supertrend_dn_start, "Sell", Color.RED, yes);

#--- band
def fmin = Lowest(indicator, rangeFilterLookback);
def fmax = Highest(indicator, rangeFilterLookback);
def rng = fmax - fmin;
def lvlup  = fmin + 0.90 * rng;
def lvldn  = fmin + 0.10 * rng;
def lvlmid = fmin + 0.50 * rng;

plot hiPlot  = lvlup;     # "Oversold Level"
plot loPlot  = lvldn;     # "Overbought Level"
plot midPlot = lvlmid;    # "mid Level"

midPlot.SetStyle(Curve.SHORT_DASH);
hiPlot.SetDefaultColor(Color.DARK_GRAY);
loPlot.SetDefaultColor(Color.DARK_GRAY);
midPlot.SetDefaultColor(Color.DARK_GRAY);

#-- ZigZag
def LongTrigger  = dir != dir[1] and dir < 0;
def ShortTrigger = dir != dir[1] and dir > 0;

plot zigzag = if !ShowZigZag then na else
              if LongTrigger then supertrend else if ShortTrigger then supertrend else
              if IsNaN(close) then
              if  dir > 0 then Highest(indicator, atr_length) else Lowest(indicator, atr_length) else na;
zigzag.AssignValueColor(if dir[1] < 0 then Color.CYAN else Color.MAGENTA);
zigzag.EnableApproximation();


#--- END of CODE
 
Last edited:
Thanks a bunch for the updated code. At first glance, it is quite an impressive indicator. I am looking forward to testing it out! Have you found any indicators that work best when 'SuperTrended"?
 

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
439 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