Zero-lag TEMA Crosses [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("Zero-lag TEMA Crosses [Loxx]",
     overlay = true, 
     timeframe="", 
     timeframe_gaps = true)

greencolor = #2DD204
redcolor = #D2042D 
bluecolor = #042dd2

import loxx/loxxexpandedsourcetypes/4

zlagtema(float src, simple int len)=>
    float ema1 = ta.ema(src, len)
    float ema2 = ta.ema(ema1, len)
    float ema3 = ta.ema(ema2, len)
    float out = 3 * (ema1 - ema2) + ema3
    float ema1a = ta.ema(out, len)
    float ema2a = ta.ema(ema1a, len)
    float ema3a = ta.ema(ema2a, len)
    float outf = 3 * (ema1a - ema2a) + ema3a
    outf

smthtype = input.string("Kaufman", "HAB Calc Type", options = ["AMA", "T3", "Kaufman"], group='Source 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='Source Settings')

inpPeriodFast = input.int(22, "Fast Period", group = "Basic Settings")
inpPeriodSlow = input.int(144, "Slow Period", group = "Basic 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

temafast = zlagtema(sourceout(smthtype, srcin), inpPeriodFast)
temaslow = zlagtema(sourceout(smthtype, srcin), inpPeriodSlow)

colorout = temafast > temaslow ? greencolor : redcolor
plot(temafast, "Zero-lag TEMA Crosses Fast", color = colorout, linewidth = 2)
plot(temaslow, "Zero-lag TEMA Crosses Slow", color = color.white, linewidth = 1)

barcolor(colorbars ? colorout : na)

goLong = ta.crossover(temafast, temaslow)
goShort = ta.crossunder(temafast, temaslow)

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

alertcondition(goLong, title="Long", message="Zero-lag TEMA Crosses [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Zero-lag TEMA Crosses [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")