Compression support&resistance [LM]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © lmatl

//@version=5
indicator('Compression support&resistance [LM]', shorttitle='Compression S/R [LM]', overlay=true, max_bars_back=4990)

i_offsetVal = input.int(0, 'Label Offset', group='General settings')
i_showLabels = input.bool(true, 'Show Labels', group='General settings')
i_volumeFilter = input.bool(true, 'Volume filter', group='General settings')
i_volatilityFilter = input.bool(false, 'Volatility filter', group='General settings')
i_volatilityPercentage = input.int(5, 'Volatility percentage', group='General settings')
i_volatilityLookBackPeriod = input.int(5, 'volatility lookback period', group='General settings')

i_hideLines = input.bool(false, 'hide lines', group='current resolution S/R setting')
i_lineCount = input.int(10, 'line count', group='current resolution S/R setting')
i_candleHighColor = input.color(color.lime, 'candle high color', group='current resolutionS/R setting')
i_candleLowColor = input.color(color.maroon, 'candle low color', group='current resolutionS/R setting')
i_candleExtendLines = input.bool(true, 'extend lines', group='current resolutionS/R setting')
i_candleLineWidth = input.int(2, 'line width', minval=1, maxval=4, group='current resolutionS/R setting')

i_secondTimeFrame = input.timeframe('M', 'resolution', group='second S/R setting')
i_secondCandleHighColor = input.color(color.aqua, 'candle high color', group='second S/R setting')
i_secondCandleLowColor = input.color(color.blue, 'candle low color', group='second S/R setting')
i_secondCandleLineWidth = input.int(2, 'line width', minval=1, maxval=4, group='second S/R setting')
i_showSecondSR1 = input.bool(true, 'Show S/R 1', group='second S/R setting')
i_showSecondSR2 = input.bool(true, 'Show S/R 2', group='second S/R setting')
i_showSecondSR3 = input.bool(false, 'Show S/R 3', group='second S/R setting')
i_showSecondSR4 = input.bool(false, 'Show S/R 4', group='second S/R setting')


i_thirdTimeFrame = input.timeframe('W', 'resolution', group='third S/R setting')
i_thirdCandleHighColor = input.color(color.red, 'candle high color', group='third S/R setting')
i_thirdCandleLowColor = input.color(color.maroon, 'candle low color', group='third S/R setting')
i_thirdCandleLineWidth = input.int(2, 'line width', minval=1, maxval=4, group='third S/R setting')
i_showThirdSR1 = input.bool(true, 'Show S/R 1', group='third S/R setting')
i_showThirdSR2 = input.bool(true, 'Show S/R 2', group='third S/R setting')
i_showThirdSR3 = input.bool(false, 'Show S/R 3', group='third S/R setting')
i_showThirdSR4 = input.bool(false, 'Show S/R 4', group='third S/R setting')

i_fourthTimeFrame = input.timeframe('D', 'resolution', group='fourth S/R setting')
i_fourthCandleHighColor = input.color(color.lime, 'candle high color', group='fourth S/R setting')
i_fourthCandleLowColor = input.color(color.olive, 'candle low color', group='fourth S/R setting')
i_fourthCandleLineWidth = input.int(2, 'line width', minval=1, maxval=4, group='fourth S/R setting')
i_showFourthSR1 = input.bool(false, 'Show S/R 1', group='fourth S/R setting')
i_showFourthSR2 = input.bool(false, 'Show S/R 2', group='fourth S/R setting')
i_showFourthSR3 = input.bool(false, 'Show S/R 3', group='fourth S/R setting')
i_showFourthSR4 = input.bool(false, 'Show S/R 4', group='fourth S/R setting')

// functions


f_drawLine(_x1, _x2, _yValue, _lineColor, _style, _width) =>
    line.new(x1=_x1, y1=_yValue, x2=_x2, y2=_yValue, color=_lineColor, style=_style, width=_width)

f_extendArray(_lineArray, _extendLines) =>
    if array.size(_lineArray) > 0
        for _i = array.size(_lineArray) - 1 to 0 by 1

            x2 = line.get_x2(array.get(_lineArray, _i))
            yValue = line.get_y1(array.get(_lineArray, _i))

            if _extendLines or bar_index - 1 == x2 and not(high >= yValue and low <= yValue)
                line.set_x2(array.get(_lineArray, _i), bar_index)

f_barssince(_cond, _count) =>
    _barssince = bar_index - ta.valuewhen(_cond, bar_index, _count)
    _barssince

f_compressionCondition(_isVolumeFilter) =>
    c1 = high[2] >= high[1] and low[2] <= low[1]
    c2 = high[1] >= high and low[1] <= low

    volumeCond = volume[2] > volume[1] and volume[1] > volume

    isPercentageChangeEnough = false
    for i = 0 to i_volatilityLookBackPeriod - 1 by 1
        if (low[i] - close) / close >= i_volatilityPercentage / 100 or (high[i] - close) / close >= i_volatilityPercentage / 100
            isPercentageChangeEnough := true
            break

    isCond = c1 and c2 and (_isVolumeFilter ? volumeCond : true) and (i_volatilityFilter ? isPercentageChangeEnough : true)
    isCond

f_mutitimeframeCompressionCondition(_isVolumeFilter, _occurence) =>
    c1 = high[2] >= high[1] and low[2] <= low[1]
    c2 = high[1] >= high and low[1] <= low

    volumeCond = volume[2] > volume[1] and volume[1] > volume

    isPercentageChangeEnough = false
    for i = 0 to i_volatilityLookBackPeriod - 1 by 1
        if (low[i] - close) / close >= i_volatilityPercentage / 100 or (high[i] - close) / close >= i_volatilityPercentage / 100
            isPercentageChangeEnough := true
            break

    isCond = c1 and c2 and (_isVolumeFilter ? volumeCond : true) and (i_volatilityFilter ? isPercentageChangeEnough : true)
    index = f_barssince(isCond, _occurence)

    compressionHigh = na(index) ? na : high[index + 1]
    compressionLow = na(index) ? na : low[index + 1]

    [compressionHigh, compressionLow]

f_drawLabel(_yValue, _xValue, _labelColor, _text, _showLabels) =>
    var label lb = na
    label.delete(lb)

    if _showLabels and not na(_yValue)
        lb := label.new(x=_xValue, y=_yValue, text=_text, textcolor=_labelColor, style=label.style_none, xloc=xloc.bar_time, yloc=yloc.price)
        lb
    lb

isCond = f_compressionCondition(i_volumeFilter)

// array init
var lineArray = array.new_line()

float yValue = na
int x1 = na
int x2 = na
line l = na

// current timeframe
if isCond and not i_hideLines
    yValue := high[1]
    x1 := bar_index[1]
    x2 := bar_index
    l := f_drawLine(x1, x2, yValue, i_candleHighColor, line.style_dotted, i_candleLineWidth)
    if array.size(lineArray) == i_lineCount
        line.delete(array.shift(lineArray))
    array.push(lineArray, l)

    yValue := low[1]
    l := f_drawLine(x1, x2, yValue, i_candleLowColor, line.style_dotted, i_candleLineWidth)
    if array.size(lineArray) == i_lineCount
        line.delete(array.shift(lineArray))
    array.push(lineArray, l)

f_extendArray(lineArray, i_candleExtendLines)

// other time frames
diffTime = na(time[1]) ? time : math.min(time, time - time[1])
firstValue = time + diffTime * (i_offsetVal + 30)
secondValue = time + diffTime * (i_offsetVal + 60)
thirdValue = time + diffTime * (i_offsetVal + 90)

// Second timeframe
[secondH1, secondL1] = request.security(syminfo.tickerid, i_secondTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 0))
[secondH2, secondL2] = request.security(syminfo.tickerid, i_secondTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 1))
[secondH3, secondL3] = request.security(syminfo.tickerid, i_secondTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 2))
[secondH4, secondL4] = request.security(syminfo.tickerid, i_secondTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 3))

plot(i_showSecondSR1 ? secondH1 : na, title='Second High 1', linewidth=2, color=i_secondCandleHighColor, show_last=1, trackprice=true)
plot(i_showSecondSR1 ? secondL1 : na, title='Second Low 1', linewidth=2, color=i_secondCandleLowColor, show_last=1, trackprice=true)
plot(i_showSecondSR2 ? secondH2 : na, title='Second High 2', linewidth=2, color=i_secondCandleHighColor, show_last=1, trackprice=true)
plot(i_showSecondSR2 ? secondL2 : na, title='Second Low 2', linewidth=2, color=i_secondCandleLowColor, show_last=1, trackprice=true)
plot(i_showSecondSR3 ? secondH3 : na, title='Second High 3', linewidth=2, color=i_secondCandleHighColor, show_last=1, trackprice=true)
plot(i_showSecondSR3 ? secondL3 : na, title='Second Low 3', linewidth=2, color=i_secondCandleLowColor, show_last=1, trackprice=true)
plot(i_showSecondSR4 ? secondH4 : na, title='Second High 4', linewidth=2, color=i_secondCandleHighColor, show_last=1, trackprice=true)
plot(i_showSecondSR4 ? secondL4 : na, title='Second Low 4', linewidth=2, color=i_secondCandleLowColor, show_last=1, trackprice=true)

f_drawLabel(secondH1, firstValue, i_secondCandleHighColor, i_secondTimeFrame + ' High 1', i_showSecondSR1 and i_showLabels)
f_drawLabel(secondL1, firstValue, i_secondCandleLowColor, i_secondTimeFrame + ' Low 1', i_showSecondSR1 and i_showLabels)
f_drawLabel(secondH2, firstValue, i_secondCandleHighColor, i_secondTimeFrame + ' High 2', i_showSecondSR2 and i_showLabels)
f_drawLabel(secondL2, firstValue, i_secondCandleLowColor, i_secondTimeFrame + ' Low 2', i_showSecondSR2 and i_showLabels)
f_drawLabel(secondH3, firstValue, i_secondCandleHighColor, i_secondTimeFrame + ' High 3', i_showSecondSR3 and i_showLabels)
f_drawLabel(secondL3, firstValue, i_secondCandleLowColor, i_secondTimeFrame + ' Low 3', i_showSecondSR3 and i_showLabels)
f_drawLabel(secondH4, firstValue, i_secondCandleHighColor, i_secondTimeFrame + ' High 4', i_showSecondSR4 and i_showLabels)
f_drawLabel(secondL4, firstValue, i_secondCandleLowColor, i_secondTimeFrame + 'Low 4', i_showSecondSR4 and i_showLabels)

// Third timeframe
[thirdH1, thirdL1] = request.security(syminfo.tickerid, i_thirdTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 0))
[thirdH2, thirdL2] = request.security(syminfo.tickerid, i_thirdTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 1))
[thirdH3, thirdL3] = request.security(syminfo.tickerid, i_thirdTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 2))
[thirdH4, thirdL4] = request.security(syminfo.tickerid, i_thirdTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 3))

plot(i_showThirdSR1 ? thirdH1 : na, title='Third High 1', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleHighColor, show_last=1, trackprice=true)
plot(i_showThirdSR1 ? thirdL1 : na, title='Third Low 1', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleLowColor, show_last=1, trackprice=true)
plot(i_showThirdSR2 ? thirdH2 : na, title='Third High 2', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleHighColor, show_last=1, trackprice=true)
plot(i_showThirdSR2 ? thirdL2 : na, title='Third Low 2', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleLowColor, show_last=1, trackprice=true)
plot(i_showThirdSR3 ? thirdH3 : na, title='Third High 3', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleHighColor, show_last=1, trackprice=true)
plot(i_showThirdSR3 ? thirdL3 : na, title='Third Low 3', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleLowColor, show_last=1, trackprice=true)
plot(i_showThirdSR4 ? thirdH4 : na, title='Third High 4', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleHighColor, show_last=1, trackprice=true)
plot(i_showThirdSR4 ? thirdL4 : na, title='Third Low 4', linewidth=i_thirdCandleLineWidth, color=i_thirdCandleLowColor, show_last=1, trackprice=true)

f_drawLabel(thirdH1, secondValue, i_thirdCandleHighColor, i_thirdTimeFrame + ' High 1', i_showThirdSR1 and i_showLabels)
f_drawLabel(thirdL1, secondValue, i_thirdCandleLowColor, i_thirdTimeFrame + ' Low 1', i_showThirdSR1 and i_showLabels)
f_drawLabel(thirdH2, secondValue, i_thirdCandleHighColor, i_thirdTimeFrame + ' High 2', i_showThirdSR2 and i_showLabels)
f_drawLabel(thirdL2, secondValue, i_thirdCandleLowColor, i_thirdTimeFrame + ' Low 2', i_showThirdSR2 and i_showLabels)
f_drawLabel(thirdH3, secondValue, i_thirdCandleHighColor, i_thirdTimeFrame + ' High 3', i_showThirdSR3 and i_showLabels)
f_drawLabel(thirdL3, secondValue, i_thirdCandleLowColor, i_thirdTimeFrame + ' Low 3', i_showThirdSR3 and i_showLabels)
f_drawLabel(thirdH4, secondValue, i_thirdCandleHighColor, i_thirdTimeFrame + ' High 4', i_showThirdSR4 and i_showLabels)
f_drawLabel(thirdL4, secondValue, i_thirdCandleLowColor, i_thirdTimeFrame + ' Low 4', i_showThirdSR4 and i_showLabels)


// Fourth timeframe
[fourthH1, fourthL1] = request.security(syminfo.tickerid, i_fourthTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 0))
[fourthH2, fourthL2] = request.security(syminfo.tickerid, i_fourthTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 1))
[fourthH3, fourthL3] = request.security(syminfo.tickerid, i_fourthTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 2))
[fourthH4, fourthL4] = request.security(syminfo.tickerid, i_fourthTimeFrame, f_mutitimeframeCompressionCondition(i_volumeFilter, 3))

plot(i_showFourthSR1 ? fourthH1 : na, title='Fourth High 1', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleHighColor, show_last=1, trackprice=true)
plot(i_showFourthSR1 ? fourthL1 : na, title='Fourth Low 1', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleLowColor, show_last=1, trackprice=true)
plot(i_showFourthSR2 ? fourthH2 : na, title='Fourth High 2', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleHighColor, show_last=1, trackprice=true)
plot(i_showFourthSR2 ? fourthL2 : na, title='Fourth Low 2', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleLowColor, show_last=1, trackprice=true)
plot(i_showFourthSR3 ? fourthH3 : na, title='Fourth High 3', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleHighColor, show_last=1, trackprice=true)
plot(i_showFourthSR3 ? fourthL3 : na, title='Fourth Low 3', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleLowColor, show_last=1, trackprice=true)
plot(i_showFourthSR4 ? fourthH4 : na, title='Fourth High 4', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleHighColor, show_last=1, trackprice=true)
plot(i_showFourthSR4 ? fourthL4 : na, title='Fourth Low 4', linewidth=i_fourthCandleLineWidth, color=i_fourthCandleLowColor, show_last=1, trackprice=true)

f_drawLabel(fourthH1, thirdValue, i_fourthCandleHighColor, i_fourthTimeFrame + ' High 1', i_showFourthSR1 and i_showLabels)
f_drawLabel(fourthL1, thirdValue, i_fourthCandleLowColor, i_fourthTimeFrame + ' Low 1', i_showFourthSR1 and i_showLabels)
f_drawLabel(fourthH2, thirdValue, i_fourthCandleHighColor, i_fourthTimeFrame + ' High 2', i_showFourthSR2 and i_showLabels)
f_drawLabel(fourthL2, thirdValue, i_fourthCandleLowColor, i_fourthTimeFrame + ' Low 2', i_showFourthSR2 and i_showLabels)
f_drawLabel(fourthH3, thirdValue, i_fourthCandleHighColor, i_fourthTimeFrame + ' High 3', i_showFourthSR3 and i_showLabels)
f_drawLabel(fourthL3, thirdValue, i_fourthCandleLowColor, i_fourthTimeFrame + ' Low 3', i_showFourthSR3 and i_showLabels)
f_drawLabel(fourthH4, thirdValue, i_fourthCandleHighColor, i_fourthTimeFrame + ' High 4', i_showFourthSR4 and i_showLabels)
f_drawLabel(fourthL4, thirdValue, i_fourthCandleLowColor, i_fourthTimeFrame + ' Low 4', i_showFourthSR4 and i_showLabels)

