Net Positions (Net Longs & Net Shorts) - By Leviathan
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LeviathanCapital
 
//@version=5
indicator("Net Positions (Net Longs & Net Shorts) - By Leviathan", max_labels_count = 500, overlay = false, format = format.volume)

g1 = '📊 Net Positions '
g2 = '📈 Moving Averages (VWMA/EMA) '
g3 = '⚙️ Additional Settings '
g4 = '🎚️ Profile '
g5 = '🖥️ Statistics '
g6 = '⚖️ Divergences'

// User inputs - General settings 
dtype = input.string('Net Positions', 'Type',                options = ['Net Positions', 'Position RSI'])
disp  = input.string('Candles', 'Display as',                options = ['Candles', 'Line', 'Columns'])
cumu  = input.string('Visible Range', 'Cumulation',          options = ['Full Data', 'Visible Range'])
denom = input.string('Base Currency', 'Quoted in',           options = ['Base Currency', 'Quote Currency'])

// User inputs - Data Source Settings
binance   = input.bool(true, 'Binance USDT.P', inline = 'src')
binance2  = input.bool(true, 'Binance USD.P',  inline = 'src')
binance3  = input.bool(true, 'Binance BUSD.P', inline = 'src2')
bitmex    = input.bool(true, 'BitMEX USD.P',   inline = 'src2')
bitmex2   = input.bool(true, 'BitMEX USDT.P ', inline = 'src3')
kraken    = input.bool(true, 'Kraken USD.P',   inline = 'src3')

// User inputs - Net Positions
showL = input.bool(true,  'NET LONGS   ►',   group = g1, inline='l')
showS = input.bool(false, 'NET SHORTS  ►',   group = g1, inline='s')
showD = input.bool(false, 'NET DELTA    ►',  group = g1, inline='d')
showR = input.bool(false, 'NET RATIO    ►',  group = g1, inline='r')

pcolL = input.color(#a5d6a7, '',       group = g1, inline = 'l')
ncolL = input.color(#f77c80,   '',     group = g1, inline = 'l')
lcolL = input.color(#a5d6a7, '━',      group = g1, inline = 'l')

pcolS = input.color(#a5d6a7, '',       group = g1, inline = 's')
ncolS = input.color(#f77c80,   '',     group = g1, inline = 's')
lcolS = input.color(#faa1a4,   '━',    group = g1, inline = 's')

pcolD = input.color(#a5d6a7, '',       group = g1, inline = 'd')
ncolD = input.color(#f77c80,   '',     group = g1, inline = 'd')
lcolD = input.color(#90bff9,   '━',    group = g1, inline = 'd')

pcolR = input.color(#a5d6a7, '',       group = g1, inline = 'r')
ncolR = input.color(#f77c80,   '',     group = g1, inline = 'r')
lcolR = input.color(#f9d690,   '━',    group = g1, inline = 'r')

// User inputs - Net Positions EMAs
mat  = input.string('VWMA', 'Type', options=['VWMA', 'EMA'], group=g2)
emaL = input.bool(false, 'LONGS  ', group=g2,   inline='emal')
emaS = input.bool(false, 'SHORTS ', group=g2,   inline='emas')
emaD = input.bool(false, 'DELTA   ',group=g2,   inline='emad')
emaR = input.bool(false, 'RATIO   ',group=g2,   inline='emar')

emaLl = input.int(100, '',               group=g2,   inline='emal')
emaSl = input.int(100, '',               group=g2,   inline='emas')
emaDl = input.int(100, '',               group=g2,   inline='emad')
emaRl = input.int(100, '',               group=g2,   inline='emar')

emaLc = input.color(color.rgb(165, 214, 167, 60), '', group=g2, inline='emal')
emaSc = input.color(color.rgb(250, 161, 164, 60), '', group=g2, inline='emas')
emaDc = input.color(color.rgb(144, 191, 249, 60), '', group=g2, inline='emad')
emaRc = input.color(color.rgb(249, 214, 144, 60), '', group=g2, inline='emar')

// User inputs - Additional settings 
volhm   = input.bool(false, 'Volume HM', group=g3, inline='vol')
volc2   = input.color(color.rgb(49, 121, 245),'', group=g3, inline = 'vol')
offs    = input.int (10,    'Label Offset',             group=g3)
length  = input.int (14,    'Position RSI Length',      group=g3)
vlbl    = input.bool(true,  'Value Labels',             group=g3,  inline='lv')
nlbl    = input.bool(true,  'Data Labels',              group=g3,  inline='lv')
wick    = input.bool(false, 'Show Candle Wicks',        group=g3)


// User inputs - Profile settings
prof     = input.bool  (false, 'Generate a profile', group=g4)
profsrc  = input.string('Net Longs', 'Profile Data', options = ['Net Delta', 'Net Longs', 'Net Shorts', 'Net Ratio'], group=g4)
vapct    = input.float (70, 'Value Area %', minval = 5, maxval = 95,         group = g4)
ori      = input.string("Left", 'Position', options = ["Left", "Right"],     group = g4)  
profSize = input.int   (2, 'Node Size', minval = 1,                          group = g4)
rows     = input.int   (40, 'Rows', minval = 6, maxval = 500, step = 25,     group = g4) - 1
vancol   = input.color (color.new(color.blue, 75), 'Node Colors         ', group = g4, inline = 'nc')
nvancol  = input.color (color.new(color.gray, 75), '━',             group = g4, inline = 'nc')
poc      = input.bool  (false, 'POC',                                 group = g4, inline = 'POC'), 
poccol   = input.color (color.new(color.red, 50), '            ',   group = g4, inline = "POC")
val      = input.bool  (false, 'VA',                                  group = g4, inline = "VA")
vafill   = input.color (color.new(color.blue, 95), '             ', group = g4, inline = 'VA')

// User inputs - Statistics
stats       = input.bool(false, 'Show Stats', group = g5)
chg_b       = input.int(50, 'Bars Back',      group = g5)
tablevpos   = input.string('Horizontal', 'Orientation', options=['Horizontal', 'Vertical'], group = g5)
tablepos    = input.string('Bottom Center', 'Position', options=['Top Left', 'Top Center', 'Top Right', 'Bottom Left', 'Bottom Center', 'Bottom Right'], group = g5)

stat_oi    = input.bool(true, 'OI   ━',       group = g5, inline = 'oi')
stat_nl    = input.bool(true, 'NL  ━',        group = g5, inline = 'nl')
stat_ns    = input.bool(true, 'NS  ━',        group = g5, inline = 'ns')
stat_nd    = input.bool(true, 'ND  ━',        group = g5, inline = 'nd')
stat_oi_c  = input.bool(true, 'OI Change  ━', group = g5, inline = 'oi')
stat_nl_c  = input.bool(true, 'NL Change  ━', group = g5, inline = 'nl')
stat_ns_c  = input.bool(true, 'NS Change  ━', group = g5, inline = 'ns')
stat_nd_c  = input.bool(true, 'ND Change  ━', group = g5, inline = 'nd')
stat_oi_r  = input.bool(true, 'OI RSI',       group = g5, inline = 'oi')
stat_nl_r  = input.bool(true, 'NL RSI',       group = g5, inline = 'nl')
stat_ns_r  = input.bool(true, 'NS RSI',       group = g5, inline = 'ns')
stat_nd_r  = input.bool(true, 'ND RSI',       group = g5, inline = 'nd')

// User inputs - Divergence Finder
showdiv       = input.bool(false, 'Divergence finder', group = g6)
divsrc        = input.string('Net Longs', 'Source', options = ['Net Longs', 'Net Shorts', 'Net Delta', 'Net Ratio'], group=g6)
pivotDistance = input.int(5, 'Maximum Distance',    minval=0, group=g6)
leftPivot     = input.int(8, 'Lookback Bars Left',  minval=1, group=g6)
rightPivot    = input.int(8, 'Lookback Bars Right', minval=1, group=g6)

pHH_npLH      = input.bool(true, 'Price HH + Data LH',  group = g6, inline='div1')
pLH_npHH      = input.bool(true, 'Price LH + Data HH',  group = g6, inline='div2')
pLL_npHL      = input.bool(true, 'Price LL + Data HL ', group = g6, inline='div3')
pHL_npLL      = input.bool(true, 'Price HL + Data LL ', group = g6, inline='div4')
pHH_npLHcol   = input.color(color.red, '',            group = g6, inline='div1')
pLH_npHHcol   = input.color(color.red, '',            group = g6, inline='div2')
pLL_npHLcol   = input.color(color.green, '',          group = g6, inline='div3')
pHL_npLLcol   = input.color(color.green, '',          group = g6, inline='div4')


// Getting OI data
mex = syminfo.basecurrency=='BTC' ? 'XBT' : string(syminfo.basecurrency)
[oid1, oi1] = request.security('BINANCE' + ":" + string(syminfo.basecurrency) + 'USDT.P_OI',  timeframe.period,  [close-close[1], close], ignore_invalid_symbol = true)
[oid2, oi2] = request.security('BINANCE' + ":" + string(syminfo.basecurrency) + 'USD.P_OI',   timeframe.period,  [close-close[1], close], ignore_invalid_symbol = true)
[oid3, oi3] = request.security('BINANCE' + ":" + string(syminfo.basecurrency) + 'BUSD.P_OI',  timeframe.period,  [close-close[1], close], ignore_invalid_symbol = true)
[oid4, oi4] = request.security('BITMEX'  + ":" + mex                          + 'USD.P_OI',   timeframe.period,  [close-close[1], close], ignore_invalid_symbol = true)
[oid5, oi5] = request.security('BITMEX'  + ":" + mex                          + 'USDT.P_OI',  timeframe.period,  [close-close[1], close], ignore_invalid_symbol = true)
[oid6, oi6] = request.security('KRAKEN'  + ":" + string(syminfo.basecurrency) + 'USD.P_OI',   timeframe.period,  [close-close[1], close], ignore_invalid_symbol = true)

deltaOI = (binance ? nz(oid1,0) : 0)   +   (binance2 ? nz(oid2,0)/close : 0)   +    (binance3 ? nz(oid3,0) : 0)    +   (bitmex ? nz(oid4,0)/close : 0)   +   (bitmex2 ? nz(oid5,0)/close : 0)   +   (kraken ? nz(oid6,0)/close : 0)
OI      = (binance ? nz(oi1,0) : 0)   +   (binance2 ? nz(oi2,0)/close : 0)   +    (binance3 ? nz(oi3,0) : 0)    +   (bitmex ? nz(oi4,0)/close : 0)   +   (bitmex2 ? nz(oi5,0)/close : 0)   +   (kraken ? nz(oi6,0)/close : 0)

// Conditions for positions entering and exiting
priceUP   = close>open
priceDOWN = close<open
oiUP      = deltaOI>0
oiDOWN    = deltaOI<0

newlongs   = oiUP   and priceUP
rektlongs  = oiDOWN and priceDOWN
newshorts  = oiUP   and priceDOWN
rektshorts = oiDOWN and priceUP

// Visible range 
vrc = cumu=='Visible Range' ? time > chart.left_visible_bar_time and time <= chart.right_visible_bar_time : true

// Cumulation of positions entering and exiting
longs_entering     = ta.cum(newlongs   and vrc   ?   (denom=='Base Currency' ? deltaOI : deltaOI * close) : 0)
longs_exiting      = ta.cum(rektlongs  and vrc   ?   (denom=='Base Currency' ? deltaOI : deltaOI * close) : 0)
shorts_entering    = ta.cum(newshorts  and vrc   ?   (denom=='Base Currency' ? deltaOI : deltaOI * close) : 0)
shorts_exiting     = ta.cum(rektshorts and vrc   ?   (denom=='Base Currency' ? deltaOI : deltaOI * close) : 0)

// Output data
net_longs          = longs_entering  - math.abs(longs_exiting)
net_shorts         = shorts_entering - math.abs(shorts_exiting)
net_delta          = net_longs       - net_shorts
net_ratio          = net_longs       / net_shorts

// Calculating Relative Strength
longs_strength     = ta.rsi(net_longs,  length)
shorts_strength    = ta.rsi(net_shorts, length)
delta_strength     = ta.rsi(net_delta,  length)
ratio_strength     = ta.rsi(net_ratio,  length)
oi_strength        = ta.rsi(OI,         length)

// Calculating candle OHLC
src    = dtype=='Net Positions' ?  net_longs  : longs_strength
OpenL  = wick ? ta.sma(src[1], 2) : src[1]
HighL  = ta.highest(src, 1)
LowL   = ta.lowest(src, 1)
CloseL = wick ? ta.sma(src, 2) : src

src2   = dtype=='Net Positions' ?  net_shorts : shorts_strength
OpenS  = wick ? ta.sma(src2[1], 2) : src2[1]
HighS  = ta.highest(src2, 1)
LowS   = ta.lowest(src2, 1)
CloseS = wick ? ta.sma(src2, 2) : src2

src3   = dtype=='Net Positions' ?  net_delta  : delta_strength
OpenD  = wick ? ta.sma(src3[1], 2) : src3[1]
HighD  = ta.highest(src3, 1)
LowD   = ta.lowest(src3, 1)
CloseD = wick ? ta.sma(src3, 2) : src3

src4   = dtype=='Net Positions' ?  net_ratio  : ratio_strength
OpenR  = wick ? ta.sma(src4[1], 2) : src4[1]
HighR  = ta.highest(src4, 1)
LowR   = ta.lowest(src4, 1)
CloseR = wick ? ta.sma(src4, 2) : src4

// Calculating EMAs
Lema = mat=='EMA' ? ta.ema(src,  emaLl) : ta.vwma(src,   emaLl)
Sema = mat=='EMA' ? ta.ema(src2, emaSl) : ta.vwma(src2,  emaSl)
Dema = mat=='EMA' ? ta.ema(src3, emaDl) : ta.vwma(src3,  emaDl)
Rema = mat=='EMA' ? ta.ema(src4, emaRl) : ta.vwma(src4,  emaRl)

// Conditions
lcondL = showL and (disp=='Line' or disp=='Columns'), ccondL = showL and disp=='Candles'
lcondS = showS and (disp=='Line' or disp=='Columns'), ccondS = showS and disp=='Candles'
lcondD = showD and (disp=='Line' or disp=='Columns'), ccondD = showD and disp=='Candles'
lcondR = showR and (disp=='Line' or disp=='Columns'), ccondR = showR and disp=='Candles'

// Plotting Lines
plot(lcondL ? src   : na, title="Net Longs",  color=disp=='Line' ? lcolL : (net_longs  >0 ? pcolL : ncolL), linewidth=1, style = disp=='Line' ? plot.style_line : disp=='Columns' ? plot.style_columns : na, editable = false)
plot(lcondS ? src2  : na, title="Net Shorts", color=disp=='Line' ? lcolS : (net_shorts >0 ? pcolS : ncolS), linewidth=1, style = disp=='Line' ? plot.style_line : disp=='Columns' ? plot.style_columns : na, editable = false)
plot(lcondD ? src3  : na, title="Net Shorts", color=disp=='Line' ? lcolD : (net_delta  >0 ? pcolD : ncolD), linewidth=1, style = disp=='Line' ? plot.style_line : disp=='Columns' ? plot.style_columns : na, editable = false)
plot(lcondR ? src4  : na, title="Net Ratio",  color=disp=='Line' ? lcolR : (net_ratio  >0 ? pcolR : ncolR), linewidth=1, style = disp=='Line' ? plot.style_line : disp=='Columns' ? plot.style_columns : na, editable = false)

// Plotting Candles
plotcandle(ccondL ? OpenL : na, ccondL ? HighL : na, ccondL ? LowL : na, ccondL ? CloseL : na, "Longs",  CloseL>OpenL ? pcolL : ncolL, CloseL>OpenL ? pcolL : ncolL, false, bordercolor = CloseL>OpenL ? pcolL : ncolL)
plotcandle(ccondS ? OpenS : na, ccondS ? HighS : na, ccondS ? LowS : na, ccondS ? CloseS : na, "Shorts", CloseS>OpenS ? pcolS : ncolS, CloseS>OpenS ? pcolS : ncolS, false, bordercolor = CloseS>OpenS ? pcolS : ncolS)
plotcandle(ccondD ? OpenD : na, ccondD ? HighD : na, ccondD ? LowD : na, ccondD ? CloseD : na, "Delta",  CloseD>OpenD ? pcolD : ncolD, CloseD>OpenD ? pcolD : ncolD, false, bordercolor = CloseD>OpenD ? pcolD : ncolD)
plotcandle(ccondR ? OpenR : na, ccondR ? HighR : na, ccondR ? LowR : na, ccondR ? CloseR : na, "Ratio",  CloseR>OpenR ? pcolR : ncolR, CloseR>OpenR ? pcolR : ncolR, false, bordercolor = CloseR>OpenR ? pcolR : ncolR)

// Plotting EMAs
plot(emaL ? Lema : na, color=emaLc, editable = false)
plot(emaS ? Sema : na, color=emaSc, editable = false)
plot(emaD ? Dema : na, color=emaDc, editable = false)
plot(emaR ? Rema : na, color=emaRc, editable = false)

// Plotting Relative Strength
plot(dtype=='Position RSI' ? 100 : na, color=color.rgb(120, 123, 134, 90), title = 'RSI 100')
plot(dtype=='Position RSI' ? 70  : na, color=color.rgb(120, 123, 134, 72), title = 'RSI 70')
plot(dtype=='Position RSI' ? 50  : na, color=color.rgb(120, 123, 134, 90), title = 'RSI 50')
plot(dtype=='Position RSI' ? 30  : na, color=color.rgb(120, 123, 134, 72), title = 'RSI 30')
plot(dtype=='Position RSI' ? 0   : na, color=color.rgb(120, 123, 134, 90), title = 'RSI 0')

// Volume Heatmap
vol    = volume
volmax = ta.highest(volume, 50)
col    = color.from_gradient(volume, 0, volmax, chart.bg_color, volc2)
plotshape(time>chart.left_visible_bar_time and volhm, style=shape.square, size=size.normal,location = location.bottom, color=col, editable = false)

// Labels
if vlbl and disp=='Candles'
    vLlabel = showL ? label.new(bar_index, CloseL>OpenL ? HighL : LowL, newlongs  or rektlongs  ? str.tostring(deltaOI, format.volume) : na, size = size.auto, color=color.rgb(255, 255, 255, 100), textcolor = chart.fg_color, style = CloseL>OpenL ? label.style_label_down : label.style_label_up) : na
    vSlabel = showS ? label.new(bar_index, CloseS>OpenS ? HighS : LowS, newshorts or rektshorts ? str.tostring(deltaOI, format.volume) : na, size = size.auto, color=color.rgb(255, 255, 255, 100), textcolor = chart.fg_color, style = CloseS>OpenS ? label.style_label_down : label.style_label_up) : na
    vDlabel = showD ? label.new(bar_index, CloseD>OpenD ? HighD : LowD, str.tostring(deltaOI, format.volume), size = size.auto, color=color.rgb(255, 255, 255, 100), textcolor = chart.fg_color, style = CloseD>OpenD ? label.style_label_down : label.style_label_up) : na
    vRlabel = showR ? label.new(bar_index, CloseR>OpenR ? HighR : LowR, str.tostring(deltaOI, format.volume), size = size.auto, color=color.rgb(255, 255, 255, 100), textcolor = chart.fg_color, style = CloseR>OpenR ? label.style_label_down : label.style_label_up) : na

if nlbl and disp!='Columns'
    Llabel = showL ? label.new(bar_index+offs, src,   'NET LONGS',  size = size.tiny, color=lcolL, textcolor = color.black, style = label.style_label_left) : na
    Slabel = showS ? label.new(bar_index+offs, src2,  'NET SHORTS', size = size.tiny, color=lcolS, textcolor = color.black, style = label.style_label_left) : na
    Dlabel = showD ? label.new(bar_index+offs, src3,  'NET DELTA',  size = size.tiny, color=lcolD, textcolor = color.black, style = label.style_label_left) : na
    Rlabel = showR ? label.new(bar_index+offs, src4,  'NET RATIO',  size = size.tiny, color=lcolR, textcolor = color.black, style = label.style_label_left) : na
    label.delete(Llabel[1])
    label.delete(Slabel[1])
    label.delete(Dlabel[1])   
    label.delete(Rlabel[1])

// Generating a profile - Code from @KioseffTrading's "Profile Any Indicator" script (used with their permission)
srcp = profsrc=='Net Longs' ? src : profsrc=='Net Shorts' ? src2 : profsrc=='Net Delta' ? src3 : src4

var int   [] timeArray  = array.new_int()
var float [] dist       = array.new_float()
var int   [] x2         = array.new_int(rows + 1, 5)
var          vh         = matrix.new<float>(1, 1)

array.unshift(timeArray, math.round(time)) 

if prof and time >= chart.left_visible_bar_time and time <= chart.right_visible_bar_time
    matrix.add_col(vh)
    matrix.set(vh, 0, matrix.columns(vh) - 1, srcp)


if prof and barstate.islast

    [pos, n] = switch ori
        "Left" =>  [chart.left_visible_bar_time , array.indexof(timeArray,  chart.left_visible_bar_time)]
        =>         [chart.right_visible_bar_time, array.indexof(timeArray, chart.right_visible_bar_time)]


    calc = (matrix.max(vh) - matrix.min(vh)) / (rows + 1)

    for i = 0 to rows
        array.push(dist, matrix.min(vh) + (i * calc))
    

    for i = 1 to matrix.columns(vh) - 1
        for x = 0 to array.size(dist) - 1
            if matrix.get(vh, 0, i) >= matrix.get(vh, 0, i - 1)
                if array.get(dist, x) >= matrix.get(vh, 0, i - 1) and array.get(dist, x) <= matrix.get(vh, 0, i)
                    array.set(x2, x, array.get(x2, x) + profSize)
            
            else 
                
                if array.get(dist, x) >= matrix.get(vh, 0, i) and array.get(dist, x) <= matrix.get(vh, 0, i - 1)
                    array.set(x2, x, array.get(x2, x) + profSize)

    boc = array.new_box()
    for i = 1 to rows
        
        right = array.get(timeArray, n + array.get(x2, i))
        
        if ori == "Left"
            switch math.sign(n - array.get(x2, i))

                -1 => right := chart.right_visible_bar_time
                =>    right := array.get(timeArray, n - array.get(x2, i))



        array.push(boc, box.new(pos, array.get(dist, i - 1), 
             right, array.get(dist, i), xloc = xloc.bar_time, border_color = 
             nvancol, bgcolor = nvancol
             ))
        if i == rows 
            array.push(boc, box.new(pos, array.get(dist, array.size(dist) - 1), 
                     right, array.get(dist, array.size(dist) - 1) + calc, xloc = xloc.bar_time, border_color = 
                     nvancol, bgcolor = nvancol
                     ))


    array.shift(x2), nx = array.indexof(x2, array.max(x2))
    nz = nx - 1, nz2 = 0, nz3 = 0, nz4 = 0
    for i = 0 to array.size(x2) - 1
        if nz > -1 and nx <= array.size(x2) - 1
            switch array.get(x2, nx) >= array.get(x2, nz)
                true => nz2 += array.get(x2, nx), nx += 1
                =>      nz2 += array.get(x2, nz), nz -= 1
                
        else if nz <= -1
            nz2 += array.get(x2, nx), nx += 1
        else if nx >= array.size(x2)
            nz2 += array.get(x2, nz), nz -= 1
        if nz2 >= array.sum(x2) * (vapct / 100)
            nz3 := nx <= array.size(x2) - 1 ? nx : array.size(x2) - 1, nz4 := nz <= -1 ? 0 : nz
            break

    for i = nz3 to nz4
        box.set_border_color(array.get(boc, i), vancol)
        box.set_bgcolor(array.get(boc, i), vancol)
    if poc 
        var pocL = line(na)
        y = math.avg(box.get_top(array.get(boc, array.indexof(x2, array.max(x2)))), box.get_bottom(array.get(boc, array.indexof(x2, array.max(x2)))))
        if na(pocL)
            pocL := line.new(chart.left_visible_bar_time, y, chart.right_visible_bar_time, y, xloc = xloc.bar_time, color = poccol, width = 1)
        else 
            line.set_xy1(pocL, chart.left_visible_bar_time, y)
            line.set_xy2(pocL, chart.right_visible_bar_time, y)
    if val 
        var vaup = line(na), var vadn = line(na)
        ydn = box.get_bottom(array.get(boc, nz3)), yup = box.get_top(array.get(boc, nz4))

        if na(vaup)

            vadn := line.new(chart.left_visible_bar_time, ydn, chart.right_visible_bar_time, ydn, xloc = xloc.bar_time, color = vancol, width = 1)
            vaup := line.new(chart.left_visible_bar_time, yup, chart.right_visible_bar_time, yup, xloc = xloc.bar_time, color = vancol, width = 1)

        else 

            line.set_xy1(vadn, chart.left_visible_bar_time, ydn), line.set_xy2(vadn, chart.right_visible_bar_time, ydn)
            line.set_xy1(vaup, chart.left_visible_bar_time, yup), line.set_xy2(vaup, chart.right_visible_bar_time, yup)

        linefill.new(vadn, vaup, vafill)

//Generating tables for Stats
switchpos(tablepos) =>
    switch tablepos
        'Top Left'      => position.top_left
        'Top Center'    => position.top_center
        'Top Right'     => position.top_right
        'Bottom Left'   => position.bottom_left
        'Bottom Center' => position.bottom_center
        'Bottom right'  => position.bottom_right

dataTable = table.new(switchpos(tablepos), columns=15, rows=15, bgcolor=color.rgb(120, 123, 134, 56))
fill_rows(cond, txt, c, r) =>
    if cond
        table.cell(table_id=dataTable, column = tablevpos=='Horizontal' ? c : 0,  row = tablevpos=='Horizontal' ? 0 : r, text = txt, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center)

if barstate.islast and stats and dtype!='Position RSI'
    txt  = ' •𝗢𝗜: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(denom=='Base Currency' ? OI : OI*close, format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt2 = ' •𝗡𝗟: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(net_longs, format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt3 = ' •𝗡𝗦: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(net_shorts, format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt4 = ' •𝗡𝗗: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(net_delta, format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt5 = ' •𝗢𝗜𝗖: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(denom=='Base Currency' ? OI-OI[chg_b] : (OI-OI[chg_b]) * close, format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt6 = ' •𝗡𝗟𝗖: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(net_longs - net_longs[chg_b], format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt7 = ' •𝗡𝗦𝗖: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(net_shorts - net_shorts[chg_b], format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt8 = ' •𝗡𝗗𝗖: ' + (denom=='Quote Currency' ? '$' : '') + str.tostring(net_delta - net_delta[chg_b], format = format.volume) + ' ' + (denom=='Base Currency' ? str.tostring(string(syminfo.basecurrency)) : '')
    txt9 = ' •𝗢𝗜 𝗥𝗦𝗜: ' + str.tostring(math.round(oi_strength,1))
    txt10 = ' •𝗡𝗟 𝗥𝗦𝗜: ' + str.tostring(math.round(longs_strength,1))
    txt11 = ' •𝗡𝗦 𝗥𝗦𝗜: ' + str.tostring(math.round(shorts_strength, 1))
    txt12 = ' •𝗡𝗗 𝗥𝗦𝗜: ' + str.tostring(math.round(delta_strength, 1))

    fill_rows(stat_oi,   txt,   0, 0)
    fill_rows(stat_nl,   txt2,  1, 1)
    fill_rows(stat_ns,   txt3,  2, 2)
    fill_rows(stat_nd,   txt4,  3, 3)
    fill_rows(stat_oi_c, txt5,  4, 4)
    fill_rows(stat_nl_c, txt6,  5, 5)
    fill_rows(stat_ns_c, txt7,  6, 6)
    fill_rows(stat_nd_c, txt8,  7, 7)
    fill_rows(stat_oi_r, txt9,  8, 8)
    fill_rows(stat_nl_r, txt10, 9, 9)
    fill_rows(stat_ns_r, txt11, 10, 10)
    fill_rows(stat_nd_r, txt12, 11, 11)

// Divergence Finder
switchdivsrc(divsrc) =>
    switch divsrc
        'Net Longs'  => src
        'Net Shorts' => src2
        'Net Delta'  => src3
        'Net Ratio'  => src4

np = switchdivsrc(divsrc)

var priceHigh         = array.new_float(0), var priceLow          = array.new_float(0)
var priceHighIndex    = array.new_int  (0), var priceLowIndex     = array.new_int  (0) 
var npHigh            = array.new_float(0), var npLow             = array.new_float(0)
var npHighIndex       = array.new_int  (0), var npLowIndex        = array.new_int  (0) 
var priceHighTrend    = 0,                  var priceLowTrend     = 0
var npHighTrend       = 0,                  var npLowTrend        = 0
bool closeRecentHighs = false,              bool closeOldHighs    = false
bool closeHighs       = false,              bool closeRecentLows  = false
bool closeOldLows     = false,              bool closeLows        = false

curPriceHigh          = ta.pivothigh(close,  leftPivot, rightPivot)
curPriceLow           = ta.pivotlow (close,  leftPivot, rightPivot)
curnpHigh             = ta.pivothigh(np,     leftPivot, rightPivot)
curnpLow              = ta.pivotlow (np,     leftPivot, rightPivot)

if not na(curPriceHigh)
    array.push(priceHigh, curPriceHigh)
    array.push(priceHighIndex, bar_index-rightPivot)
if not na(curPriceLow)
    array.push(priceLow, curPriceLow)
    array.push(priceLowIndex,  bar_index-rightPivot)

if not na(curnpHigh)
    array.push(npHigh, curnpHigh)
    array.push(npHighIndex,   bar_index-rightPivot)
if not na(curnpLow)
    array.push(npLow, curnpLow)
    array.push(npLowIndex,    bar_index-rightPivot)

if showdiv
    if array.size(priceHigh) >= 2 and not na(curPriceHigh)
        if array.get(priceHigh, array.size(priceHigh)-1) >= array.get(priceHigh, array.size(priceHigh)-2)
            priceHighTrend := 1
        else 
            priceHighTrend := -1

    if array.size(priceLow) >= 2 and not na(curPriceLow)
        if array.get(priceLow, array.size(priceLow)-1) >= array.get(priceLow, array.size(priceLow)-2)
            priceLowTrend  := 1
        else 
            priceLowTrend  := -1

    if array.size(npHigh) >= 2 and not na(curnpHigh)
        if array.get(npHigh, array.size(npHigh)-1) >= array.get(npHigh, array.size(npHigh)-2)
            npHighTrend := 1
        else 
            npHighTrend := -1

    if array.size(npLow) >= 2 and not na(curnpLow)
        if array.get(npLow, array.size(npLow)-1) >= array.get(npLow, array.size(npLow)-2)
            npLowTrend  := 1
        else 
            npLowTrend  := -1

    if array.size(priceHighIndex) >= 2 and array.size(npHighIndex) >=2
        closeRecentHighs := math.abs(array.get(priceHighIndex, array.size(priceHighIndex)-1) - array.get(npHighIndex, array.size(npHighIndex)-1)) <= pivotDistance
        closeOldHighs    := math.abs(array.get(priceHighIndex, array.size(priceHighIndex)-2) - array.get(npHighIndex, array.size(npHighIndex)-2)) <= pivotDistance
        closeHighs       := closeRecentHighs and closeOldHighs

    if array.size(priceLowIndex) >= 2 and array.size(npLowIndex) >=2
        closeRecentLows := math.abs(array.get(priceLowIndex, array.size(priceLowIndex)-1) - array.get(npLowIndex, array.size(npLowIndex)-1)) <= pivotDistance
        closeOldLows    := math.abs(array.get(priceLowIndex, array.size(priceLowIndex)-2) - array.get(npLowIndex, array.size(npLowIndex)-2)) <= pivotDistance
        closeLows       := closeRecentLows and closeOldLows

bool uptrendExhuastion   = closeHighs and priceHighTrend > 0 and npHighTrend < 0 and (not na(curnpHigh) or not na(curPriceHigh))
bool uptrendAbsorption   = closeHighs and priceHighTrend < 0 and npHighTrend > 0 and (not na(curnpHigh) or not na(curPriceHigh))
bool downtrendExhuastion = closeLows  and priceLowTrend  < 0 and npLowTrend  > 0 and (not na(curnpLow)  or not na(curPriceLow))
bool downtrendAbsorption = closeLows  and priceLowTrend  > 0 and npLowTrend  < 0 and (not na(curnpLow)  or not na(curPriceLow))

drawDiv(time1, price1, time2, price2, type) =>
    dcol = type == 'Uptrend Exhuastion' ? pHH_npLHcol : type == 'Uptrend Absorption' ? pLH_npHHcol : type == 'Downtrend Exhaustion' ? pLL_npHLcol : type == 'Downtrend Absorption' ? pHL_npLLcol : na
    line.new(x1=time1, y1=price1, x2=time2, y2=price2, color=dcol, width=1)

if uptrendAbsorption or uptrendExhuastion and showdiv
    highTime1  = array.get(npHighIndex, array.size(npHighIndex)-1)
    highPrice1 = array.get(npHigh,      array.size(npHigh)-1)
    highTime2  = array.get(npHighIndex, array.size(npHighIndex)-2)
    highPrice2 = array.get(npHigh,      array.size(npHigh)-2)
    if uptrendExhuastion and pHH_npLH
        drawDiv(highTime1, highPrice1, highTime2, highPrice2, 'Uptrend Exhuastion')
    if uptrendAbsorption and pLH_npHH
        drawDiv(highTime1, highPrice1, highTime2, highPrice2, 'Uptrend Absorption')

if downtrendAbsorption or downtrendExhuastion and showdiv
    lowTime1  = array.get(npLowIndex, array.size(npLowIndex)-1)
    lowPrice1 = array.get(npLow,      array.size(npLow)-1)
    lowTime2  = array.get(npLowIndex, array.size(npLowIndex)-2)
    lowPrice2 = array.get(npLow,      array.size(npLow)-2)
    if downtrendExhuastion and pLL_npHL
        drawDiv(lowTime1,  lowPrice1, lowTime2, lowPrice2, 'Downtrend Exhuastion')
    if downtrendAbsorption and pHL_npLL
        drawDiv(lowTime1,  lowPrice1, lowTime2, lowPrice2, 'Downtrend Absorption')
