High Volume Price Levels x3
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © noop42

//@version=5
indicator("High Volumes Price Levels", "HVPL", overlay=true)

vol_per_trigger = input.float(99.9, title="Volume level trigger (0.1 - 100.0)", minval=0.1, maxval=100.0)

period1 = input.int(100, title="Period #1", minval=1)
period2 = input.int(200, title="Period #2", minval=1)
period3 = input.int(500, title="Period #3", minval=1)

show_p1 = input.bool(true, "Show period #1")
show_p2 = input.bool(true, "Show period #2")
show_p3 = input.bool(true, "Show period #3")

lvl1_color = input.color(color.green, "Period #1 color")
lvl2_color = input.color(color.orange, "Period #2 color")
lvl3_color = input.color(color.red, "Period #3 color")

show_ghost_lines = input.bool(true, "Show 3rd period ghost lines")

current_levels_only = input.bool(false, "Show current levels only")

extend_level = input.string("Both", title="Extend last level", options=["Right", "Left", "Both", "None"])

find_last_high_volume(data, n) =>
    r = 0
    for i=0 to n
        if data[i] > vol_per_trigger
            r := i 
            break
    r

get_price_data(period) =>
    v = 100 * (volume / ta.highest(volume, period))
    f = find_last_high_volume(v, period)
    src = open[f] > close[f] ? low : high
    [v, f, src]

ext = extend_level == "Right" ? extend.right : extend_level == "Left" ? extend.left : extend_level == "Both" ? extend.both : extend.none

var line l1 = na
var line l2 = na
var line l3 = na

if show_p1
    [v1, f1, src1] = get_price_data(period1)
    if v1 > vol_per_trigger
        line.set_extend(l1, extend.none)
        line.set_color(l1, #a1a1a170)
        l1 := line.new(bar_index[1], src1[f1], bar_index, src1[f1], color=lvl1_color, style=line.style_solid, width=3, extend=ext)

if show_p2
    [v2, f2, src2] = get_price_data(period2)
    if v2 > vol_per_trigger
        line.set_extend(l2, extend.none)
        line.set_color(l2, #a1a1a170)
        l2 := line.new(bar_index[1], src2[f2], bar_index, src2[f2], color=lvl2_color, style=line.style_solid, width=3, extend=ext)

if show_p3
    [v3, f3, src3] = get_price_data(period3)
    if v3 > vol_per_trigger
        line.set_extend(l3, extend.none)
        if show_ghost_lines and not current_levels_only
            line.set_extend(l3, extend=extend.both)
        line.set_color(l3, #a1a1a170)
        l3 := line.new(bar_index[1], src3[f3], bar_index, src3[f3], color=lvl3_color, style=line.style_solid, width=3, extend=ext)

if not current_levels_only
    line.set_x2(l1, bar_index)
    line.set_x2(l2, bar_index)
    line.set_x2(l3, bar_index)