Liquidity Channel with B/S
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © atnx


//@version=5
indicator("Liquidity Channel with B/S", overlay = true, shorttitle = "Liq Chan B/S")

// 1. Indicator - Liquidity Level
source = close
length = 14
mult = 1.0
lowestLow = ta.lowest(low, length)
highestHigh = ta.highest(high, length)
rng = highestHigh - lowestLow
averagerng = ta.sma(rng, length)
middleLine = lowestLow + rng / 2
upperLine = middleLine + mult * averagerng
lowerLine = middleLine - mult * averagerng

liquidityLevel = (upperLine + lowerLine) / 2
liquidityLevelDist = (upperLine - lowerLine) / 2
sellSide = liquidityLevel + (liquidityLevelDist / 2)
buySide = liquidityLevel - (liquidityLevelDist / 2)

liquidityBuyCondition = close < buySide
liquiditySellCondition = close > sellSide
plot(sellSide,'UpperLiquidity', color=color.rgb(250, 0, 0))
plot(buySide,'LowerLiquidity', color=#006cc4)

// 2. Indicator - D-BoT Alpha Reversals 
ROCLength = 20
RSILength = 14
osg = 50
obg = 50
Extremities = 0.5
xPrice = close
nRes = ta.rsi(ta.roc(xPrice, ROCLength), RSILength)
maxrsi = 21
minrsi = 7

// Signal triggering
var FiredSignal = false
var CooledSignal = false

N = maxrsi - minrsi + 1
z = nz(xPrice - xPrice[1])
var X = array.new_float(N, 0)
var Y = array.new_float(N, 0)

t = 0
o = 0
s = 0
avg = 0.
for i = minrsi to maxrsi
    alpha = 1 / i

    X_rma = alpha * z + (1 - alpha) * array.get(X, t)
    Y_rma = alpha * math.abs(z) + (1 - alpha) * array.get(Y, t)
    rsi = 50 * X_rma / Y_rma + 50
    avg := avg + rsi

    o := rsi > osg ? o + 1 : o
    s := rsi < obg ? s + 1 : s

    array.set(X, t, X_rma)
    array.set(Y, t, Y_rma)
    t := t + 1

v_rs = avg / N

overboughtCondition = nRes > osg and v_rs > osg and math.abs(nRes - v_rs) <= Extremities
oversoldCondition = nRes < obg and v_rs < obg and math.abs(nRes - v_rs) <= Extremities

if (overboughtCondition and not FiredSignal)
    if (close < open) // red bar
        FiredSignal := true

if (oversoldCondition and not CooledSignal)
    if (close > open) // green bar
        CooledSignal := true

if (not overboughtCondition)
    FiredSignal := false

if (not oversoldCondition)
    CooledSignal := false

// Combined conditions
buyCondition = liquidityBuyCondition and CooledSignal
sellCondition = liquiditySellCondition and FiredSignal

// Plot signals
plotshape(buyCondition, title = "Buy", style = shape.labelup, location = location.belowbar, color = color.new(color.green, 0), text='Buy', textcolor=color.white, size = size.tiny)
plotshape(sellCondition, title = "Sell", style = shape.labeldown, location = location.abovebar, color = color.new(color.red, 0), text='Sell', textcolor=color.white, size = size.tiny)
barcolor(color=color.gray,title='BarColorPref:')
// Alerts
alertcondition(buyCondition, title='Buy', message='Buy!')
alertcondition(sellCondition, title='Sell', message='Sell!')
