Stochastic RSI of Smoothed Price [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("Stochastic RSI of Smoothed Price [Loxx]", 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)

greencolor = #2DD204
redcolor = #D2042D 

import loxx/loxxvarietyrsi/1 as lxrsi
import loxx/loxxexpandedsourcetypes/4

rsimodeout(rsitype)=>
    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"
    rsimode

variant(type, src, len) =>
    sig = 0.0
    if type == "SMA"
        sig := ta.sma(src, len) 
    else if type == "EMA"
        sig := ta.ema(src, len) 
    else if type == "WMA"
        sig := ta.wma(src, len)   
    else if type == "RMA"
        sig := ta.rma(src, len)  
    else if type == "VWMA"
        sig := ta.rma(src, len)  
    sig

string SM02 = 'Fixed Levels'
string SM03 = 'Floating Levels'
string SM04 = 'Quantile Levels'
string SM05 = 'Fixed Middle'
string SM06 = 'Floating Middle'
string SM07 = 'Quantile Middle'

StocPeriod = input.int(32, "Stochastic Period", group = "Stochastic Settings")
StocSlowing = input.int(8, "Stochastic Slowing Period", group = "Stochastic Settings")  

smthtype = input.string("Kaufman", "HAB Calc Type", options = ["AMA", "T3", "Kaufman"], group='RSI Settings')
srcin = input.string("Close", "Source", 
	 options = 
	 ["Close", "Open", "High", "Low", "Median", "Typical", "Weighted", "Average", "Average Median Body", "Trend Biased", "Trend Biased (Extreme)", 
	 "HA Close", "HA Open", "HA High", "HA Low", "HA Median", "HA Typical", "HA Weighted", "HA Average", "HA Average Median Body", "HA Trend Biased", "HA Trend Biased (Extreme)",
	 "HAB Close", "HAB Open", "HAB High", "HAB Low", "HAB Median", "HAB Typical", "HAB Weighted", "HAB Average", "HAB Average Median Body", "HAB Trend Biased", "HAB Trend Biased (Extreme)"], 
	 group='RSI Settings')


PriceSmoothing = input.int(8, "Price Smoothing Period", group = "RSI Settings")  
matype = input.string("SMA", "RSI Smoothing Type", options = ["EMA", "WMA", "RMA", "SMA", "VWMA"], group = "RSI Settings")

RsiPeriod = input.int(32, "RSI Period", group = "RSI Settings")
rsitype = input.string("Regular", "RSI type", options = ["RSX", "Regular", "Slow", "Rapid", "Harris", "Cuttler", "Ehlers Smoothed"], group = "RSI Settings")

MinMaxPeriod =  input.int(25, "Levels Period", group = "Signal Settings")  
LevelUp = input.int(80, "Upper %", group = "Signal Settings")  
LevelDown = input.int(20, "Lower %", group = "Signal Settings")  
sigtype = input.string(SM03, "Signal type", options = [SM02, SM03, SM04, SM05, SM06, SM07], group = "Signal Settings")

colorBars = input.bool(true, "Color bars?", group = "UI Options")
showSigs = input.bool(true, "Show Signals?", group = "UI Options")


kfl = input.float(0.666, title="* Kaufman's Adaptive MA (KAMA) Only - Fast End", group = "Moving Average Inputs")
ksl = input.float(0.0645, title="* Kaufman's Adaptive MA (KAMA) Only - Slow End", group = "Moving Average Inputs")
amafl = input.int(2, title="* Adaptive Moving Average (AMA) Only - Fast", group = "Moving Average Inputs")
amasl = input.int(30, title="* Adaptive Moving Average (AMA) Only - Slow", group = "Moving Average Inputs")
t3hot = input.float(.7, "* T3 Only - T3 Hot", group = "Moving Average Inputs")
t3swt = input.string("T3 New", "* T3 Only - T3 Type", options = ["T3 New", "T3 Original"], group = "Moving Average Inputs")

haclose  =  ohlc4
haopen   = float(na)
haopen  := na(haopen[1]) ? (open + close) / 2 : (nz(haopen[1]) + nz(haclose[1])) / 2
hahigh   =math.max(high, math.max(haopen, haclose))
halow    = math.min(low,  math.min(haopen, haclose))
hamedian = (hahigh + halow) / 2
hatypical = (hahigh + halow + haclose) / 3
haweighted =  (hahigh + halow + haclose + haclose)/4 
haaverage =  (haopen + hahigh + halow + haclose)/4

sourceout(smthtype, srcin)=>
	src = switch srcin
		"Close" => close
		"Open" => open
		"High" => high
		"Low" => low
		"Median" => hl2
		"Typical" => hlc3
		"Weighted" => hlcc4
		"Average" => ohlc4
		"Average Median Body" => (open + close)/2
		"Trend Biased" => loxxexpandedsourcetypes.rtrendb()
		"Trend Biased (Extreme)" => loxxexpandedsourcetypes.rtrendbext()
		"HA Close" => loxxexpandedsourcetypes.haclose(haclose)
		"HA Open" => loxxexpandedsourcetypes.haopen(haopen)
		"HA High" => loxxexpandedsourcetypes.hahigh(hahigh)
		"HA Low" => loxxexpandedsourcetypes.halow(halow)
		"HA Median" => loxxexpandedsourcetypes.hamedian(hamedian)
		"HA Typical" => loxxexpandedsourcetypes.hatypical(hatypical)
		"HA Weighted" => loxxexpandedsourcetypes.haweighted(haweighted)
		"HA Average" => loxxexpandedsourcetypes.haaverage(haaverage)
		"HA Average Median Body" => loxxexpandedsourcetypes.haavemedbody(haclose, haopen)
		"HA Trend Biased" => loxxexpandedsourcetypes.hatrendb(haclose, haopen, hahigh, halow)
		"HA Trend Biased (Extreme)" => loxxexpandedsourcetypes.hatrendbext(haclose, haopen, hahigh, halow)
		"HAB Close" => loxxexpandedsourcetypes.habclose(smthtype, amafl, amasl, kfl, ksl)
		"HAB Open" => loxxexpandedsourcetypes.habopen(smthtype, amafl, amasl, kfl, ksl)
		"HAB High" => loxxexpandedsourcetypes.habhigh(smthtype, amafl, amasl, kfl, ksl)
		"HAB Low" => loxxexpandedsourcetypes.hablow(smthtype, amafl, amasl, kfl, ksl)
		"HAB Median" => loxxexpandedsourcetypes.habmedian(smthtype, amafl, amasl, kfl, ksl)
		"HAB Typical" => loxxexpandedsourcetypes.habtypical(smthtype, amafl, amasl, kfl, ksl)
		"HAB Weighted" => loxxexpandedsourcetypes.habweighted(smthtype, amafl, amasl, kfl, ksl)
		"HAB Average" => loxxexpandedsourcetypes.habaverage(smthtype, amafl, amasl, kfl, ksl)
		"HAB Average Median Body" => loxxexpandedsourcetypes.habavemedbody(smthtype, amafl, amasl, kfl, ksl)
		"HAB Trend Biased" => loxxexpandedsourcetypes.habtrendb(smthtype, amafl, amasl, kfl, ksl)
		"HAB Trend Biased (Extreme)" => loxxexpandedsourcetypes.habtrendbext(smthtype, amafl, amasl, kfl, ksl)
		=> close

rsi = lxrsi.rsiVariety(rsimodeout(rsitype), variant(matype, sourceout(smthtype, srcin), PriceSmoothing), RsiPeriod)

stoch = ta.sma(ta.stoch(rsi, rsi, rsi, StocPeriod), StocSlowing)

float lvlup = LevelUp
float lvldn = LevelDown
float lvlmid = 50.

if sigtype == SM03 or sigtype == SM06 
    fmin = ta.lowest(stoch,  MinMaxPeriod)
    fmax = ta.highest(stoch,  MinMaxPeriod)
    rng = fmax - fmin
    lvlup := fmin + LevelUp * rng / 100.0
    lvldn := fmin + LevelDown * rng / 100.0
    lvlmid := (lvlup + lvldn) * 0.5

if sigtype == SM04 or sigtype == SM07
    lvlup := ta.percentile_linear_interpolation(stoch, MinMaxPeriod, LevelUp) 
    lvldn := ta.percentile_linear_interpolation(stoch, MinMaxPeriod, LevelDown) 
    lvlmid := ta.percentile_linear_interpolation(stoch, MinMaxPeriod, (LevelUp + LevelDown) * 0.5) 

state = 0

if sigtype == SM02 or sigtype == SM03 or sigtype == SM04
    if stoch > lvlup
        state := 1
    if stoch < lvldn
        state := -1

if sigtype == SM05 or sigtype == SM06 or sigtype == SM07
    if stoch > lvlmid
        state := 1
    if stoch < lvlmid
        state := -1

colorout = state == 1 ? greencolor : state == -1 ? redcolor : color.gray

plot(lvlmid, "Middle", color = color.gray)
plot(lvlup, "Upper level", color = greencolor)
plot(lvldn, "Lower level", color = redcolor)
plot(stoch, "Stochastic", color = colorout, linewidth = 2)

barcolor(colorBars ? colorout : na)

goLong =  state == 1 and state[1] != 1
goShort = state == -1 and state[1] != -1

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="Stochastic RSI of Smoothed Price [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Stochastic RSI of Smoothed Price [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")