RSI + Divergences + Alerts [MisterMoTA]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// @author  = MisterMoTA
// © MisterMoTA

//@version=5
indicator(title="RSI + Divergences + Alerts [MisterMoTA]", format=format.price)

len = input.int(title="RSI Period", minval=1, defval=14, group="RSI Settings")
src = input(title="RSI Source", defval=close, group="RSI Settings")

overBought = input.int(title="RSI Overbought", minval=60, defval=70, group="RSI Settings")
obXLevel  = input.int(title="RSI Extreme Overbought", minval=70, defval=80, group="RSI Settings")
overSold = input.int(title="RSI Oversold", maxval=40, defval=30, group="RSI Settings")
osXLevel  = input.int(title="RSI Extreme Oversold", maxval=30, defval=20, group="RSI Settings")

maTypeInput = input.string("WMA", title="MA Type", options=["SMA", "EMA", "RMA", "WMA"], group="MA Settings")
maLengthInput = input.int(14, title="MA Length", group="MA Settings")

emaBullColor = input(#00ff77, "Ema Rising Color", group="MA Settings", inline="Rising")
emaBearColor = input(#fc0202, "EMA Falling Color", group="MA Settings", inline="Falling")

showFill = input.bool(false, title="Fill the Rsi and Moving Average ?", group="RSI FILL")

col_grow_above = input(#26A69A, "Above Grow", group="RSI FILL", inline="Above")
col_fall_above = input(#B2DFDB, "Fall", group="RSI FILL", inline="Above")
col_grow_below = input(#FFCDD2, "Below Grow", group="RSI FILL", inline="Below")
col_fall_below = input(#FF5252, "Fall", group="RSI FILL", inline="Below")


lbR = input(title="Pivots to Lookback Right", defval=5, group="Divergences Settings")
lbL = input(title="Pivots to Lookback Left", defval=5, group="Divergences Settings")
rangeUpper = input(title="Max of Lookback Range", defval=60, group="Divergences Settings")
rangeLower = input(title="Min of Lookback Range", defval=5, group="Divergences Settings")

plotBull = input(title="Plot Bullish", defval=true, group="Divergences Settings")
plotHiddenBull = input(title="Plot Hidden Bullish", defval=true, group="Divergences Settings")
plotBear = input(title="Plot Bearish", defval=true, group="Divergences Settings")
plotHiddenBear = input(title="Plot Hidden Bearish", defval=true, group="Divergences Settings")

bearColor = input(#fc0202, "Bearish", group="Divergences colors", inline="Bear")
hiddenBearColor = input(#ffea00, "Hidden Bearish", group="Divergences colors", inline="Bear")

bullColor = input(#01820a, "Bullish", group="Divergences colors", inline="Bull")
hiddenBullColor =input(#001dfc, "Hidden Bulliish", group="Divergences colors", inline="Bull")


textColor = color.white
noneColor = color.new(color.white, 100)



txtcol_grow_above = input(#1a7b24, "Above   Grow", group="Trend labels colors", inline="Above")
txtcol_fall_above = input(#672ec5, "Fall", group="Trend labels colors", inline="Above")
txtcol_grow_below = input(#F37121, "Below Grow", group="Trend labels colors", inline="Below")
txtcol_fall_below = input(#be0606, "Fall", group="Trend labels colors", inline="Below")

h0 = hline(0, title="Zero lime", color=#00000000)
h100 = hline(100, title="100 line", color=#00000000)
h40 = hline(40, title="Bearish line", color=col_fall_below)
h60 = hline(60, title="Bullish line", color=col_grow_above)
hline(50, title="Middle Line", color=#e78114a0, linestyle=hline.style_dashed)
obLevel = hline(80, title="Overbought", color=color.rgb(4, 214, 50, 90), linestyle=hline.style_dotted)

osLevel = hline(20, title="Oversold", color=color.rgb(243, 33, 100, 90), linestyle=hline.style_dotted)
ma(source, length, type) =>
    switch type
        "RMA" => ta.rma(source, length)
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "WMA" => ta.wma(source, length)


rsi = ta.rsi(src, len)

rsi2 = ta.rsi(src,2)
rsi5 = ta.rsi(src,5)

rsiMA = ma(rsi, maLengthInput, maTypeInput)


rsiMaColor = rsiMA >=rsiMA[1] ? emaBullColor : emaBearColor 


hfill = (rsi > overBought) ? (rsi > overBought and rsi < obXLevel ? color.new(color.red,85) : #FF286858): (rsi < overSold) ? (rsi > osXLevel ? color.new(color.teal, 85) :  rsi < osXLevel ? color.new(color.teal, 75) : na):na

fill(h0,h100, title="OB/OS Background", color=hfill)

fill(obLevel, h60, title="RSI Bullish Zone Background", color=color.new(color.teal, 85))
//fill(h40, h60, title="RSI Bearish Zone Background", color=color.rgb(1, 4, 45))
fill(osLevel, h40, title="RSI Background", color=color.rgb(255, 5, 84, 85))


fillColor = rsi > rsiMA and rsi >= rsi[1] ? col_grow_above : rsi > rsiMA and rsi < rsi[1]   ? col_fall_above: rsi < rsiMA and rsi < rsi[1]  ? col_fall_below : rsi < rsiMA and rsi >= rsi[1] ? col_grow_below : na

fillColor2 = rsi2 > rsiMA and rsi2 >= rsi2[1] ? col_grow_above : rsi2 > rsiMA and rsi2 < rsi2[1]   ? col_fall_above: rsi2 < rsiMA and rsi2 < rsi2[1]  ? col_fall_below : rsi2 < rsiMA and rsi2 >= rsi2[1] ? col_grow_below : na

fillColor5 = rsi5 > rsiMA and rsi5 >= rsi5[1] ? col_grow_above : rsi5 > rsiMA and rsi5 < rsi5[1]   ? col_fall_above: rsi5 < rsiMA and rsi5 < rsi5[1]  ? col_fall_below : rsi5 < rsiMA and rsi5 >= rsi5[1] ? col_grow_below : na

srsi = plot(rsi, title="RSI ", linewidth=4, color=fillColor)

fastRsi = plot(rsi2, title="RSI 2", linewidth=1, color=fillColor2)

medRsi = plot(rsi5, title="RSI 5", linewidth=2, color=fillColor5)

maPlot= plot(rsiMA , title="RSI MA", linewidth=3, color=rsiMaColor)


fill(srsi,maPlot, title="RSI/MA Fill Background", color=showFill == true ? fillColor: color.rgb(255, 255, 255, 100))



rsiText=(rsi > 50 ? (rsi >rsi[1]? " RSI  > 50 and ▲ Growing,  RSI = " + str.tostring(rsi[0], "#.##") :" RSI > 50 and ▼ Falling, RSI = " + str.tostring(rsi[0], "#.##") ) : (rsi > rsi[1] ? "RSI < 50 and ▲ Growing, RSI = " + str.tostring(rsi[0], "#.##"): " RSI < 50 and ▼ Falling, RSI = " + str.tostring(rsi[0], "#.##")))


oneDay = 24 * 60 * 60 * 1000
barsAhead = 3
tmf = if timeframe.ismonthly
    barsAhead * oneDay * 30
else if timeframe.isweekly
    barsAhead * oneDay * 7
else if timeframe.isdaily
    barsAhead * oneDay
else if timeframe.isminutes
    barsAhead * oneDay * timeframe.multiplier / 1440
else if timeframe.isseconds
    barsAhead * oneDay * timeframe.multiplier / 86400
else
    0
  

angle(_src) =>
    rad2degree = 180 / 3.14159265359  //pi 
    ang = rad2degree * math.atan((_src[0] - _src[1]) / ta.atr(14))
    ang

emae = angle(rsiMA)
emaanglestat = emae > emae[1] ? "▲  Growing": "▼  Falling"
rsiTextxxx = "Rsi MA/ATR angle value is " + str.tostring(emae, "#.##") + "° and is " + emaanglestat
rsicolorxxx = emae >0 and emae >=emae[1] ? txtcol_grow_above : txtcol_fall_below
// Label
label lpt1 = label.new(time, 40, text=rsiTextxxx[0], color=rsicolorxxx, xloc=xloc.bar_time, style=label.style_label_left, textcolor=color.white, textalign=text.align_left, size=size.normal)
label.set_x(lpt1, label.get_x(lpt1) + tmf)
label.delete(lpt1[1])

txtrsiColors  = (rsi > 50 ? (rsi[1] < rsi ? txtcol_grow_above : txtcol_fall_above) : (rsi[1] < rsi ? txtcol_grow_below : txtcol_fall_below))

label lrsi1 = label.new(time, 60, text=rsiText[0], color=txtrsiColors, xloc=xloc.bar_time, style=label.style_label_left, textcolor=color.white, textalign=text.align_left, size=size.normal)
label.set_x(lrsi1, label.get_x(lrsi1) + tmf)
label.delete(lrsi1[1])



plFound = na(ta.pivotlow(rsi, lbL, lbR)) ? false : true
phFound = na(ta.pivothigh(rsi, lbL, lbR)) ? false : true
_inRange(cond) =>
	bars = ta.barssince(cond == true)
	rangeLower <= bars and bars <= rangeUpper


//------------------------------------------------------------------------------
// Regular Bullish
// rsi: Higher Low

rsiHL = rsi[lbR] > ta.valuewhen(plFound, rsi[lbR], 1) and _inRange(plFound[1])

// Price: Lower Low

priceLL = low[lbR] < ta.valuewhen(plFound, low[lbR], 1)
bullCond = plotBull and priceLL and rsiHL and plFound

plot(
     plFound ? rsi[lbR] : na,
     offset=-lbR,
     title="Regular Bullish",
     linewidth=2,
     color=(bullCond ? bullColor : noneColor),
	 display = display.pane
     )

if bullCond
	BCL = label.new(x=bar_index - lbL, y= rsi[lbR], color=bullColor, style =label.style_label_up , textcolor=textColor, size=size.small, text = " Bull ")

//------------------------------------------------------------------------------
// Hidden Bullish
// rsi: Lower Low

rsiLL = rsi[lbR] < ta.valuewhen(plFound, rsi[lbR], 1) and _inRange(plFound[1])

// Price: Higher Low

priceHL = low[lbR] > ta.valuewhen(plFound, low[lbR], 1)
hiddenBullCond = plotHiddenBull and priceHL and rsiLL and plFound

plot(
	 plFound ? rsi[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bullish",
	 linewidth=2,
	 color=(hiddenBullCond ? hiddenBullColor : noneColor),
	 display = display.pane
	 )

if hiddenBullCond
	HBLabel = label.new(x=bar_index - lbL, y= rsi[lbR], color=hiddenBullColor, style =label.style_label_up , textcolor=textColor, size=size.small, text=" H Bull ")


//------------------------------------------------------------------------------
// Regular Bearish
// rsi: Lower High

rsiLH = rsi[lbR] < ta.valuewhen(phFound, rsi[lbR], 1) and _inRange(phFound[1])

// Price: Higher High

priceHH = high[lbR] > ta.valuewhen(phFound, high[lbR], 1)

bearCond = plotBear and priceHH and rsiLH and phFound


plot(
	 phFound ? rsi[lbR] : na,
	 offset=-lbR,
	 title="Regular Bearish",
	 linewidth=2,
	 color=(bearCond ? bearColor : noneColor),
	 display = display.pane
	 )

if bearCond
	RBearish = label.new(x=bar_index - lbL, y= rsi[lbR], color=bearColor, style =label.style_label_down , textcolor=textColor, size=size.small, text=" Bear ")


//------------------------------------------------------------------------------
// Hidden Bearish
// rsi: Higher High

rsiHH = rsi[lbR] > ta.valuewhen(phFound, rsi[lbR], 1) and _inRange(phFound[1])

// Price: Lower High

priceLH = high[lbR] < ta.valuewhen(phFound, high[lbR], 1)

hiddenBearCond = plotHiddenBear and priceLH and rsiHH and phFound

plot(
	 phFound ? rsi[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bearish",
	 linewidth=2,
	 color=(hiddenBearCond ? hiddenBearColor : noneColor),
	 display = display.pane
	 )

if hiddenBearCond
	RBearish = label.new(x=bar_index - lbL, y= rsi[lbR], color=bearColor, style =label.style_label_down , textcolor=textColor, size=size.small,  text=" H Bear ")


// Create alert condition
alertcondition(condition=bullCond,
	 title="Alert for Regular Bullish Divergence",
     message="Regular Bullish Divergence Detected")

alertcondition(condition=hiddenBullCond,
	 title="Alert for Hidden Bullish Divergence",
     message="Hidden Bullish Divergence Detected")


alertcondition(condition=bearCond,
	 title="Alert for Regular Bearish Divergence",
     message="Regular Bearish Divergence Detected")

alertcondition(condition=hiddenBearCond,
	 title="Alert for Hidden Bearish Divergence",
     message="Hidden Bearish Divergence Detected")

rsiOverbought = rsi > overBought 
rsiXOverbought = rsi > obXLevel  
rsiOversold =  rsi < overSold 
rsiXOversold =  rsi < osXLevel 

alertcondition(condition=rsiOverbought,
	 title="Alert for RSI Overbought",
     message="RSI Overbought")

alertcondition(condition=rsiXOverbought,
	 title="Alert for RSI Extreme Overbought",
     message="RSI Extreme Overbought")

alertcondition(condition=rsiOversold,
	 title="Alert for RSI Oversold",
     message="RSI Oversold")

alertcondition(condition=rsiXOversold,
	 title="Alert for RSI Extreme Oversold",
     message="RSI Extreme Oversold")

rsiAboveMA = rsi > rsiMA and rsi[1] < rsiMA[1]
rsiBelloweMA = rsi < rsiMA and rsi[1] > rsiMA[1]

alertcondition(condition=rsiAboveMA,
	 title="Alert for RSI Crossing Above RSI MA",
     message="RSI Crossed Above RSI Moving average")

alertcondition(condition=rsiBelloweMA,
	 title="Alert for RSI Crossing Bellow RSI MA",
     message="RSI Crossed Bellow RSI Moving average")

rsiAbove50 = rsi > 50 and rsi[1] <= 50
rsiBellowe50 = rsi < 50 and rsi[1] >= 50

alertcondition(condition=rsiAbove50,
	 title="Alert for RSI Crossing Above 50",
     message="RSI Crossed Above 50")

alertcondition(condition=rsiBellowe50,
	 title="Alert for RSI Crossing Bellow 50",
     message="RSI Crossed Bellow RSI 50")