Smoother Momentum Stops [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("Smoother Momentum Stops [Loxx]", 
     overlay = true, 
     timeframe="", 
     timeframe_gaps = true)

color greencolor = #2DD204
color redcolor = #D2042D 

smmom(float src, float per)=>
    float alphareg = 2.0 / (1.0 + per)
    float alphadbl = 2.0 / (1.0 + math.sqrt(per))
    float ema = src 
    float ema21 = src
    float ema22 = src
    if bar_index > 0
        ema := nz(ema[1]) + alphareg * (src - nz(ema[1]))
        ema21 := nz(ema21[1]) + alphadbl * (src - nz(ema21[1]))
        ema22 := nz(ema22[1]) + alphadbl * (ema21 - nz(ema22[1]))
    float out = (ema22 - ema)
    out

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

variant(typein, src, per)=>
    float out = 0.
    if typein == "Exponential Moving Average - EMA"
        out := ta.ema(src, per)
    if typein == "Fast Exponential Moving Average - FEMA"
        out := fema(src, per)
    if typein ==  "Linear Weighted Moving Average - LWMA"
        out := ta.wma(src, per)
    if typein ==  "Simple Moving Average - SMA"
        out := ta.sma(src, per)
    if typein ==  "Smoothed Moving Average - SMMA"
        out := ta.rma(src, per)
    out

float inpPrice = input.source(close, "Source", group = "Basic Settings")
int inpMomPeriod = input.int(20, "Momentum Period", group = "Basic Settings")
int inpAvgPeriod = input.int(20, "Average Period", group = "Basic Settings") 
string inpAvgMethod = input.string("Simple Moving Average - SMA", "Smoothing Type",
     options = ["Exponential Moving Average - EMA", 
     "Fast Exponential Moving Average - FEMA", 
     "Linear Weighted Moving Average - LWMA", 
     "Simple Moving Average - SMA", 
     "Smoothed Moving Average - SMMA"], 
     group = "Basic Settings") 
float inpMultiplier = input.float(1.5, "Multiplier", group = "Basic Settings")

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

_avg = variant(inpAvgMethod, inpPrice, inpAvgPeriod)
_mom = inpMultiplier * smmom(inpPrice, inpMomPeriod)

float stopu = na
float stopd = na
float stopda = na
float stopua = na

if _mom > 0 
    stopu := na(stopu[1]) ? _avg - _mom : math.max(nz(stopu[1]), _avg - _mom)  
    stopd := na
    stopda := na
    stopua := na(stopu[1]) ? stopu : na  

if _mom < 0
    stopd := na(stopd[1]) ? _avg - _mom : math.min(nz(stopd[1]), _avg - _mom)  
    stopu := na
    stopua := na
    stopda := na(stopd[1]) ? stopd : na  

colorout = stopu ? greencolor : redcolor

goLong = stopu and stopd[1]
goShort = stopd and stopu[1]

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

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

plot(stopu ? stopu : na, "Upper", color = greencolor, linewidth = 2, style = plot.style_linebr)
plot(stopd ? stopd : na, "Lower", color = redcolor, linewidth = 2, style = plot.style_linebr)

float support = ta.valuewhen(stopua, stopua, 0)
float resistance = ta.valuewhen(stopda, stopda, 0)

plot(resistance, style = plot.style_circles, color = redcolor)
plot(support, style = plot.style_circles, color = greencolor)

barcolor(colorbars ? colorout : na)