Candlestick Channels [LUX] with SuperTrend for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
q3Awnxt.png


Candlestick Channels return channels whose extremities converge towards the price when a corresponding candlestick pattern is detected. This allows for us to obtain more reactive extremities in the presence of a cluster of candlestick patterns.

The detected candlestick patterns are also highlighted with labels on your chart automatically.

Settings
  • Trend Length: Period of the stochastic oscillator used to determine trend sentiment; this sentiment is used to detect certain candlestick patterns.(RSI, OBV and CCI Options added as well).
  • Convergence: Convergence percentage of the channel extremities used during the occurrence of a candlestick pattern. A lower value will return extremities converging more slowly toward the price.
  • Smooth: Determines the degree of smoothness of the channel extremities.
  • Option to switch between channel mode to SuperTrend mode.
pls test it :)

Code:
CSS:
#indicator("Candlestick Channels [LUX]", overlay = true, max_labels_count = 500)
#indicator("SuperTrend+", overlay = true, format=format.price, precision=2)
# combined candlestick channel and supertrend+
# Created by Sam4Cok@Samer800 - 09/2022
#//------------------------------------------------------------------------------
#//Settings
#//-----------------------------------------------------------------------------{
input Mode = {SuperTrend,Default Channel};
#//Patterns
input enable_hammer = yes;     #'Hammer'
input enable_ihammer = yes;    #'Inverted Hammer'
input enable_shooting = yes;   #'Shooting Star'
input enable_hanging = yes;    #'Hanging Man'
input enable_bulleng = no;     #'Bullish Engulfing'
input enable_beareng = no;     #'Bearish Engulfing'
input enable_wm = yes;         #'White Marubozu'
input enable_bm = yes;         #'Black Marubozu'
input maType = {"VAWMA", "eVWMA",default "SMMA", "EMA", "TEMA", "WMA", "VWMA", "SMA", "HMA", "McGinley"};
input atrPeriod = 20;    # Period use in calculating the ATR value.
input maxDeviation = 0; # The max deviation of true range before being considered and outlier
input closeBars = 2;      # Closed bars that have to exceed the ST value before the trend reversal is confirmed
input Wicks    = yes;
input showsignals = no;   # Show Buy/Sell Bubble
input showBand = yes;
input showCloud = yes;
input CandlestickBubble = yes;
input TrendFilter = {Default Stochastic, RSI, OBV, CCI};
input TrendLength = 14;    # 'Trend Length'
input alpha = 50;     # 'Convergence'
input smooth = 7;     # 'Smooth'

def na = Double.NaN;
DefineGlobalColor("green", CreateColor(76, 175, 80));
DefineGlobalColor("red", CreateColor(255, 82, 82));
#//-----------------------------------------------------------------------------}
#//Variables/Functions
#//-----------------------------------------------------------------------------{
def n = BarNumber();
def o = open;
def h = if Wicks then high else max(close, open);
def l = if Wicks then low else  min(close, open);
def c = close;
def v = volume;
# 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;
}
#----- Scripts----
script nz {
    input data  = close;
    input repl  = 0;
    def ret_val = if IsNaN(data) then repl else data;
    plot return = ret_val;
}
#naOutliers( src, len,  maxDeviation = 4)=>
script naOutliers {
    input src = close;
    input len = 120;
    input maxDeviation = 0;
    def prev = src[1];# // ignore current in measurment as it could throw off result.
    def avg = SimpleMovingAvg(prev, len);
    def dev = StDev(prev, len) * maxDeviation;
    def upper = avg + dev;
    def lower = avg - dev;
    def newUpper;
    def newLower;
    newUpper = if IsNaN(newUpper[1]) then upper else
        if prev >= newUpper[1]
           then upper else if(isNaN(newUpper[1]), upper,newUpper[1]);
    newLower = if isNaN(newLower[1]) then lower else
        if prev <= newLower[1]
           then lower else if(isNaN(newLower[1]),lower,newLower[1]);
    def newSrcUp = newUpper;
    def newStcDn = newLower;
    def naOutliers = if src > upper then newSrcUp else
                     if src < lower then newStcDn else src;
    plot return = naOutliers;
}
#------------scripts-----------
# vawma(src, len) =>
script vawma {
input src = hlc3;
input len = 50;
def sum; def vol; def v;
def  s   = fold i = 0 to len with p do
           src[i];
def volm = if IsNaN(volm[1]) then 0 else
           fold j = 0 to len with u do
           volume[j];
def ma   = if !IsNaN(s) and !IsNaN(volm) then
           fold k = 0 to len with w do
           len - k  else 0;
       v = fold l=1 to len with q do
           if IsNaN(v[1]) then volm else
           volume * ma;
     vol = fold m = 0 to len with r do
           r + v[m];
     sum = fold n = 0 to len with t do
           t + src[n] * v[n];
plot vawma = sum/vol;
}
#vwma(source, length)
script VWMA {
    input x = close;
    input y = 15;
    def VWMA = SimpleMovingAvg(x * volume, y) / SimpleMovingAvg(volume, y);
    plot result = VWMA;
}
#ma(mode, len,  src) =>
script ma {
    input type = "EMA";
    input src = close;
    input len = 100;
    def volumeSum = Sum(volume, len);
    def evwma = ((volumeSum - volume) * nz(evwma[1]) + volume * src) / volumeSum;
    def e = ExpAverage(src, len);
    def Mcg = if IsNaN(Mcg[1]) then Average(src, len) else
              CompoundValue(1, Mcg[1] + ((src - Mcg[1]) / (0.6 * len * Power(src / Mcg[1], 4))), src);
    def ma;
    ma = if type == "SMA"   then SimpleMovingAvg(src, len) else
     if type == "VAWMA" then vawma(src, len) else
     if type == "EMA"   then ExpAverage(src, len) else
     if type == "TEMA"  then 3 * (e - ExpAverage(e, len)) + ExpAverage(ExpAverage(e, len), len) else
     if type == "WMA"   then WMA(src, len) else
     if type == "VWMA"  then vwma(src, len) else
     if type == "SMMA"  then WildersSmoothing(src, len) else
     if type == "HMA"   then WMA(2 * WMA(src, len / 2) - WMA(src, len), Round(Sqrt(len), 0)) else
     if type == "eVWMA" then evwma else
     if type == "McGinley" then Mcg else Double.NaN;
    plot result = ma;
}
#----- Trend
def tr = if IsNaN(close[1]) then high - low else TrueRange(high, close, low);
def trCleaned = if maxDeviation == 0 then tr else naOutliers(tr, atrPeriod, maxDeviation);
def atATR = ma(maType , trCleaned, atrPeriod);
def getATR = atATR;
def change = c-c[1];
def obv = if TotalSum(change) > 0 then v else if change < 0 then -v else 0*v;
def obvFast = ExpAverage(obv, 2);
def obvSlow = ExpAverage(obv, 14);
def obvlong  = obvFast > obvSlow;
def obvshort = obvFast < obvSlow;

def nATR = getATR / 2;
def nRSI = RSI(length=Trendlength);
def nCCI = CCI(length=Trendlength);
def Stoc = stoch(c, c, c, Trendlength);

def downtrend = if TrendFilter == TrendFilter.Stochastic then Stoc < 50 else
                if TrendFilter == TrendFilter.RSI then nRSI < 50 else
                if TrendFilter == TrendFilter.CCI then nCCI < 0 else obvshort;
def uptrendd   = if TrendFilter == TrendFilter.Stochastic then Stoc > 50 else
                if TrendFilter == TrendFilter.RSI then nRSI > 50 else
                if TrendFilter == TrendFilter.CCI then nCCI > 0 else obvlong;
def d = AbsValue(c - o);
#-----------------------------------------------------------------------------}
#Pattern Rules
#-----------------------------------------------------------------------------{
def hammer  = downtrend and Min(o, c) - l > 2 * d and h - Max(c, o) < d / 4;
def ihammer = downtrend and h - Max(o, c) > 2 * d and Min(c, o) - l < d / 4;
def bulleng = downtrend and c > o and c[1] < o[1] and c > o[1] and d > nATR;
def wm = downtrend[1] and c > o and h - Max(o, c) + Min(o, c) - l < d / 10 and d > nATR;
#---------------------------------------------------------------------------
def shooting = uptrendd and h - Max(o, c) > 2 * d and Min(c, o) - l  < d / 4;
def hanging  = uptrendd and Min(o, c) - l > 2 * d and h - Max(c, o) < d / 4;
def beareng = uptrendd   and c < o and c[1] > o[1] and c < o[1] and d > nATR;
def bm = uptrendd[1] and c < o and h - Max(o, c) + Min(o, c) - l < d / 10 and d > nATR;
#-----------------------------------------------------------------------------}
# Channel
# ----------------------------------------------------------------------------{
def max;
def min;
def lbl;
#//Bullish Patterns-----------------------
if hammer and enable_hammer {
    max = max[1] + alpha / 100 * (c - max[1]);
    min = min[1];
    lbl = 1;
} else {
    if ihammer and enable_ihammer {
        max = max[1] + alpha / 100 * (c - max[1]);
        min = min[1];
        lbl = 2;
    } else {
        if bulleng and enable_bulleng {
            max = max[1] + alpha / 100 * (c - max[1]);
            min = min[1];
            lbl = 3;
        } else {
            if wm and enable_wm {
                max = max[1] + alpha / 100 * (c - max[1]);
                min = min[1];
                lbl = 4;
            } else {  
#//Bearish Patterns-------------------------------------------------------------------
                if shooting and enable_shooting  {
                    min = min[1] + alpha / 100 * (c - min[1]);
                    max = max[1];
                    lbl = 5;
                } else {
                    if hanging and enable_hanging {
                        min = min[1] + alpha / 100 * (c - min[1]);
                        max = max[1];
                        lbl = 6;
                    } else {
                        if beareng and enable_beareng {
                            min = min[1] + alpha / 100 * (c - min[1]);
                            max = max[1];
                            lbl = 7;
                        } else {
                            if bm and enable_bm {
                                min = min[1] + alpha / 100 * (c - min[1]);
                                max = max[1];
                                lbl = 8;
                            } else {
#//-----------------------------------------------------------------------------------
                                max = if n < 1 then h else Max(c, max[1]);
                                min = if n < 1 then l else Min(c, min[1]);
                                lbl = 0;
                            }
                        }
                    }
                }
            }
        }
    }
}
def smooth_max = ExpAverage(max, smooth);
def smooth_min = ExpAverage(min, smooth);
def avg = (smooth_max + smooth_min) / 2;
#//---------------------------------------------------------------------------}
#//Plots
#//--------------------------------------------------------------------------{
def os;
os = if c > smooth_max then 1 else if c < smooth_min then 0 else os[1];
def fade_max;
fade_max = if os == 0 then fade_max[1] + 1 else 0;
def fade_min;
fade_min = if os == 1 then fade_min[1] + 1 else 0;

plot Upper = if mode == mode.Channel then smooth_max else na;  
Upper.SetHiding(!showBand);

plot Middle = if mode == mode.Channel then avg else na;

plot Lower = if mode == mode.Channel then smooth_min else na;
Lower.SetHiding(!showBand);

Upper.AssignValueColor(if fade_max < fade_min then Color.GREEN else
                       if fade_max > fade_min then Color.RED else Color.GRAY);
Middle.AssignValueColor(if fade_max < fade_min then GlobalColor("green") else
                        if fade_max > fade_min then GlobalColor("red") else Color.GRAY);
Lower.AssignValueColor(if fade_max < fade_min then Color.GREEN else
                       if fade_max > fade_min then Color.RED else Color.GRAY);
#----cloud---

AddCloud(if showCloud then Upper else na, Middle, Color.DARK_GREEN);
AddCloud(if showCloud then Middle else na, Lower, Color.DARK_RED);


#---Bubbles
AddChartBubble(CandlestickBubble and lbl == 1, low, "H", Color.DARK_GREEN, no);
AddChartBubble(CandlestickBubble and lbl == 2, low, "iH", Color.DARK_GREEN, no);
AddChartBubble(CandlestickBubble and lbl == 3, low, "BE", Color.DARK_GREEN, no);
AddChartBubble(CandlestickBubble and lbl == 4, low, "WM", Color.DARK_GREEN, no);
AddChartBubble(CandlestickBubble and lbl == 5, high, "SS", Color.DARK_RED, yes);
AddChartBubble(CandlestickBubble and lbl == 6, high, "HM", Color.DARK_RED, yes);
AddChartBubble(CandlestickBubble and lbl == 7, high, "BE", Color.DARK_RED, yes);
AddChartBubble(CandlestickBubble and lbl == 8, high, "BM", Color.DARK_RED, yes);


#------------SuperTrend-----------

def dn = max;
def up = min;

def up1 = if (up > up1[1]) or (h[1] < up1[1]) then if l[1] > up1[1] then Max(up1[1], up) else up else up1[1];
def dn1 = if (dn < dn1[1]) or (l[1] > dn1[1]) then if h[1] < dn1[1] then Min(dn1[1], dn) else dn else dn1[1];

def lastU = up1[1];
def lastD = dn1[1];
def lastUp;
def lastDn;
def state = {default init, long, short};

def trend;
def confirm;
def unconfirm;

switch (state[1]) {
case init:
    state = state.short;
    trend = 0;
    confirm = if isNaN(confirm[1]) then 0 else confirm[1];
    unconfirm = if isNaN(unconfirm[1]) then 0 else  unconfirm[1];
case long:
    if (trend[1] != 1 and l > lastDn[1])
    then {
        state = state.short;
        trend = 1;
        confirm   = confirm[1];
        unconfirm = unconfirm[1];
    } else {
        state = state.long;
        trend = trend[1];
        confirm   = If((trend != +1 and h > lastDn) and (confirm[1] < closeBars and close[1] > lastDn)
                or (trend != -1 and l < lastUp) and (confirm[1] < closeBars and close[1] < lastUp), confirm[1] + 1,
                If(trend[1] != trend or lastUp[1] != lastUp or lastDn[1] != lastDn, 0, confirm[1]));
        unconfirm = If((trend != +1 and h > lastD) or (trend != -1 and l < lastU), unconfirm[1] + 1,
                If(trend[1] != trend or lastUp[1] != lastUp or lastDn[1] != lastDn, 0, unconfirm[1]));
    }
case short:
    if (trend[1] != -1 and h < lastUp[1])
    then {
        state = state.long;
        trend     = -1;
        confirm   = confirm[1];
        unconfirm = unconfirm[1];
    } else {
        state = state.short;
        if (trend[1] != +1 and h > lastDn[1])
        then {
            unconfirm = If((trend[1] != trend), 0, unconfirm[1] + 1);
            confirm   = If(confirm[1] < closeBars and close[1] > lastUp[1], confirm[1] + 1, confirm[1]);
            trend     = If(confirm[1] >= closeBars, +1, trend[1]);
        } else {
            if (trend[1] != -1 and l < lastUp[1])
            then {
                unconfirm = If(trend[1] != trend , 0, unconfirm[1] + 1);
                confirm   = If(confirm[1] < closeBars and close[1] < lastUp[1], confirm[1] + 1, confirm[1]);
                trend     = If(confirm[1] >= closeBars, -1, trend[1]);

            } else {
                trend     = trend[1];
                confirm   = If(trend[1] != trend or lastUp[1] != lastUp or lastDn[1] != lastDn, 0, confirm[1]);
                unconfirm = If(trend[1] != trend or lastUp[1] != lastUp or lastDn[1] != lastDn, 0, unconfirm[1]);
            }
        }
    }
}
if (trend[1] != trend)
then {
    lastUp = lastU;
    lastDn = lastD;
} else {
    lastUp = if trend == +1 then Max(lastUp[1], up1) else up1;
    lastDn = if trend == -1 then Min(lastDn[1], dn1) else dn1;
}
#----- Calculations -------
def upTrend = if trend == 1 then lastUp else na;
def buySignal = trend == 1 and trend[1] == -1;
def upPoint = if buySignal then lastUp else na;

def dnTrend = if trend == 1 then na else lastDn;
def sellSignal = trend == -1 and trend[1] == 1;
def dnPoint = if sellSignal then lastDn else na;
#------ plot ----------------
plot upPlot = if mode == mode.SuperTrend then upTrend else na;    # "Up Trend"
upPlot.AssignValueColor(if unconfirm == 0 then GlobalColor("green") else Color.YELLOW);

plot pointUp = if mode == mode.SuperTrend then upPoint else na;   # "UpTrend Begins"
pointUp.SetDefaultColor(GlobalColor("green"));
pointUp.SetStyle(Curve.POINTS);
pointUp.SetLineWeight(3);

plot dnPlot = if mode == mode.SuperTrend then dnTrend else na;    # "Down Trend"
dnPlot.AssignValueColor(if unconfirm == 0 then GlobalColor("red") else Color.YELLOW);

plot pointDn = if mode == mode.SuperTrend then dnPoint else na;   # "DownTrend Begins"
pointDn.SetDefaultColor(GlobalColor("red"));
pointDn.SetStyle(Curve.POINTS);
pointDn.SetLineWeight(3);

#------- Cloud -------
AddCloud(ohlc4, if ShowCloud then upPlot else na, Color.DARK_GREEN, Color.WHITE);
AddCloud(if ShowCloud then dnPlot else na, ohlc4, Color.DARK_RED, Color.WHITE);
#------- Bubble ------
AddChartBubble(buySignal and showsignals, lastUp, "Buy", Color.GREEN, no);
AddChartBubble(sellSignal and showsignals, lastDn, "Sell", Color.RED, yes);
   
### END
 
Last edited by a moderator:

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