Expected Liquidity
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RickSimpson

//@version=5
indicator('Expected Liquidity', 'Expected Liquidity Range', true, max_lines_count=500, max_labels_count=500)

//Inputs

i_period        = input.int(25,         'Period',          minval=15, maxval=60,                      group='Expected Liquidity Settings')
i_linewidth     = input.int(2,          'Lines Size',      minval=1,   maxval=3,                      group='Expected Liquidity Settings', inline='style')
i_linestyle     = input.string('⎯⎯⎯', 'Lines Style',     options=['⎯⎯⎯', '····', '----'],         group='Expected Liquidity Settings', inline='style')
i_extend        = input.string('Right', 'Lines Extension', options=['Left', 'Right', 'Both', 'None'], group='Expected Liquidity Settings')
i_premiumcolor  = input(color.red,    'Premium Liquidity',                                          group='Expected Liquidity Settings', inline='colsetup')
i_discountcolor = input(color.green,  'Discount Liquidity',                                         group='Expected Liquidity Settings', inline='colsetup')

//Constants Variables Declaration

line premium  = (na)
line discount = (na)
highbar       = true
highfractal   = true
lowfractal    = true
closefractal  = true

//Lines Style String Function

f_i_linestyle(style) =>
    out = switch style
        '⎯⎯⎯'   => line.style_solid
        '----' => line.style_dashed
        '····' => line.style_dotted

//Lines Extension String Function

f_i_line_extend(extend) =>
    out = switch extend
        'Left'  => extend.left
        'Right' => extend.right
        'Both'  => extend.both
        'None'  => extend.none

//Pivots Definition

hb   = ta.highest(high, i_period)
lb   = ta.lowest(low,   i_period)
dist = hb - lb

//Premium Fibonacci Levels Calculation

hf  = hb - dist * 0.236
chf = hb - dist * 0.382

//Discount Fibonacci Levels Calculation

clf = hb - dist * 0.618
lf  = hb - dist * 0.764

//High/Low Fractals Scalling

pfractal            = high  >  hb[1]
dfractal            = low   <  lb[1]
premiumexpectstart  = hb[3] == hb[2] and hb[2] == hb[1] and pfractal
discountexpectstart = lb[3] == lb[2] and lb[2] == lb[1] and dfractal

//Liquidity Range Calculation

highexpect    = premiumexpectstart  or               high[1] == hb
lowexpect     = discountexpectstart or               low[1]  == lb
highbar      := highexpect ? true :      lowexpect ? false : highbar[1]
barexpin      = ta.crossover(close,            hf)
barexpout     = ta.crossunder(close,           hf)
highfractal  := barexpin   ? true :      barexpout ? false : highfractal[1]
fractexpin    = ta.crossunder(close,           lf)
fractexpout   = ta.crossover(close,            lf)
lowfractal   := fractexpin ? true :    fractexpout ? false : lowfractal[1]
closefractal := not highfractal and not lowfractal ? true  : false

//Drawing Calculation

stateislast  = barstate.islast
stateislast := barstate.isrealtime and timeframe.isintraday ? not barstate.isconfirmed : barstate.islast
hbdtrue      = stateislast and highfractal
lbdtrue      = stateislast and lowfractal
chfdtrue     = stateislast and closefractal and     highbar
clfdtrue     = stateislast and closefractal and not highbar

//Expected Liquidity Range Conditions

hbexpect  = hb
hbexpect := hbdtrue ? hb : lbdtrue ? lf : chfdtrue ? hf  : clfdtrue ? chf : na
lbexpect  = lb
lbexpect := hbdtrue ? hf : lbdtrue ? lb : chfdtrue ? clf : clfdtrue ? lf  : na

//Plotting

premium  := line.new(bar_index[1], hbexpect, bar_index, hbexpect, extend=f_i_line_extend(i_extend), color=i_premiumcolor,  style=f_i_linestyle(i_linestyle), width=i_linewidth)
discount := line.new(bar_index[1], lbexpect, bar_index, lbexpect, extend=f_i_line_extend(i_extend), color=i_discountcolor, style=f_i_linestyle(i_linestyle), width=i_linewidth)
line.delete(premium[1])
line.delete(discount[1])