Liquidity Peaks
// 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("Liquidity Peaks", "{Ʌ} - 𝐋𝐢𝐪. 𝐏𝐞𝐚𝐤𝐬", true)

// up or down candle
red_candle = (close < open)
green_candle = (close > open)


//inputs
lookback = input.int(55,"Lookback",tooltip = "More lookback = more reacting zone, less lookback = less reacting zone",group = "Inputs")
src = input.string("Open","Source",["Body","Full","Open","Close"],group = "Inputs")
col = input.color(#bbd9fb,"Liquidity Color",group = "Color")
col_2 = input.color(color.gray,"Liquidity Formed Color",group = "Color")
col_3 = input.color(#e65100,"Liquidity Swipe",group = "Color")
extd = input.bool(false,"Display Origin Point",group = "UI Options")
mult = input.int(2,"Multiplier",tooltip = "Add weight to the future bar",group = "Inputs",minval = 1)
adjustment = input.bool(true,"Adjust Liquidity Grab",group = "UI Options")
text_c = input.color(color.rgb(238, 255, 0),title = "Volume Text Color",group = "Color")



//variables
vol = close > open ? volume : -volume
var data = array.new<float>(lookback)
var current_index = 0
var float max_vol = 0
index = 0


// main calculation
current_index += 1
array.push(data,vol)

if current_index == lookback + 1
    array.clear(data)
    current_index   := 0
    max_vol         := 0

if current_index == lookback
    max_vol := array.max(data)
    index   := array.indexof(data,array.max(data))


draw_swipe(left,top,right,bottom) =>
    var box bx = na
    bx_col     = color.new(col_3,0)
    bx        := box.new(left,top,right,bottom,border_color =  color.new(bx_col,100),bgcolor = color.new(bx_col,50))


draw_box(left,top,right,bottom) =>
    var box bx = na
    bx_col     = color.new(col_2,80)
    bx        := box.new(left,top,right,bottom,border_color =  color.new(bx_col,100),bgcolor = color.new(bx_col,90))

draw_volume(left,top,right,bottom) =>
    var box bx = na
    bx_col     = color.new(col,50)
    bx        := box.new(left,top,right,bottom,bgcolor = color.new(bx_col,66),border_color = color.new(color.yellow,100),text = str.tostring(math.round(max_vol)) + " K",text_halign = text.align_right,text_color = text_c,text_size = size.auto)



var float top    = na
var float bottom = na

if current_index == lookback
    top := switch src
        "Open" =>   red_candle[lookback] ? high[current_index]  :  open[current_index]
        "Body" =>   red_candle[lookback] ? open[current_index]  :  close[current_index]
        "Close" =>  red_candle[lookback] ? close[current_index] :  high[current_index]
        "Full" => high[current_index]

    bottom := switch src
        "Open" =>   red_candle[lookback] ? open[current_index]  : low[current_index]
        "Body" =>   red_candle[lookback] ? close[current_index] : open[current_index]
        "Close" =>  red_candle[lookback] ? low[current_index]   : close[current_index]
        "Full" => low[current_index]


if current_index == lookback
    if adjustment
        top := switch src
            "Open" =>    red_candle[lookback] ? high[current_index] + math.abs(open[current_index]-high[current_index]) : low[current_index]
            "Close" =>   red_candle[lookback] ? low[current_index]                                                      : high[current_index] + math.abs(close[current_index] - high[current_index])
            "Body" =>    red_candle[lookback] ? open[current_index]                                                     : close[current_index]
            "Full" =>    high[current_index]

        bottom := switch src
            "Open" =>   red_candle[lookback] ? high[current_index]                                                      : low[current_index] - math.abs(open[current_index]-low[current_index])
            "Close" =>  red_candle[lookback] ? low[current_index] - math.abs(close[current_index] - low[current_index]) : high[current_index]
            "Body" =>   red_candle[lookback] ? close[current_index]                                                     : open[current_index]
            "Full" =>   low[current_index]


    num = lookback * mult
    back = extd == true ? current_index : 0 
    
    if adjustment == false
        draw_box(   bar_index - back - 1, high[current_index + 1],bar_index + num, low[current_index + 1])
        draw_volume(bar_index - back    , top                    ,bar_index + num, bottom)

        if ta.crossover(high, top)
            swipe_bottom = red_candle ? low : close
            swipe_top = red_candle ? close : high
            draw_swipe(bar_index,swipe_top,bar_index + current_index * mult,swipe_bottom)

        if ta.crossunder(low, bottom)
            swipe_bottom = red_candle ? low : close
            swipe_top = red_candle ? close : high
            draw_swipe(bar_index,swipe_top,bar_index + current_index * mult,swipe_bottom)


    if adjustment == true
        top_b =     high[current_index]
        bottom_b =  low[current_index]

        draw_box(   bar_index - back, top_b, bar_index + num,bottom_b)
        draw_volume(bar_index - back, top , bar_index + num, bottom)

        if ta.crossover(high, top_b)
            swipe_bottom = red_candle ? low : close
            swipe_top = red_candle ? close : high
            draw_swipe(bar_index,swipe_top,bar_index + current_index * mult,swipe_bottom)

        if ta.crossunder(low, bottom_b)
            swipe_bottom = red_candle ? low : close
            swipe_top = red_candle ? close : high
            draw_swipe(bar_index,swipe_top,bar_index + current_index * mult,swipe_bottom)