PrivacySmurf's RSIs
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © PrivacySmurf 

//@version=5
indicator(title='PrivacySmurfs RSIs', overlay=false, shorttitle='PS RSIs v2.2')
tradrsi = input(false, title='Use Traditional RSI')
stockbands = input(false, title='Plot Traditional 70/30 bands?')
plotmidline = input(true, title='Plot Midline?')

//Stock RSI
stocklen = 14
src = close
up = ta.rma(math.max(ta.change(src), 0), stocklen)
down = ta.rma(-math.min(ta.change(src), 0), stocklen)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down)
stockbandtop = 70.0
stockbandbottom = 30.0
midline = 50.0

//Cyclic Smoothed RSI by Lars Von Thienen (whentotrade)
domcycle = input.int(20, minval=10, title='Dominant Cycle Length')
crsi = 0.0
cyclelen = domcycle / 2
vibration = 10
leveling = 10.0
cyclicmemory = domcycle * 2
//set min/max ranges?

torque = 2.0 / (vibration + 1)
phasingLag = (vibration - 1) / 2.0

cUp = ta.rma(math.max(ta.change(src), 0), cyclelen)
cDown = ta.rma(-math.min(ta.change(src), 0), cyclelen)
rsi2 = cDown == 0 ? 100 : cUp == 0 ? 0 : 100 - 100 / (1 + cUp / cDown)
crsi := torque * (2 * rsi2 - rsi2[phasingLag]) + (1 - torque) * nz(crsi[1])

lmax = -999999.0
lmin = 999999.0
for i = 0 to cyclicmemory - 1 by 1
    if nz(crsi[i], -999999.0) > lmax
        lmax := nz(crsi[i])
        lmax
    else
        if nz(crsi[i], 999999.0) < lmin
            lmin := nz(crsi[i])
            lmin

mstep = (lmax - lmin) / 100
aperc = leveling / 100

db = 0.0
for steps = 0 to 100 by 1
    testvalue = lmin + mstep * steps
    above = 0
    below = 0
    for m = 0 to cyclicmemory - 1 by 1
        below += (crsi[m] < testvalue ? 1 : 0)
        below

    ratio = below / cyclicmemory
    if ratio >= aperc
        db := testvalue
        break
    else
        continue

ub = 0.0
for steps = 0 to 100 by 1
    testvalue = lmax - mstep * steps
    above = 0
    for m = 0 to cyclicmemory - 1 by 1
        above += (crsi[m] >= testvalue ? 1 : 0)
        above

    ratio = above / cyclicmemory
    if ratio >= aperc
        ub := testvalue
        break
    else
        continue

//Plots
mid = plot(plotmidline ? midline : na, 'Midline', color=color.new(color.white, 0))

lowband = plot(not stockbands ? db : na, 'Adaptive Lower Band', color.new(#FF5252, 0), linewidth=2)
highband = plot(not stockbands ? ub : na, 'Adaptive Higher Band', color.new(#4CAF50, 0), linewidth=2)
signal = plot(not tradrsi ? crsi : na, 'CRSI', color.new(color.fuchsia, 0), linewidth=4)
fill(lowband, highband, color=color.new(color.gray, 90), title="Backgound fill color")
fill(signal, highband, crsi > ub ? color.new(#4CAF50,55) : na, 'PS RSI Overbought fill color')
fill(signal, lowband, crsi < db ? color.new(#FF5252,55) : na, 'PS RSI Oversold fill color')

linetop = plot(stockbands ? stockbandtop : na,'70 line', color=color.new(#4CAF50, 2), linewidth=2)
linebottom = plot(stockbands ? stockbandbottom : na, '30 line', color=color.new(#FF5252, 2), linewidth=2)
fill(signal, linetop, crsi > 70 and stockbands ? color.new(#4CAF50,55) : na, 'PS RSI w/ 70/30 Overbought fill color')
fill(signal, linebottom, crsi < 30 and stockbands ? color.new(#FF5252,55) : na, 'PS RSI w/ 70/30 Oversold fill color')

signal2 = plot(tradrsi ? rsi : na, 'Traditional RSI', color=color.new(color.blue, 0), linewidth=4)
fill(signal2, highband, rsi > ub ? color.new(#4CAF50,55) : na, 'Trad RSI w/ ABs Overbought fill color')
fill(signal2, lowband, rsi < db ? color.new(#FF5252,55) : na, 'Trad RSI w/ ABs Oversold fill color')
fill(signal2, linetop, rsi > 70 and stockbands ? color.new(#4CAF50,55) : na, 'Traditional RSI Overbought fill color')
fill(signal2, linebottom, rsi < 30 and stockbands ? color.new(#FF5252,55) : na, 'Traditional RSI Oversold fill color')

//alerts
alertcondition(ta.crossunder(crsi, db) or ta.crossunder(crsi, stockbandbottom) or ta.crossunder(rsi, db) or ta.crossunder(rsi, stockbandbottom), title='Oversold', message='Entering Oversold Territory')
alertcondition(ta.crossover(crsi, ub) or ta.crossover(crsi, stockbandtop) or ta.crossover(rsi, ub) or ta.crossover(rsi, stockbandtop), title='Overbought', message='Entering Overbought Territory')
 
