Synthetic EMA Momentum w/ DSL [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("Synthetic EMA Momentum w/ DSL [Loxx]", 
     shorttitle='SEMAMDSL [Loxx]', 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)

import loxx/loxxexpandedsourcetypes/4

greencolor = #2DD204
redcolor = #D2042D 

lightgreencolor = #96E881 
lightredcolor =  #DF4F6C

SM02 = 'Levels Crosses'
SM03 = 'Middle Crosses'

smthtype = input.string("Kaufman", "Heikin-Ashi Better Caculation Type", options = ["AMA", "T3", "Kaufman"], group = "Source Settings")

srcin = input.string("Close", "Source", group= "Source Settings", 
     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)"])

inpPeriod1  = input.int(5, "Period 1", group = "Basic Settings")
inpPeriod2  = input.int(20, "Period 2", group = "Basic Settings")
inpPeriod3  = input.int(50, "Period 3", group = "Basic Settings")
inpPeriod4  = input.int(100, "Period 4", group = "Basic Settings")
inpPeriod5  = input.int(200, "Period 5", group = "Basic Settings")

inpSignal   = input.int(20, "Signal Period", group = "Signal/DSL Settings")
sigtype = input.string(SM02, "Signal type", options = [SM02, SM03], group = "Signal/DSL 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")

haclose = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)
haopen = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, open)
hahigh = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, high)
halow = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, low)
hamedian = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hl2)
hatypical = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlc3)
haweighted = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlcc4)
haaverage = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, ohlc4)

src = switch srcin
	"Close" => loxxexpandedsourcetypes.rclose()
	"Open" => loxxexpandedsourcetypes.ropen()
	"High" => loxxexpandedsourcetypes.rhigh()
	"Low" => loxxexpandedsourcetypes.rlow()
	"Median" => loxxexpandedsourcetypes.rmedian()
	"Typical" => loxxexpandedsourcetypes.rtypical()
	"Weighted" => loxxexpandedsourcetypes.rweighted()
	"Average" => loxxexpandedsourcetypes.raverage()
    "Average Median Body" => loxxexpandedsourcetypes.ravemedbody()
	"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)
	=> haclose
	
coeff1 = float(inpPeriod5 / inpPeriod4)
coeff2 = float(inpPeriod5 / inpPeriod3)
coeff3 = float(inpPeriod5 / inpPeriod2)

avg   = ta.ema(src, inpPeriod1)
avg1  = ta.ema(src, inpPeriod2)
mom1 = 100. * (avg - avg1) / avg1

avg2  = ta.ema(src, inpPeriod3) 
mom2 = 100. * (avg - avg2) / avg2

avg3  = ta.ema(src, inpPeriod4)
mom3 = 100. * (avg - avg3) / avg3

avg4  = ta.ema(src, inpPeriod5)
mom4 = 100. * (avg - avg4) / avg4

val  = (mom4 + mom3 * coeff1 + mom2 * coeff2 + mom1 * coeff3) / 4.0
sig = val[1]
mid = 0

dslupl = 0., dsldnl = 0.
tempu = ta.ema(val, inpSignal)

dslupl := val > 0 ? tempu : nz(dslupl[1])
dsldnl :=  val < 0 ? tempu : nz(dsldnl[1])

state = 0.
if sigtype == SM02
    if (val < dsldnl) 
        state :=-1
    if (val > dslupl)
        state := 1
else if sigtype == SM03
    if (val < mid) 
        state :=-1
    if (val > mid)
        state := 1
        
colorout = state == 1 ? greencolor : state == -1 ? redcolor : color.gray

plot(val, "Synthetic Super Smoother Momentum", color = colorout, linewidth = 3)
plot(dslupl, "DSL Level Up", color = lightgreencolor)
plot(dsldnl, "DSL Level Down", color = lightredcolor)
plot(mid, "Middle", color = bar_index % 2 ? color.gray : na)

barcolor(colorbars ? colorout : na)

goLong_pre =  sigtype == SM02 ? ta.crossover(val, dslupl) : ta.crossover(val, mid) 
goShort_pre = sigtype == SM02 ? ta.crossunder(val, dsldnl) :  ta.crossunder(val, mid) 

contSwitch = 0
contSwitch := nz(contSwitch[1])
contSwitch := goLong_pre ? 1 : goShort_pre ? -1 : contSwitch


goLong = contSwitch == 1 and ta.change(contSwitch)
goShort =  contSwitch == -1 and ta.change(contSwitch)


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="Synthetic EMA Momentum w/ DSL [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Synthetic EMA Momentum w/ DSL [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")



