Absorbing System Support and Resistance
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © only_fibonacci

//@version=5
indicator("Absorbing System", overlay = true, max_bars_back = 2000)



pivotLen = input.int(defval = 10, title = "PivotLEN", minval = 5, maxval = 10)
showBreakDown = input.bool(defval = false, title = "Show Breakdown")
sensitive = input.bool(defval = false, title = "Sensitive Breakdown")
isBox = input.bool( defval = false, title = "BOX ?", tooltip = "If box is right, line is closed")
ph = ta.pivothigh(pivotLen, pivotLen) == high[pivotLen]
pl = ta.pivotlow(pivotLen, pivotLen) == low[pivotLen]



varip indexes_r = array.new_int()
varip removed_r = array.new_int()

varip indexes_s = array.new_int()
varip removed_s = array.new_int()



// FUNC TRANSFORMATION
func(lineType)=>
    wickRes = high - math.max(open,close) 
    wickSup = math.min(close,open) - low
    body = math.abs(close - open)
    isRes = wickRes > wickSup //and open > close
    isSup = wickSup > wickRes
    cond = lineType == "RES" ? isRes and wickRes > body : isSup and wickSup > body
    resCond = lineType == "RES" ? ph and cond[pivotLen] : pl and cond[pivotLen]
    res_index = ta.valuewhen(resCond, bar_index, 0) - pivotLen 
    brokenCond = lineType == "RES" ? ta.crossover(high, high[bar_index - res_index]) : ta.crossunder(low, low[bar_index - res_index])
    indexes = lineType == "RES" ? indexes_r : indexes_s
    removed = lineType == "RES" ? removed_r : removed_s
    if resCond
        array.push(indexes,bar_index - pivotLen)
    if array.size(indexes) > 5
        array.remove(indexes,0)
    hORl = lineType == "RES" ? high : low
    cORo = lineType == "RES" ? math.max(open,close) : math.min(open,close)
    col = lineType == "RES" ? color.red : color.green
    sens = sensitive ? hORl : lineType == "RES" ? math.max(close,open) : math.min(open,close)
    if array.size(indexes) > 0
        for i = 0 to array.size(indexes) - 1 by 1
            index = array.get(indexes,i)
            inCond = lineType == "RES" ? sens[1] <= hORl[bar_index - index] and sens > hORl[bar_index - index] : sens[1] >= hORl[bar_index - index] and sens < hORl[bar_index - index]
            if inCond
                if isBox
                    box.new(index, hORl[bar_index - index], bar_index, cORo[bar_index - index], bgcolor = color.new(col,80), border_color = color.new(col,80))
                else
                    line.new(index, hORl[bar_index - index], bar_index, hORl[bar_index - index], color = col)
                
                array.push(removed,index)
                if showBreakDown
                    label.new(bar_index , sens[bar_index - index], text = "BREAKDOWN", color = color.new(col,80), style = lineType == "RES" ? label.style_label_up : label.style_label_down, textcolor = color.white)

        if barstate.islast
            for k = 0 to array.size(indexes) -1 by 1
                indexk = array.get(indexes,k)
                if isBox
                    box.new(indexk, hORl[bar_index - indexk], bar_index, cORo[bar_index - indexk], bgcolor = color.new(col,80), border_color = color.new(col,80))
                else
                    line.new(indexk, hORl[bar_index - indexk], bar_index, hORl[bar_index - indexk], color = col)

    if array.size(indexes) > 0 and array.size(removed) > 0
        for x = 0 to array.size(removed) - 1 by 1
            index_x = array.get(removed,x)
            indexof_i = array.indexof(indexes,index_x)
            if indexof_i >= 0
                array.remove(indexes,indexof_i)


func("RES")
func("SUP")



            






