Variety RSI of Adaptive Lookback Averages [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 RSI of Adaptive Lookback Averages [Loxx]", 
     shorttitle="VRSIALBA [Loxx]", 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)

import loxx/loxxvarietyrsi/1

greencolor = #2DD204
redcolor = #D2042D 

darkGreenColor =  #1B7E02 
darkRedColor = #93021F

SM02 = 'Slope'
SM03 = 'Middle Crosses'

_iLWMA(src, per)=>
    lwma = src, workLwma = src
    sumw = per, sum = per * src
    for k = 1 to per - 1 
        weight = per - k
        sumw += weight
        sum += weight * nz(workLwma[k])   
    lwma := (sum/sumw)
    lwma

_iRMA(src, per) =>
    rma = src
    rma := na(rma[1]) ? src : (src - nz(rma[1])) * (1/per) + nz(rma[1])
    rma

_iEMA(src, per) =>
    ema = src
    ema := na(ema[1]) ? src : (src - nz(ema[1])) * (2 / (per + 1)) + nz(ema[1])
    ema
    
_iSMA(src, per)=>
    avg = src, k = 1, workSma = src
    while k < per
        avg += nz(workSma[k])
        k += 1
    out = avg/k
    out

_albper(swingCount, speed)=>
    swing = 0.
    if bar_index > 3
        if (high > nz(high[1]) and 
             nz(high[1]) > nz(high[2]) and
             nz(low[2]) < nz(low[3]) and 
             nz(low[3]) < nz(low[4]))
            swing := -1
            
        if (low < nz(low[1]) and 
             nz(low[1]) < nz(low[2]) and 
             nz(high[2]) > nz(high[3]) and 
             nz(high[3]) > nz(high[4]))
            swing :=  1
    
    swingBuffer = swing
    k = 0, n = 0
    while (k < bar_index) and (n < swingCount)
        if(swingBuffer[k] != 0) 
            n += 1
        k += 1
    albPeriod = math.max(math.round((speed != 0 and swingCount != 0) ? k/swingCount/speed : k/swingCount), 1)
    albPeriod
    
src = input.source(close, "Source", group = "Basic Settings")
type = input.string("SMA", "Source Smoothing Type", options = ["EMA", "WMA", "RMA", "SMA"], group = "Basic Settings")
inpPeriod = input.int(14, "RSI Period", group = "Basic Settings")
rsitype = input.string("Regular", "RSI Type", options = ["RSX", "Regular", "Slow", "Rapid", "Harris", "Cuttler", "Ehlers Smoothed"], group = "Basic Settings")

swingCount = input.int(5, "ALB Swing Count", group = "Adaptive Lookback Settings")
speed = input.float(0.5, "ALB Speed", group = "Adaptive Lookback Settings")

sigtype = input.string(SM03, "Signal type", options = [SM02, SM03], group = "Signal Settings")

lbR = input(title="Pivot Lookback Right", defval=5, group = "Divergences Settings")
lbL = input(title="Pivot 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=false, group = "Divergences Settings")
plotBear = input(title="Plot Bearish", defval=true, group = "Divergences Settings")
plotHiddenBear = input(title="Plot Hidden Bearish", defval=false, group = "Divergences Settings")
bearColor = darkRedColor
bullColor = darkGreenColor
hiddenBullColor = color.new(darkGreenColor, 80)
hiddenBearColor = color.new(darkRedColor, 80)
textColor = color.white
noneColor = color.new(color.white, 100)

colorbars = input.bool(true, "Color bars?", group = "UI Options")
showsignals = input.bool(true, "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"

variant(type, src, len) =>
    sig = 0.0
    if type == "SMA"
        sig := _iSMA(src, len) 
    else if type == "EMA"
        sig := _iEMA(src, len) 
    else if type == "WMA"
        sig := _iLWMA(src, len)   
    else if type == "RMA"
        sig := _iRMA(src, len)  
    sig
    
albout = _albper(swingCount, speed)
src := variant(type, src, albout)

rsi = loxxvarietyrsi.rsiVariety(rsimode, src, inpPeriod)
sig = nz(rsi[1])
mid = 50

state = 0.
if sigtype == SM02
    if (rsi<sig) 
        state :=-1
    if (rsi>sig) 
        state := 1
else if sigtype == SM03
    if (rsi<mid) 
        state :=-1
    if (rsi>mid)
        state := 1

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

plot(rsi, "RSI", color = colorout, linewidth = 2)
plot(mid, "Middle", color =  bar_index % 2 ? color.gray : na)

barcolor(colorbars ? colorout : na)

goLong = sigtype == SM02 ? ta.crossover(rsi, sig) :  ta.crossover(rsi, mid) 
goShort = sigtype == SM02 ? ta.crossunder(rsi, sig) :  ta.crossunder(rsi, mid)  

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

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




