SuperTrend Toolkit
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © QuantiLuxe

//@version=5
indicator("SuperTrend Toolkit", "[Ʌ] -‌ Super Kit", false)

type bar
    float o = na
    float h = na
    float l = na
    float c = na

type supertrend
    float s = na
    int   d = na

method src(bar b, simple string src) =>
    float x = switch src
        'oc2'   => math.avg(b.o, b.c          )
        'hl2'   => math.avg(b.h, b.l          )
        'hlc3'  => math.avg(b.h, b.l, b.c     )
        'ohlc4' => math.avg(b.o, b.h, b.l, b.c)
        'hlcc4' => math.avg(b.h, b.l, b.c, b.c)

    x

method atr(bar b, simple int len) =>
    float tr = 
         na(b.h[1]) ? 
         b.h - b.l  : 
         math.max(
             math.max(
                 b.h - b.l, 
                 math.abs(b.h - b.c[1])), 
             math.abs    (b.l - b.c[1]))

    len == 1 ? tr : ta.rma(tr, len)

method st(bar b, simple float factor, simple int len) =>
	float atr = b.atr( len )
	float up  = b.src('hl2') + factor * atr
    up       := up < nz(up[1]) or b.c[1] > nz(up[1]) ? up : nz(up[1])
    float dn  = b.src('hl2') - factor * atr
    dn       := dn > nz(dn[1]) or b.c[1] < nz(dn[1]) ? dn : nz(dn[1])
	
    float st  = na
    int   dir = na
    dir := switch
        na(atr[1])         => 1
        st[1] == nz(up[1]) => dir := b.c > up ? -1 : +1
        =>                    dir := b.c < dn ? +1 : -1
	st  :=                    dir == -1       ? dn : up
	
    supertrend.new(st, dir)


var string tp = 'Choose an indicator source of which to base the SuperTrend on.'
var string g1 = "SuperTrend Settings", var string gu = "UI Options"
src  = input.source(close    , "Source"            ,             tp          , group = g1)
len  = input.int   (10       , "Length"            ,             inline = '1', group = g1)
mlt  = input.float (5.       , "Factor"            , 1, 20, 0.5, inline = '1', group = g1)
clbl = input.bool  (false    , "Contrarian Signals",                           group = gu)
colu = input.color (#008cff, "Bull Color"        ,                           group = gu)
cold = input.color (#ff4800, "Bear Color"        ,                           group = gu)


bar        b  = bar.new(
       nz(src[1])               ,
       math.max(nz(src[1]), src),
       math.min(nz(src[1]), src),
       src                      )
float      tr = b  .atr(     len)
supertrend st = b  .st (mlt, len)


color cst = switch st.d
    +1 => cold
    -1 => colu
    
t = plot(st.d > 0 ? st.s : na, 'Bear ST'  , cst           , 1, plot.style_linebr)
d = plot(st.d < 0 ? st.s : na, 'Bull ST'  , cst           , 1, plot.style_linebr)
i = plot(st.d                , 'Direction', display =          display.none     )
c = plot(b.src('oc2')        , 'Filler'   , display =          display.none     )

fill(t, c, color.new(cold, 90))
fill(d, c, color.new(colu, 90))

bool scon = clbl and math.sign(ta.change(st.d)) ==  1 ? true : false
bool bcon = clbl and math.sign(ta.change(st.d)) == -1 ? true : false

plotshape(scon ? st.s + tr / 3 : na, 'Sell Signal', shape.labeldown, location.absolute, color.new(cold, 60), 0, '𝓢', chart.fg_color)
plotshape(bcon ? st.s - tr / 3 : na, 'Buy Signal' , shape.labelup  , location.absolute, color.new(colu, 60), 0, '𝓑', chart.fg_color)