Standardized SuperTrend Oscillator
// 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/
// © EliCobra

//@version=5
indicator("Standardized SuperTrend Oscillator", "[Ʌ] -‌ Super Osc.", false)

type bar
    float o = open
    float h = high
    float l = low
    float c = close

type supertrend
    float s = na
    int   d = na
    float u = na
    float l = 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 ha(bar b, simple bool p = true) =>
    var bar x = bar.new(       )
    x.c      := b  .src('ohlc4')
    x        := bar.new(
         na(x.o[1]) ? 
             b.src('oc2') : nz(x.src('oc2')[1]),
         math.max(b.h, math.max(x.o, x.c))     ,
         math.min(b.l, math.min(x.o, x.c))     ,
         x.c                                   )

    p ? x : b

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, up, dn)

method sso(bar b, supertrend st, simple int len) =>
    float std = ta .ema(st.u - st.l, len) / 100
    bar   x   = bar.new(
                      (b.o - st.s) / std,
                      (b.h - st.s) / std,
                      (b.l - st.s) / std,
                      (b.c - st.s) / std)

    x


var string tp = 'Source for SuperTrend -\n\n∙ On-> Heikin-Ashi candles\n∙ Off-> Regular candles'
var string g1 = "Oscillator Settings", var string g2 = "SuperTrend of Oscillator", var string gu = "UI Options"
base = input.bool  (false    , "Heikin-Ashi Source", tp                             ,               group = g1)
len1 = input.int   (10       , "Length"            ,                                  inline = '1', group = g1)
mlt1 = input.float (5.       , "Factor"            , 1, 10, 0.5                     , inline = '1', group = g1)
len2 = input.int   (10       , "Length"            ,                                  inline = '2', group = g2)
mlt2 = input.float (3.       , "Factor"            , 1, 10, 0.5                     , inline = '2', group = g2)
osc  = input.string('Candles', "Oscillator Style"  , ['Candles',             'Line'],               group = gu)
d_st = input.bool  (true     , "SuperTrend Of Osc.",                                                group = gu)
d_rt = input.bool  (true     , "Reversion  Tracer" ,                                                group = gu)
rlbl = input.string('None'   , "Reversion  Signals", ['None', 'OB' , 'OS'  , 'Both'],               group = gu)
clbl = input.string('None'   , "Contrarian Signals", ['None', 'Buy', 'Sell', 'Both'],               group = gu)


bar        b   = bar.new(           ).ha(base)
supertrend t1  = b  .st (mlt1 , len1)
bar        sso = b  .sso(t1   , len1).ha(    )
supertrend t2  = sso.st (mlt2 , len2)
float      rvt = ta .rsi(-t1.d, len1) * 2 - 100

var color colup = #22ab94 
var color coldn = #ffdab9
var color colvt = #daa520
var color colut = color.new(#22ab94       , 60 )
var color coldt = color.new(#f23645       , 60 )
var color trnsp =   color.new(chart.bg_color, 100)

color col = switch
    sso.c > sso.o => colup
    sso.c < sso.o => coldn

color cst = switch t2.d
    +1 => #ff4800
    -1 => #1582ff

color cso = switch
    sso.c > rvt and sso.c > 0 => #22ab94
    sso.c < rvt and sso.c < 0 => #f23645
    =>                             chart.fg_color

plotcandle(osc == 'Candles' ? sso.o : na     ,
           osc == 'Candles' ? sso.h : na     ,
           osc == 'Candles' ? sso.l : na     ,
           osc == 'Candles' ? sso.c : na     ,
           'SSO', col, col, bordercolor = col)

h = hline(0                                      , 'Mid-Line', chart.fg_color,    hline.style_dotted)
o = plot (osc == 'Line'     ? sso.c          : na, 'SSO'     , cso           , 1, plot.style_line   )
t = plot (d_st and t2.d > 0 ? t2.s           : na, 'Bear ST' , cst           , 1, plot.style_linebr )
d = plot (d_st and t2.d < 0 ? t2.s           : na, 'Bull ST' , cst           , 1, plot.style_linebr )
u = plot (d_rt and rvt  > 0 ? rvt            : na, 'Upper RT', colvt         , 1, plot.style_linebr )
l = plot (d_rt and rvt  < 0 ? rvt            : na, 'Lower RT', colvt         , 1, plot.style_linebr )
c = plot (osc == 'Candles'  ? sso.src('oc2') : na, 'Filler'  , display =          display.none      )
m = plot (0                                      , 'Filler'  , display =          display.none      )

fill(m, o, 10 * mlt1,  10       , colut, trnsp)
fill(m, o, 10       , -10 * mlt1, trnsp, coldt)

fill(t, c, #ff480010)
fill(d, c, #1582ff10)

bool scon = (clbl == 'Sell' or clbl == 'Both') and math.sign    (ta.change(t2.d))   ==   1  ? true : false
bool bcon = (clbl == 'Buy'  or clbl == 'Both') and math.sign    (ta.change(t2.d))   ==  -1  ? true : false
bool ucon = (rlbl == 'OB'   or rlbl == 'Both') and ta.crossover (sso.c, rvt < 0 ? rvt : na) ? true : false
bool dcon = (rlbl == 'OS'   or rlbl == 'Both') and ta.crossunder(sso.c, rvt > 0 ? rvt : na) ? true : false

plotshape(scon ? t2.s + 5  : na, 'Sell Signal', shape.labeldown, location.absolute, #ff480075, 0, '𝓢' , chart.fg_color)
plotshape(bcon ? t2.s - 5  : na, 'Buy Signal' , shape.labelup  , location.absolute, #1582ff75, 0, '𝓑' , chart.fg_color)
plotshape(dcon ? rvt  + 15 : na, 'OB Signal'  , shape.labeldown, location.absolute, #f2364575, 0, '𝓞𝓑', chart.fg_color)
plotshape(ucon ? rvt  - 15 : na, 'OS Signal'  , shape.labelup  , location.absolute, #22ab9475, 0, '𝓞𝓢', chart.fg_color)

//Source Construction For Indicator\Strategy Exports
plot(osc == 'Candles' ? sso.o            : na, "open" , editable = false, display = display.none)
plot(osc == 'Candles' ? sso.h            : na, "high" , editable = false, display = display.none)
plot(osc == 'Candles' ? sso.l            : na, "low"  , editable = false, display = display.none)
plot(osc == 'Candles' ? sso.c            : na, "close", editable = false, display = display.none)
plot(osc == 'Candles' ? sso.src('hl2'  ) : na, "hl2"  , editable = false, display = display.none)
plot(osc == 'Candles' ? sso.src('hlc3' ) : na, "hlc3" , editable = false, display = display.none)
plot(osc == 'Candles' ? sso.src('ohlc4') : na, "ohlc4", editable = false, display = display.none)
plot(osc == 'Candles' ? sso.src('hlcc4') : na, "hlcc4", editable = false, display = display.none)