[dharmatech] KBDR Mean Reversion
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © dharmatech

//@version=5
indicator(title = "KBDR Mean Reversion", shorttitle = "KBDR Mean Reversion", overlay = true)

// 2023-09-21 Updating permissions

// ----------------------------------------------------------------------
// bollinger bands
// ----------------------------------------------------------------------
length = input.int(20, minval=1)
src = input(close, title="Source")
mult = input.float(2.0, minval=0.001, maxval=50, title="StdDev")

basis = ta.sma(src, length)
dev = mult * ta.stdev(src, length)

bbands_upper = basis + dev
bbands_lower = basis - dev
// ----------------------------------------------------------------------
// keltner channels
// ----------------------------------------------------------------------

exp = input(true, "Use Exponential MA")
BandsStyle = input.string("Average True Range", options = ["Average True Range", "True Range", "Range"], title="Bands Style")
atrlength = input(10, "ATR Length")

esma(source, length)=>
	s = ta.sma(source, length)
	e = ta.ema(source, length)
	exp ? e : s

ma = esma(src, length)
rangema = BandsStyle == "True Range" ? ta.tr(true) : BandsStyle == "Average True Range" ? ta.atr(atrlength) : ta.rma(high - low, length)

kc_upper = ma + rangema * mult
kc_lower = ma - rangema * mult
// ----------------------------------------------------------------------

input_bbands_lower = input.float(defval = 0.98)
input_bbands_upper = input.float(defval = 1.02)

near_bbands_lower = low  * input_bbands_lower < bbands_lower		// is (low - 1%) < bbands_lower
near_bbands_upper = high * input_bbands_upper > bbands_upper
// ----------------------------------------------------------------------
// DI+ and DI-
// ----------------------------------------------------------------------

len = input(14)
th = input(20)

// TrueRange = max(max(high-low, abs(high-nz(close[1]))), abs(low-nz(close[1])))

TrueRange = math.max(math.max(high-low, math.abs(high-nz(close[1]))), math.abs(low-nz(close[1])))

DirectionalMovementPlus  = high       - nz(high[1]) > nz(low[1]) - low         ? math.max(high       - nz(high[1]), 0) : 0
DirectionalMovementMinus = nz(low[1]) - low         > high       - nz(high[1]) ? math.max(nz(low[1]) - low,         0) : 0

SmoothedTrueRange = 0.0
SmoothedTrueRange := nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1])/len) + TrueRange

SmoothedDirectionalMovementPlus = 0.0
SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - (nz(SmoothedDirectionalMovementPlus[1])/len) + DirectionalMovementPlus

SmoothedDirectionalMovementMinus = 0.0
SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1])/len) + DirectionalMovementMinus

DIPlus  = SmoothedDirectionalMovementPlus  / SmoothedTrueRange * 100
DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100

// ----------------------------------------------------------------------
// DI+ increasing
// DI- decreasing
// ----------------------------------------------------------------------

// bullish

di_plus_increasing  = DIPlus  > DIPlus[1]
di_minus_decreasing = DIMinus < DIMinus[1]

di_bullish = di_plus_increasing and di_minus_decreasing

// bearish

di_plus_decreasing  = DIPlus  < DIPlus[1]
di_minus_increasing = DIMinus > DIMinus[1]

di_bearish = di_plus_decreasing and di_minus_increasing

bbands_outside_keltner = 
     bbands_lower < kc_lower	and
     bbands_upper > kc_upper

// ----------------------------------------------------------------------
// RSI
// ----------------------------------------------------------------------

rsiLengthInput = input.int(14, minval=1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", 				 group="RSI Settings")

up   = ta.rma( math.max(ta.change(rsiSourceInput), 0), rsiLengthInput)
down = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput)

rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))

// ----------------------------------------------------------------------

rsi_increasing = rsi > rsi[1]
rsi_decreasing = rsi < rsi[1]

// rsi_near_bottom = rsi < 40
// rsi_near_top    = rsi > 60

input_rsi_near_bottom = input.float(defval = 40)
input_rsi_near_top    = input.float(defval = 60)

rsi_near_bottom = rsi < input_rsi_near_bottom   or   rsi[1] < input_rsi_near_bottom
rsi_near_top    = rsi > input_rsi_near_top      or   rsi[1] > input_rsi_near_top

// rsi_bullish = rsi_near_bottom and rsi_increasing
// rsi_bearish = rsi_near_top    and rsi_decreasing

rsi_big_increase = (rsi - rsi[1]) / rsi[1] >  0.19    // RSI increased 19%  
rsi_big_decrease = (rsi - rsi[1]) / rsi[1] < -0.19    // RSI decreased 19%  

rsi_bullish = (rsi_near_bottom and rsi_increasing)    or    rsi_big_increase
rsi_bearish = (rsi_near_top    and rsi_decreasing)    or    rsi_big_decrease

// ----------------------------------------------------------------------

bool bull_signal =
     bbands_outside_keltner		and
	 near_bbands_lower			and
	 di_bullish					and
	 rsi_bullish
	 
bool bear_signal =
     bbands_outside_keltner		and
	 near_bbands_upper			and
	 di_bearish					and
	 rsi_bearish
// ----------------------------------------------------------------------

bool bear_signal_di_bearish =
     bbands_outside_keltner		and
	 di_bearish					and
	 not bear_signal

bool bull_signal_di_bullish =
     bbands_outside_keltner		and
	 di_bullish					and
	 not bull_signal

// ----------------------------------------------------------------------
input_partial_1 = input.bool(defval = false, title = "Partial 1")
input_partial_2 = input.bool(defval = false, title = "Partial 2")
input_partial_3 = input.bool(defval = false, title = "Partial 3")
input_partial_4 = input.bool(defval = false, title = "Partial 4")

//plotchar(input_partial     and   not bbands_outside_keltner   and   not di_bearish   and   not rsi_bearish   and   not near_bbands_upper, "Short", "",  location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "")
plotchar(input_partial_1   and   not bbands_outside_keltner   and   not di_bearish   and   not rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B")
plotchar(input_partial_1   and   not bbands_outside_keltner   and   not di_bearish   and       rsi_bearish   and   not near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "R")
plotchar(input_partial_2   and   not bbands_outside_keltner   and   not di_bearish   and       rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B\nR")
plotchar(input_partial_1   and   not bbands_outside_keltner   and       di_bearish   and   not rsi_bearish   and   not near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "D")
plotchar(input_partial_2   and   not bbands_outside_keltner   and       di_bearish   and   not rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B\nD")
plotchar(input_partial_2   and   not bbands_outside_keltner   and       di_bearish   and       rsi_bearish   and   not near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "D\nR")
plotchar(input_partial_3   and   not bbands_outside_keltner   and       di_bearish   and       rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B\nD\nR")
plotchar(input_partial_1   and       bbands_outside_keltner   and   not di_bearish   and   not rsi_bearish   and   not near_bbands_upper, "Short", "",  location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\n")
plotchar(input_partial_2   and       bbands_outside_keltner   and   not di_bearish   and   not rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nB")
plotchar(input_partial_2   and       bbands_outside_keltner   and   not di_bearish   and       rsi_bearish   and   not near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nR")
plotchar(input_partial_3   and       bbands_outside_keltner   and   not di_bearish   and       rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nB\nR")
plotchar(input_partial_2   and       bbands_outside_keltner   and       di_bearish   and   not rsi_bearish   and   not near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nD")
plotchar(input_partial_3   and       bbands_outside_keltner   and       di_bearish   and   not rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nB\nD")
plotchar(input_partial_3   and       bbands_outside_keltner   and       di_bearish   and       rsi_bearish   and   not near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nD\nR")
plotchar(input_partial_4   and       bbands_outside_keltner   and       di_bearish   and       rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.red,      size = size.tiny, display = display.pane, text =    "K\nB\nD\nR")
plotchar(                            bbands_outside_keltner   and       di_bearish   and       rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.yellow,      size = size.tiny, display = display.pane)

// plotchar(    bbands_outside_keltner   and       di_bearish   and       rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.red,   size = size.tiny, text = "K\nB\nD\nR")
// plotchar(not bbands_outside_keltner   and       di_bearish   and       rsi_bearish   and       near_bbands_upper, "Short", "▼", location.abovebar, color = color.red,   size = size.tiny, text =    "B\nD\nR")

// ----------------------------------------------------------------------

// plotchar(input_partial     and   not bbands_outside_keltner   and   not di_bullish   and   not rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "")
plotchar(input_partial_1   and   not bbands_outside_keltner   and   not di_bullish   and   not rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B")
plotchar(input_partial_1   and   not bbands_outside_keltner   and   not di_bullish   and       rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "R")
plotchar(input_partial_2   and   not bbands_outside_keltner   and   not di_bullish   and       rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B\nR")
plotchar(input_partial_1   and   not bbands_outside_keltner   and       di_bullish   and   not rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "D")
plotchar(input_partial_2   and   not bbands_outside_keltner   and       di_bullish   and   not rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B\nD")
plotchar(input_partial_2   and   not bbands_outside_keltner   and       di_bullish   and       rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "D\nR")
plotchar(input_partial_3   and   not bbands_outside_keltner   and       di_bullish   and       rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "B\nD\nR")
plotchar(input_partial_1   and       bbands_outside_keltner   and   not di_bullish   and   not rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\n")
plotchar(input_partial_2   and       bbands_outside_keltner   and   not di_bullish   and   not rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nB")
plotchar(input_partial_2   and       bbands_outside_keltner   and   not di_bullish   and       rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nR")
plotchar(input_partial_3   and       bbands_outside_keltner   and   not di_bullish   and       rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nB\nR")
plotchar(input_partial_2   and       bbands_outside_keltner   and       di_bullish   and   not rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nD")
plotchar(input_partial_3   and       bbands_outside_keltner   and       di_bullish   and   not rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nB\nD")
plotchar(input_partial_3   and       bbands_outside_keltner   and       di_bullish   and       rsi_bullish   and   not near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,   size = size.tiny, display = display.pane, text =    "K\nD\nR")
plotchar(input_partial_4   and       bbands_outside_keltner   and       di_bullish   and       rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.green,    size = size.tiny, display = display.pane, text =    "K\nB\nD\nR")
plotchar(                            bbands_outside_keltner   and       di_bullish   and       rsi_bullish   and       near_bbands_lower, "Long", "▲", location.belowbar, color = color.yellow,    size = size.tiny, display = display.pane)
