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

//@version=4
study("Levels High Low", shorttitle="Levels High Low", overlay=true, max_bars_back = 5000, max_lines_count = 500, max_labels_count = 500)

lenH = input(title="Length High", type=input.integer, defval=20, minval=1)
lenL = input(title="Length Low", type=input.integer, defval=20, minval=1)
var high_label = array.new_label()
var low_label = array.new_label()
var high_array_lines = array.new_line()
var low_array_lines = array.new_line()
var high_line = close
var low_line = close


fun(src, len, isHigh, _style, _yloc, _color, array_label, array_lines) =>
    p = nz(src[len])
    isFound = true
    for i = 0 to len - 1
        if isHigh and src[i] > p
            isFound := false

        if not isHigh and src[i] < p
            isFound := false

    for i = len + 1 to 2 * len
        if isHigh and src[i] >= p
            isFound := false

        if not isHigh and src[i] <= p
            isFound := false
    
    if isFound 
        array.push(array_label, label.new(bar_index[len], p, tostring(p), style=_style, yloc=_yloc, color=_color))
        array.push(array_lines, line.new(bar_index[len], p, bar_index, p, color=_color, extend=extend.right))
        if array.size(array_label) > 1 
            for i = 1 to array.size(array_label) - 1
                if label.get_y(array.get(array_label, array.size(array_label) - 1)) > label.get_y(array.get(array_label, i - 1)) and src == high
                    label.delete(array.get(array_label, i - 1))
                    line.delete(array.get(array_lines, i - 1))
                if label.get_y(array.get(array_label, array.size(array_label) - 1)) < label.get_y(array.get(array_label, i - 1)) and src == low
                    label.delete(array.get(array_label, i - 1))
                    line.delete(array.get(array_lines, i - 1))
                    
    if array.size(array_label) > 1 
        if label.get_y(array.get(array_label, array.size(array_label) - 1)) < high and src == high
            label.delete(array.get(array_label, array.size(array_label) - 1))
            line.delete(array.get(array_lines, array.size(array_label) - 1))
        if label.get_y(array.get(array_label, array.size(array_label) - 1)) > low and src == low
            label.delete(array.get(array_label, array.size(array_label) - 1))
            line.delete(array.get(array_lines, array.size(array_label) - 1))


fun(high, lenH, true, label.style_label_down, yloc.abovebar, color.lime, high_label, high_array_lines)
fun(low, lenL, false, label.style_label_up, yloc.belowbar, color.red, low_label, low_array_lines)