Candle Strength Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © PtGambler

//@version=5
indicator(title='Candle Strength Indicator', shorttitle='[Pt] CSI')

ma_len = input.int(10, "MA period")
smooth_len = input.int(5, "Smoothing period")

ma_len2 = input.int(5, "Signal line MA period")
smooth_len2 = input.int(3, "Signal line Smoothing period")

lbR = input(2, title='Pivot Lookback Right', group = "Divergence - Pivot based")
lbL = input(5, title='Pivot Lookback Left', group = "Divergence - Pivot based")

rangeUpper = input(60, title='Max of Lookback Range', group = "Divergence - Pivot based")
rangeLower = input(5, title='Min of Lookback Range', group = "Divergence - Pivot based")
plotBull = input(false, title='Plot Bullish', group = "Divergence - Pivot based")
plotHiddenBull = input(false, title='Plot Hidden Bullish', group = "Divergence - Pivot based")
plotBear = input(false, title='Plot Bearish', group = "Divergence - Pivot based")
plotHiddenBear = input(false, title='Plot Hidden Bearish', group = "Divergence - Pivot based")

upBar = (high - open) / open * 10000 + (close - open) / open * 10000
downBar = (low - open) / open * 10000 + (close - open) / open * 10000

m = math.avg(upBar, downBar)
ma = ta.rma(m,ma_len)
ma_smoothed = ta.sma(ma, smooth_len)

ma2 = ta.rma(m,ma_len2)
ma_smoothed2 = ta.sma(ma2, smooth_len2)

hline(0, color=color.gray, linestyle=hline.style_dashed)

ma_plot = plot(ma_smoothed, title='CSI', color = ma_smoothed > 0  and ma_smoothed > ma_smoothed[1] ? color.green : ma_smoothed > 0 and ma_smoothed < ma_smoothed[1] ? color.new(color.green,50) : ma_smoothed < 0  and ma_smoothed < ma_smoothed[1] ? color.red : color.new(color.red,50) , style = plot.style_columns)
ma2_plot = plot(ma_smoothed2, title='CSI signal', color = ma_smoothed2 > 0 ? color.green : color.red, linewidth = 2, display = display.none)

//  Divergence (Pivot based) -------------------------------------------------------------
bearColor = color.red
bullColor = color.green
hiddenBullColor = color.new(color.green, 80)
hiddenBearColor = color.new(color.red, 80)
textColor = color.white
noneColor = color.new(color.white, 100)

plFound = na(ta.pivotlow(ma_smoothed, lbL, lbR)) ? false : true
phFound = na(ta.pivothigh(ma_smoothed, lbL, lbR)) ? false : true

_inRange(cond) =>
    bars = ta.barssince(cond == true)
    rangeLower <= bars and bars <= rangeUpper

//------------------------------------------------------------------------------
// Regular Bullish

// Osc: Higher Low
oscHL = ma_smoothed[lbR] > ta.valuewhen(plFound, ma_smoothed[lbR], 1) and _inRange(plFound[1])

// Price: Lower Low
priceLL = low[lbR] < ta.valuewhen(plFound, low[lbR], 1)

bullCond = plotBull and priceLL and oscHL and plFound

plot(plFound ? ma_smoothed[lbR] : na, offset=-lbR, title='Regular Bullish', linewidth=2, color=bullCond ? bullColor : noneColor)

plotshape(bullCond ? ma_smoothed[lbR] : na, offset=-lbR, title='Regular Bullish Label', text=' Bull ', style=shape.labelup, location=location.absolute, color=color.new(bullColor, 0), textcolor=color.new(textColor, 0))

//------------------------------------------------------------------------------
// Hidden Bullish

// Osc: Lower Low
oscLL = ma_smoothed[lbR] < ta.valuewhen(plFound, ma_smoothed[lbR], 1) and _inRange(plFound[1])

// Price: Higher Low
priceHL = low[lbR] > ta.valuewhen(plFound, low[lbR], 1)

hiddenBullCond = plotHiddenBull and priceHL and oscLL and plFound

plot(plFound ? ma_smoothed[lbR] : na, offset=-lbR, title='Hidden Bullish', linewidth=2, color=hiddenBullCond ? hiddenBullColor : noneColor)

plotshape(hiddenBullCond ? ma_smoothed[lbR] : na, offset=-lbR, title='Hidden Bullish Label', text=' H Bull ', style=shape.labelup, location=location.absolute, color=color.new(bullColor, 0), textcolor=color.new(textColor, 0))


//------------------------------------------------------------------------------
// Regular Bearish

// Osc: Lower High
oscLH = ma_smoothed[lbR] < ta.valuewhen(phFound, ma_smoothed[lbR], 1) and _inRange(phFound[1])

// Price: Higher High
priceHH = high[lbR] > ta.valuewhen(phFound, high[lbR], 1)

bearCond = plotBear and priceHH and oscLH and phFound

plot(phFound ? ma_smoothed[lbR] : na, offset=-lbR, title='Regular Bearish', linewidth=2, color=bearCond ? bearColor : noneColor)

plotshape(bearCond ? ma_smoothed[lbR] : na, offset=-lbR, title='Regular Bearish Label', text=' Bear ', style=shape.labeldown, location=location.absolute, color=color.new(bearColor, 0), textcolor=color.new(textColor, 0))

//------------------------------------------------------------------------------
// Hidden Bearish

// Osc: Higher High
oscHH = ma_smoothed[lbR] > ta.valuewhen(phFound, ma_smoothed[lbR], 1) and _inRange(phFound[1])

// Price: Lower High
priceLH = high[lbR] < ta.valuewhen(phFound, high[lbR], 1)

hiddenBearCond = plotHiddenBear and priceLH and oscHH and phFound

plot(phFound ? ma_smoothed[lbR] : na, offset=-lbR, title='Hidden Bearish', linewidth=2, color=hiddenBearCond ? hiddenBearColor : noneColor)

plotshape(hiddenBearCond ? ma_smoothed[lbR] : na, offset=-lbR, title='Hidden Bearish Label', text=' H Bear ', style=shape.labeldown, location=location.absolute, color=color.new(bearColor, 0), textcolor=color.new(textColor, 0))


