Variety Step RSI w/ Dynamic Zones [Loxx]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5
indicator("Variety Step RSI w/ Dynamic Zones [Loxx]")

greencolor = #2DD204
redcolor = #D2042D 

import loxx/loxxvarietyrsi/1

fema(float src, simple int len)=>
    alpha = (2.0 / (2.0 + (len - 1.0) / 2.0))
    out = 0.
    out := nz(out[1]) + alpha * (src - nz(out[1])) 
    out

variant(simple string typein, src, per)=>
    out = 0.
    if typein == "Exponential Moving Average - EMA"
        out := ta.ema(src, per)
    if typein == "Fast Exponential Moving Average - FEMA"
        out := fema(src, per)
    out
    
stepMACalc(float rsi, simple int size)=>
    float smax = rsi + 2.0 * size
    float smin = rsi - 2.0 * size
    var trend = 0
    float result = 0
    if nz(trend[1]) <= 0 and rsi > nz(smax[1]) 
        trend := 1
    if nz(trend[1]) >= 0 and rsi < nz(smin[1]) 
        trend := -1
    if trend > 0 
        if smin < nz(smin[1]) 
            smin := nz(smin[1])
        result := smin + size
    else
        if smax > nz(smax[1]) 
            smax := nz(smax[1])
        result := smax - size
    result

src = input.source(close, "Source", group = "Basic Settings")
rsitype = input.string("Slow", "RSI Type", options = ["RSX", "Regular", "Slow", "Rapid", "Harris", "Cuttler", "Ehlers Smoothed"], group = "Basic Settings")

rsiper = input.int(14, "RSI Period", group = "Basic Settings")
stpsize = input.int(5, "Step Size", group = "Basic Settings")

signal_length = input.int(9, "Signal Period", group = "Signal/DSL Settings")
sigmatype = input.string("Exponential Moving Average - EMA", "Signal/DSL Smoothing", options = ["Exponential Moving Average - EMA", "Fast Exponential Moving Average - FEMA"], group = "Signal/DSL Settings")

bool colorbars = input.bool(true, "Color bars?", group = "UI Options")
bool showSigs = input.bool(false, "Show signals?", group = "UI Options")

rsimode = switch rsitype
	"RSX" => "rsi_rsx"
	"Regular" => "rsi_rsi"
	"Slow" => "rsi_slo"
	"Rapid" => "rsi_rap"
	"Harris" => "rsi_har"
	"Cuttler" => "rsi_cut"
	"Ehlers Smoothed" => "rsi_ehl"
	=> "rsi_rsi"

rsiout = loxxvarietyrsi.rsiVariety(rsimode, src, rsiper)
sig = stepMACalc(rsiout, stpsize)

levelu = 0., leveld = 0., mid = 0.

tmp =  variant(sigmatype, rsiout, signal_length)
levelu := (rsiout > sig) ? tmp : nz(levelu[1])
leveld := (rsiout < sig) ? tmp: nz(leveld[1])
        

colorout = rsiout > levelu ? greencolor  :  rsiout < leveld ? redcolor : color.gray

plot(rsiout, "RSI", color = colorout, linewidth = 2)
plot(levelu, "Upper Level", color = greencolor)
plot(leveld, "Lower Level", color = redcolor)

barcolor(colorbars ? colorout : na)

goLong = ta.crossover(rsiout, levelu)
goShort = ta.crossunder(rsiout, leveld)

plotshape(showSigs and goLong, title = "Long", color = color.yellow, textcolor = color.yellow, text = "L", style = shape.triangleup, location = location.bottom, size = size.auto)
plotshape(showSigs and goShort, title = "Short", color = color.fuchsia, textcolor = color.fuchsia, text = "S", style = shape.triangledown, location = location.top, size = size.auto)

alertcondition(goLong, title="Long", message="Step RSI [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Step RSI [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")