// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/kama-trend-filter/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
// Kaufman Adaptive Moving Average plus an efficiency-ratio filter that shades the chart as
// trending up, trending down or no trend. State changes are confirmed on bar close.
indicator("FXP KAMA Trend Filter", shorttitle = "FXP KAMA", overlay = true)

// ── Inputs ─────────────────────────────────────────────────────────────
grpK    = "KAMA"
src     = input.source(close, "Source", group = grpK)
erLen   = input.int(10, "Efficiency ratio length", minval = 2, group = grpK)
fastLen = input.int(2, "Fast EMA period", minval = 1, group = grpK)
slowLen = input.int(30, "Slow EMA period", minval = 2, group = grpK)

grpF        = "Trend filter"
erThreshold = input.float(0.30, "Trend threshold (ER)", minval = 0.0, maxval = 1.0, step = 0.01, group = grpF, tooltip = "Smoothed efficiency ratio at or above this value counts as trending.")
erSmooth    = input.int(3, "ER smoothing", minval = 1, group = grpF)
slopeBars   = input.int(3, "Slope lookback (bars)", minval = 1, group = grpF)

grpV        = "Display"
showBg      = input.bool(true, "Shade background by state", group = grpV)
showSignals = input.bool(true, "Show trend-start labels", group = grpV)
colBull     = input.color(#26a69a, "Uptrend color", group = grpV)
colBear     = input.color(#ef5350, "Downtrend color", group = grpV)
colFlat     = input.color(#9e9e9e, "No-trend color", group = grpV)
bgTransp    = input.int(88, "Background transparency", minval = 0, maxval = 100, group = grpV)

// ── Efficiency ratio ───────────────────────────────────────────────────
direction  = math.abs(src - src[erLen])
noise      = math.sum(math.abs(src - src[1]), erLen)
erRaw      = nz(noise > 0 ? direction / noise : 0.0)
erSmoothed = ta.sma(erRaw, erSmooth)

// ── KAMA ───────────────────────────────────────────────────────────────
fastSc = 2.0 / (fastLen + 1)
slowSc = 2.0 / (slowLen + 1)
sc     = math.pow(erRaw * (fastSc - slowSc) + slowSc, 2)

var float kama = na
kama := na(kama) ? src : kama + sc * (src - kama)

// ── Trend state: 1 up, -1 down, 0 no trend ─────────────────────────────
kamaSlope = kama - kama[slopeBars]
trending  = erSmoothed >= erThreshold
int state = trending and kamaSlope > 0 ? 1 : trending and kamaSlope < 0 ? -1 : 0
prevState = nz(state[1])

bullStart = state == 1 and prevState != 1 and barstate.isconfirmed
bearStart = state == -1 and prevState != -1 and barstate.isconfirmed
flatStart = state == 0 and prevState != 0 and barstate.isconfirmed

stateColor = state == 1 ? colBull : state == -1 ? colBear : colFlat

// ── Plots ──────────────────────────────────────────────────────────────
plot(kama, "KAMA", color = stateColor, linewidth = 2)
plot(erSmoothed, "Efficiency ratio", display = display.data_window)
bgcolor(showBg ? color.new(stateColor, bgTransp) : na, title = "Trend state background")

plotshape(showSignals and bullStart, "Uptrend start", style = shape.labelup, location = location.belowbar, color = colBull, text = "Up", textcolor = color.white, size = size.small)
plotshape(showSignals and bearStart, "Downtrend start", style = shape.labeldown, location = location.abovebar, color = colBear, text = "Down", textcolor = color.white, size = size.small)
plotshape(showSignals and flatStart, "No-trend start", style = shape.xcross, location = location.abovebar, color = colFlat, size = size.tiny)

// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(bullStart, "KAMA uptrend start", "KAMA filter switched to uptrend on {{ticker}} ({{interval}})")
alertcondition(bearStart, "KAMA downtrend start", "KAMA filter switched to downtrend on {{ticker}} ({{interval}})")
alertcondition(flatStart, "KAMA no-trend start", "KAMA filter switched to no-trend on {{ticker}} ({{interval}})")
