RSI+ by Wilson (alt)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © wilsonlibero
// extended by tartigradia

//@version=5
indicator(title='RSI+ by Wilson (alt)', shorttitle='RSI+ (Wilson alt)', format=format.price, precision=2, timeframe="", timeframe_gaps=true)

//
// Inputs

var grp1 = 'Core parameters'
src1 = input.source(close, title='RSI Source', inline='11', group=grp1)
length1 = input.int(defval=14, minval=1, title='RSI Length', inline='11', group=grp1)

var grp2 = 'Thresholds and highlights'
overbthr = input.int(defval=70, minval=1, maxval=100, title='Overbought threshold', group=grp2)
oversthr = input.int(defval=30, minval=1, maxval=100, title='Oversold threshold', group=grp2)
overbthr2 = input.int(defval=75, minval=1, maxval=100, title='Extended overbought threshold', group=grp2)
oversthr2 = input.int(defval=25, minval=1, maxval=100, title='Extended oversold threshold', group=grp2)
overbthr3 = input.int(defval=85, minval=1, maxval=100, title='Maximally extended overbought threshold', group=grp2)
oversthr3 = input.int(defval=15, minval=1, maxval=100, title='Maximally extended oversold threshold', group=grp2)
plotoverli = input.bool(true, title='Plot Overbought & Oversold Margin Lines', group=grp2)
plotoverli2 = input.bool(false, title='Plot Extended Overbought & Oversold Margin Lines', group=grp2)
highlight = input.bool(true, title='Highlight Overbought & Oversold Areas', group=grp2, tooltip='Highlight the background when price is beyond overbought or oversold thresholds, with different colors for extended and maximally extended thresholds. This does not require the display of the thresholds.')
highlightmid = input.bool(true, title='Highlight Bullish & Bearish Areas Above & Below Midline', group=grp2, tooltip='Highlight the background when price is consistently above or below the midle (RSI 50%), which is usually considered a sign of bullish or bearish trend respectively.')
midlinemargin = input.int(5, minval=0, maxval=50, title='Midline Margin To Exclude Bullish & Bearish Areas Highlight', group=grp2, tooltip='When price will be plus or minus this margin around 50%, there will be no background highlighting, as a way to signal that the trend remains uncertain. Default is 5, which means that RSI 45%-55% will remain without highlighting = uncertain trend area.')

// RSI Shadow
// Copied over from the indicator of the same name by Tartigradia, but with the RSI Shadow Sentiment adapted to display as a bar instead of a background highlighting, for better ergonomy.
// How to use: compare the colors of both RSI Status and RSI Shadow Sentiment bars, when they are in agreement, especially for longer strings, the sentiment is stronger than if sentiment is only indicated by either bar alone.
// RSI Shadow Sentiment bar can also sometimes show a trend reversal earlier, although it is unreliable (it is highly sensitive to market participants emotions), hence using it as a reversal tool should always be combined with other indicators/readings from RSI (e.g. , RSI MA cloud, RSI midline sentiment with background highlight, etc...).
var grpshadow = 'RSI Shadow'
rsishadow = input.bool(true, title='Show RSI Shadow', tooltip='Shows the area of high/low RSI values attained during open sessions (ie, wicks).', group=grpshadow)
rsishadowtype = input.string('New', title='RSI Shadow calculation method', options=['Old', 'New'], tooltip='New: accurate shadow, showing the exact RSI values attained at high and low during the open session. Old: area between max(rsi of open or high or low or close) vs min of all the same possible inputs.', group=grpshadow)
src_high_str = input.string('high', title='RSI Shadow Source 1', options=['close', 'open', 'high', 'low', 'hl2', 'hlc3', 'hlcc4'], group=grpshadow)  // workaround: we use an input.string combined with a select, to avoid using multiple input.source, because when there is only one single input.source, then TradingView allows to select external inputs such as other indicators' outputs, instead of just price values.
src_low_str = input.string('low', title='RSI Shadow Source 2', options=['close', 'open', 'high', 'low', 'hl2', 'hlc3', 'hlcc4'], group=grpshadow)
shadow_sentiment = input.bool(true, "Display RSI Shadow Sentiment Bar?", tooltip="Display a bar at the bottom codifying bullish or bearish sentiment depending on RSI being closer to the high or low shadow bounds respectively.", group=grpshadow)
shadow_sentiment_congruent = input.bool(true, "RSI Shadow Sentiment Congruency", tooltip="If true, then will highlight background only if both 1) RSI is close to a bound, 2) RSI goes in the same direction as the bound it is closest. Eg, if RSI is close to high shadow bound, but is going down, then it is incongruent and there will be no highlight.", group=grpshadow)
shadow_sentiment_margin = input.int(2, "RSI Shadow Sentiment Margin", minval=0, step=1, tooltip="Margin to consider that RSI is significantly closer to the high or low bounds", group=grpshadow)

// Workaround to use only one source: we manually input each possible price source from an input.string()
src_high = switch src_high_str
    'close' => close
    'open' => open
    'high' => high
    'low' => low
    'hl2' => hl2
    'hlc3' => hlc3
    'hlcc4' => hlcc4
src_low = switch src_low_str
    'close' => close
    'open' => open
    'high' => high
    'low' => low
    'hl2' => hl2
    'hlc3' => hlc3
    'hlcc4' => hlcc4

var grp3 = 'Moving Averages'
plotma1 = input.bool(true, title='Plot First MA', group=grp3)
length2 = input.int(defval=20, minval=2, title='First MA Length', group=grp3)
type = input.string(defval='EMA', options=['SMA', 'EMA', 'WMA', 'VWMA', 'HullMA', 'ALMA'], title=' First MA Type', group=grp3)
plotma2 = input.bool(false, title='Plot Second MA', group=grp3)
length3 = input.int(defval=5, minval=2, title='Second MA Length', group=grp3)
type2 = input.string(defval='ALMA', options=['SMA', 'EMA', 'WMA', 'VWMA', 'HullMA', 'ALMA'], title=' Second MA Type', group=grp3)
almaOffset = input.float(0.85, minval=0, title='ALMA Offset', group=grp3)
almaSigma = input.int(6, minval=0, title='ALMA Sigma', group=grp3)
plothist1 = input.bool(true, title='Plot Histogram of RSI & First MA', group=grp3)
plothist2 = input.bool(false, title='Plot Histogram of RSI & Second MA', group=grp3)
colorfill1 = input.bool(true, title='Fill colour between RSI & First MA (RSI Cloud 1)', group=grp3)
colorfill2 = input.bool(false, title='Fill colour between RSI & Second MA (RSI Cloud 2)', group=grp3)
signalplot1 = input.bool(true, title='Show Cross Signals of First MA', group=grp3)
signalplot2 = input.bool(false, title='Show Cross Signals of Second MA', group=grp3)
status = input.bool(true, title='Show RSI Positional Status Bar', group=grp3, tooltip='RSI Positional Status codifies the current trend as a colored bar depending on the crossings of the two MAs. Note that the RSI Status will use the configuration for each MAs even if they are not displayed (ie, if you change one MA type, it will change the RSI Status bar).')

var grp4 = 'Alerts'
alert1 = input(false, title='Alert for Crosses of First MA', group=grp4)
alert2 = input(false, title='Alert for Crosses of Second MA', group=grp4)

//
// Aux functions

// The following shadow functions perform the usual calculations except for the current bar, for which a value based on another source is returned.
// For example, this allows to calculate what the SMA would be if we used the close value for all past bars, but use the high or low value for the current bar. Repeat this for all bars, and you get the higher/lower bound of SMA values that happened during open sessions.
// Hence, the "shadow" functions allow to plot the high/low values that were attained during open sessions, and hence allow to visually represent the variability that historically happened, which may be of importance for the future.

// From pinescript doc
shadow_sma(src, src_cur, len) =>
    sum = 0.0
    sum := nz(sum[1]) - nz(src[len]) + src  // compute the updated rolling sum
    (nz(sum[1]) - nz(src) + src_cur)/len // but don't return the normal sum using the src, instead remove the last src value and replace it with src_cur (the second source) and return the sma of it!

// Moving average used in RSI. It is the exponentially weighted moving average with alpha = 1 / length.
// from pinescript v5 doc
shadow_rma(src, src_cur, length) =>
	alpha = 1/length
	sum = 0.0
	sum_cur = na(sum[1]) ? shadow_sma(src, src_cur, length) : alpha * src_cur + (1 - alpha) * nz(sum[1]) // calculate the EMA using the second source (src_cur) before modifying the sum, because it would be more complicated to reverse the calculation afterwards (as we do in SMA)
	sum := na(sum[1]) ? shadow_sma(src, src_cur, length) : alpha * src + (1 - alpha) * nz(sum[1]) // update the sum so that on next bar we can reuse the typical EMA value derived from the first source (src).
	sum_cur // return the shadow EMA value, using src for all past bars, except current bar which uses the second source src_cur.

// from pinescript v5 doc
shadow_rsi(src1, src2, length) => 
    // normal RSI values
    u = math.max(src1 - src1[1], 0) // upward ta.change
    d = math.max(src1[1] - src1, 0) // downward ta.change
    // shadow RSI values (using second source for last bar vs first source for past bars)
    u_cur = math.max(src2 - src1[1], 0) // upward ta.change
    d_cur = math.max(src1[1] - src2, 0) // downward ta.change
    // use shadow functions to force using the second source for the last bar
    rs = shadow_rma(u, u_cur, length) / shadow_rma(d, d_cur, length)
    // calculate RSI as usual
    res = 100 - 100 / (1 + rs)
    res

//
// Calculations

rsi = ta.rsi(src1, length1)
maplot = type == 'SMA' ? ta.sma(rsi, length2) : type == 'EMA' ? ta.ema(rsi, length2) : type == 'WMA' ? ta.wma(rsi, length2) : type == 'VWMA' ? ta.vwma(rsi, length2) : type == 'HullMA' ? ta.wma(2 * ta.wma(rsi, length2 / 2) - ta.wma(rsi, length2), math.round(math.sqrt(length2))) : type == 'ALMA' ? ta.alma(rsi, length2, almaOffset, almaSigma) : na
maplot2 = type == 'SMA' ? ta.sma(rsi, length3) : type == 'EMA' ? ta.ema(rsi, length3) : type == 'WMA' ? ta.wma(rsi, length3) : type == 'VWMA' ? ta.vwma(rsi, length3) : type == 'HullMA' ? ta.wma(2 * ta.wma(rsi, length3 / 2) - ta.wma(rsi, length3), math.round(math.sqrt(length3))) : type == 'ALMA' ? ta.alma(rsi, length3, almaOffset, almaSigma) : na
diffp = (rsi - maplot) / maplot * 100
diffn = (maplot - rsi) / maplot * 100
absdiff = math.abs(rsi - maplot)
diffp2 = (rsi - maplot2) / maplot2 * 100
diffn2 = (maplot2 - rsi) / maplot2 * 100
absdiff2 = math.abs(rsi - maplot2)
rsi_h = ta.rsi(high, length1)
rsi_o = ta.rsi(open, length1)
rsi_l = ta.rsi(low, length1)
rsi_c = ta.rsi(close, length1)
// Old RSI Shadow
rsimax = rsishadow and (rsishadowtype == 'Old') ? math.max(rsi_h, rsi_o, rsi_l, rsi_c) : 0.0
rsimin = rsishadow and (rsishadowtype == 'Old') ? math.min(rsi_h, rsi_o, rsi_l, rsi_c) : 0.0
// New RSI Shadow: Calculate values of RSI, RSI high and RSI low
//vrsi = shadow_rsi(src, src, rsi_length)
vrsi_high = (rsishadow and (rsishadowtype == 'New')) or shadow_sentiment ? shadow_rsi(src1, src_high, length1) : 0.0
vrsi_low = (rsishadow and (rsishadowtype == 'New')) or shadow_sentiment ? shadow_rsi(src1, src_low, length1) : 0.0

// Preconfigure some colors
cgr = #64ffda  // color.green
cre = color.red
cwh = color.white
cye = color.yellow
cbl = #90bff9

//
// Plotting

p2 = plot(rsi, title='RSI', color=rsi > rsi[1] ? color.new(cgr, 20) : color.new(cwh, 20), linewidth=3)
p1 = plot(plotma1 ? maplot : na, title='First MA', color=color.new(color.yellow, 0))
p3 = plot(plotma2 ? maplot2 : na, title='Second MA', color=color.new(color.blue, 0))  // TODO: remove ternary conditional plotma2 and plotma1 and similar, and replace with display=display.none or display.all, this will hide/display graph by default and it can be changed in style, instead of having an input option that counts for 2 objects on graph instead of 1
p4 = plot(plothist1 ? absdiff : na, title='Histogram MA1', color=rsi > maplot ? cgr : cre, style=plot.style_histogram)
p5 = plot(plothist2 ? absdiff2 : na, title='Histogram MA2', color=rsi > maplot2 ? cgr : cre, style=plot.style_histogram)
p6 = hline(status ? -3 : na, color=color.new(cwh, 100), title='Status Line Bottom', linestyle=hline.style_dotted)
p7 = hline(status ? 0 : na, color=color.new(cwh, 100), title='Status Line Top', linestyle=hline.style_dotted)
p8 = hline(50, color=color.new(cwh, 50), title='Midline', linewidth=1, linestyle=hline.style_solid)
p9 = hline(plotoverli ? overbthr : na, color=color.new(cwh, 100), title='Overbought line', linestyle=hline.style_dotted)
p10 = hline(plotoverli ? oversthr : na, color=color.new(cwh, 100), title='Oversold line', linestyle=hline.style_dotted)
p11 = hline(plotoverli or plotoverli2 ? overbthr2 : na, color=color.new(cwh, 100), title='Extended overbought line', linestyle=hline.style_dotted)
p12 = hline(plotoverli or plotoverli2 ? oversthr2 : na, color=color.new(cwh, 100), title='Extended oversold line', linestyle=hline.style_dotted)
p13 = hline(plotoverli2 ? overbthr3 : na, color=color.new(cwh, 100), title='Maximally extended overbought line', linestyle=hline.style_dotted)
p14 = hline(plotoverli2 ? oversthr3 : na, color=color.new(cwh, 100), title='Maximally extended oversold line', linestyle=hline.style_dotted)
prsih = plot(rsishadow and (rsishadowtype == 'New') ? vrsi_high : rsishadow ? rsimax : na, title='RSI Shadow high line', color=color.new(color.white, 50), linewidth=1, display=display.none)
prsil = plot(rsishadow and (rsishadowtype == 'New') ? vrsi_low : rsishadow ? rsimin : na, title='RSI Shadow low min line', color=color.new(color.white, 50), linewidth=1, display=display.none)
pshadowsentiment = hline(shadow_sentiment ? -6 : na, color=color.new(cwh, 100), title='RSI Shadow Sentiment Bar Line Bottom', linestyle=hline.style_dotted) // use invisible color lines instead of display.none to ensure chart is scaled to include bar, otherwise with display.none the fill will still be displayed but the chart won't necessarily get scaled to display it

plotshape(signalplot1 and ta.crossover(rsi, maplot) ? rsi : na, 'First MA Crossover', size=size.tiny, style=shape.circle, location=location.absolute, color=color.new(cgr, 0))
plotshape(signalplot1 and ta.crossunder(rsi, maplot) ? rsi : na, 'First MA Crossunder', size=size.tiny, style=shape.circle, location=location.absolute, color=color.new(cre, 0))
plotshape(signalplot2 and ta.crossover(rsi, maplot2) ? rsi : na, 'Second MA Crossover', size=size.tiny, style=shape.diamond, location=location.absolute, color=color.new(cgr, 0))
plotshape(signalplot2 and ta.crossunder(rsi, maplot2) ? rsi : na, 'Second MA Crossunder', size=size.tiny, style=shape.diamond, location=location.absolute, color=color.new(cre, 0))

fill(p6, p7, rsi > maplot and rsi > maplot2 and status ? color.new(cgr, 10) : na, title="RSI Status Bullish")
fill(p6, p7, rsi < maplot and rsi < maplot2 and status ? color.new(cre, 10) : na, title="RSI Status Bearish")
fill(p6, p7, rsi > maplot and rsi < maplot2 and status ? color.new(cye, 10) : na, title="RSI Status Undecided")
fill(p6, p7, rsi < maplot and rsi > maplot2 and status ? color.new(cye, 10) : na, title="RSI Status Undecided")

fill(prsih, prsil, color=rsishadow ? color.new(color.white, 50) : na, title='RSI Shadow') // Fill between RSI high and RSI low to get the RSI Shadow!

// RSI Shadow Sentiment Bar coloring
// To save on the PineScript limit of maximum drawn objects under 64, we plot all this under one call:
// First we check if shadow_sentiment display is enabled
// Secondly, we check if RSI is closer to the higher shadow bound than the lower bound, including the margin.
//      If yes, then if congruency check is enabled, we check if bar is congruent (ie, RSI of current bar is higher than RSI of previous bar, hence, RSI is both closer to higher shadow bound AND it is rising higher), then we fill in green
//      Otherwise, bar is incongruent, we fill in gray.
// If no (RSI is not closer to the higher shadow bound), then Thirdly, we check if RSI is closer to the lower shadow bound than the higher bound, including the margin.
//      If yes, then if congruency check is enabled, check if bar is congruent. If yes, fill in red. Otherwise, bar is incongruent, fill in gray.
// If no again (RSI is neither closer to the higher shadow bound nor lower bound including margin, it's kind of in the middle), then fill in yellow, to signal current bar has an undecided sentiment.
// 
fill(pshadowsentiment, p6, color=
     not shadow_sentiment ?
         na :
         (vrsi_high - rsi + shadow_sentiment_margin) < (rsi - vrsi_low) ?
             (shadow_sentiment_congruent ? rsi > rsi[1] : true) ?
                 color.new(cgr, 10) :
                 color.new(color.gray, 10)
             :
             (vrsi_high - rsi) > (rsi - vrsi_low + shadow_sentiment_margin) ?
                 (shadow_sentiment_congruent ? rsi < rsi[1] : true) ?
                     color.new(cre, 10) :
                     color.new(color.gray, 10)
                 :
                 color.new(cye, 10),
     title="RSI Shadow Sentiment Status Bar (is RSI closer to the higher or lower bound?)")

fill(p9, p11, plotoverli ? color.new(cwh, 90) : na, title='Overbought Margin')
fill(p11, p13, plotoverli2 ? color.new(cwh, 85) : na, title='Oversold Margin')
fill(p10, p12, plotoverli ? color.new(cwh, 90) : na, title='Extended Overbought Margin')
fill(p12, p14, plotoverli2 ? color.new(cwh, 85) : na, title='Extended OverSold Margin')

//
// Fill diff
// TODO: to save on number of outputs and still keep a filling gradient, try to use the new overload filling? https://www.tradingview.com/script/Tj38mR1q-RSI-colour-fill/

fill(p1, p2, color=colorfill1 and rsi > maplot and diffp > 90 ? color.new(cgr, 5) : na, title='Fill Diff Positive MA1 >90%')
fill(p1, p2, color=colorfill1 and rsi > maplot and diffp > 80 and diffp <= 90 ? color.new(cgr, 10) : na, title='Fill Diff Positive MA1 >80%')
fill(p1, p2, color=colorfill1 and rsi > maplot and diffp > 60 and diffp <= 80 ? color.new(cgr, 20) : na, title='Fill Diff Positive MA1 >60%')
fill(p1, p2, color=colorfill1 and rsi > maplot and diffp > 40 and diffp <= 60 ? color.new(cgr, 30) : na, title='Fill Diff Positive MA1 >40%')
fill(p1, p2, color=colorfill1 and rsi > maplot and diffp > 20 and diffp <= 40 ? color.new(cgr, 40) : na, title='Fill Diff Positive MA1 >20%')
fill(p1, p2, color=colorfill1 and rsi > maplot and diffp > 10 and diffp <= 20 ? color.new(cgr, 60) : na, title='Fill Diff Positive MA1 >10%')
fill(p1, p2, color=colorfill1 and rsi > maplot and diffp <= 10 ? color.new(cgr, 80) : na, title='Fill Diff MA1 <=10%')

fill(p1, p2, color=colorfill1 and rsi < maplot and diffn > 90 ? color.new(cre, 5) : na, title='Fill Diff Negative MA1 >90%')
fill(p1, p2, color=colorfill1 and rsi < maplot and diffn > 80 and diffn <= 90 ? color.new(cre, 10) : na, title='Fill Diff Negative MA1 >80%')
fill(p1, p2, color=colorfill1 and rsi < maplot and diffn > 60 and diffn <= 80 ? color.new(cre, 20) : na, title='Fill Diff Negative MA1 >60%')
fill(p1, p2, color=colorfill1 and rsi < maplot and diffn > 40 and diffn <= 60 ? color.new(cre, 30) : na, title='Fill Diff Negative MA1 >40%')
fill(p1, p2, color=colorfill1 and rsi < maplot and diffn > 20 and diffn <= 40 ? color.new(cre, 40) : na, title='Fill Diff Negative MA1 >20%')
fill(p1, p2, color=colorfill1 and rsi < maplot and diffn > 10 and diffn <= 20 ? color.new(cre, 60) : na, title='Fill Diff Negative MA1 >10%')
fill(p1, p2, color=colorfill1 and rsi < maplot and diffn <= 10 ? color.new(cre, 80) : na, title='Fill Diff Negative MA1 <=10%')

fill(p3, p2, color=colorfill2 and rsi > maplot2 and diffp2 > 90 ? color.new(cgr, 5) : na, title='Fill Diff Positive MA2 >90%')
fill(p3, p2, color=colorfill2 and rsi > maplot2 and diffp2 > 80 and diffp2 <= 90 ? color.new(cgr, 10) : na, title='Fill Diff Positive MA2 >80%')
fill(p3, p2, color=colorfill2 and rsi > maplot2 and diffp2 > 60 and diffp2 <= 80 ? color.new(cgr, 20) : na, title='Fill Diff Positive MA2 >60%')
fill(p3, p2, color=colorfill2 and rsi > maplot2 and diffp2 > 40 and diffp2 <= 60 ? color.new(cgr, 30) : na, title='Fill Diff Positive MA2 >40%')
fill(p3, p2, color=colorfill2 and rsi > maplot2 and diffp2 > 20 and diffp2 <= 40 ? color.new(cgr, 40) : na, title='Fill Diff Positive MA2 >20%')
fill(p3, p2, color=colorfill2 and rsi > maplot2 and diffp2 > 10 and diffp2 <= 20 ? color.new(cgr, 60) : na, title='Fill Diff Positive MA2 >10%')
fill(p3, p2, color=colorfill2 and rsi > maplot2 and diffp2 <= 10 ? color.new(cgr, 80) : na, title='Fill Diff Positive MA2 <=10%')

fill(p3, p2, color=colorfill2 and rsi < maplot2 and diffn2 > 90 ? color.new(cre, 5) : na, title='Fill Diff Negative MA2 >90%')
fill(p3, p2, color=colorfill2 and rsi < maplot2 and diffn2 > 80 and diffn2 <= 90 ? color.new(cre, 10) : na, title='Fill Diff Negative MA2 >80%')
fill(p3, p2, color=colorfill2 and rsi < maplot2 and diffn2 > 60 and diffn2 <= 80 ? color.new(cre, 20) : na, title='Fill Diff Negative MA2 >60%')
fill(p3, p2, color=colorfill2 and rsi < maplot2 and diffn2 > 40 and diffn2 <= 60 ? color.new(cre, 30) : na, title='Fill Diff Negative MA2 >40%')
fill(p3, p2, color=colorfill2 and rsi < maplot2 and diffn2 > 20 and diffn2 <= 40 ? color.new(cre, 40) : na, title='Fill Diff Negative MA2 >20%')
fill(p3, p2, color=colorfill2 and rsi < maplot2 and diffn2 > 10 and diffn2 <= 20 ? color.new(cre, 60) : na, title='Fill Diff Negative MA2 >10%')
fill(p3, p2, color=colorfill2 and rsi < maplot2 and diffn2 <= 10 ? color.new(cre, 80) : na, title='Fill Diff Negative MA2 <=10%')

//
// Overbought highlight

bgcolor(highlight and rsi >= overbthr and rsi < overbthr2 ? color.new(cgr, 50) : na, title='Overbought Highlight')
bgcolor(highlight and rsi >= overbthr2 and rsi < overbthr3 ? color.new(cgr, 20) : na, title='Extended Overbought Highlight')
bgcolor(highlight and rsi >= overbthr3 ? color.new(cgr, 5) : na, title='Maximally Extended Overbought Highlight')

//
// Oversold highlight

bgcolor(highlight and rsi <= oversthr and rsi > oversthr2 ? color.new(cre, 50) : na, title='Oversold Highlight')
bgcolor(highlight and rsi <= oversthr2 and rsi > oversthr3 ? color.new(cre, 20) : na, title='Extended Oversold Highlight')
bgcolor(highlight and rsi <= oversthr3 ? color.new(cre, 10) : na, title='Maximally Extended Oversold Highlight')

//
// RSI trend compared to midline
bgcolor(highlightmid and rsi < 50 - midlinemargin ? color.new(cye, 75) : na, title='Bearish Trend (Below Midline) Bg Highlight')
bgcolor(highlightmid and rsi > 50 + midlinemargin ? color.new(cbl, 70) : na, title='Bullish Trend (Above Midline) Bg Highlight')

//
// Alerts

alertcondition(alert1 and ta.crossover(rsi, maplot) or ta.crossunder(rsi, maplot), title='RSI Crossing First MA')
alertcondition(alert2 and ta.crossover(rsi, maplot2) or ta.crossunder(rsi, maplot2), title='RSI Crossing Second MA')

//
// Stochastic RSI (from TradingView native library)
cstoch1 = #2962FF
cstoch2 = #FF6D00

var grp5 = 'Stochastic RSI'
plotstoch = input(true, title='Plot Stochastic RSI', inline='S1', group=grp5)
lengthStoch = input.int(14, "Stochastic Length", minval=1, inline='S1', group=grp5)
smoothK = input.int(3, "Stochastic smoothing K", minval=1, inline='S2', group=grp5)
smoothD = input.int(3, "Stochastic smoothing D", minval=1, inline='S2', group=grp5)
stochrescale = input(true, title='Rescale Stochastic RSI between RSI overbought/oversold thresholds?', group=grp5, tooltip='Rescale stochastic RSI to be under overbought/oversold thresholds instead of 0-100%, to minimize space used by stochastic RSI and hence less cluttered visuals.')

k = ta.sma(ta.stoch(rsi, rsi, rsi, lengthStoch), smoothK)
d = ta.sma(k, smoothD)
k_rescale = oversthr + ((k - ta.min(k)) * (overbthr - oversthr) / ta.max(k) - ta.min(k))
d_rescale = oversthr + ((d - ta.min(d)) * (overbthr - oversthr) / ta.max(d) - ta.min(d))

plot(plotstoch ? (stochrescale ? k_rescale : k) : na, "StochRSI K", color=color.new(cstoch1, 30))
plot(plotstoch ? (stochrescale ? d_rescale : d) : na, "StochRSI D", color=color.new(cstoch2, 30))

//h0 = hline(80, "Upper Band", color=#787B86)
//hline(50, "Middle Band", color=color.new(#787B86, 50))
//h1 = hline(20, "Lower Band", color=#787B86)
//fill(h0, h1, color=color.rgb(33, 150, 243, 90), title="Background")
