Jayadev Rana Get a custom script
Free Pine Script Indicators / EMA Trend Signals
Free indicator · Pine Script v6

EMA Trend Signals

Fast/slow EMA crossover signals filtered by a 200 EMA trend line, with a trend-coloured fill, non-repainting BUY/SELL labels and alert conditions.

IndicatorPine Script v6OverlayFree

Get the codeDownload .pine.txt

Snapshots

BUY and SELL labels only fire with the 200 EMA trend. Counter-trend crosses are skipped.
BUY and SELL labels only fire with the 200 EMA trend. Counter-trend crosses are skipped.
Trend EMA lowered from 200 to 50: a looser filter lets more signals through.
Trend EMA lowered from 200 to 50: a looser filter lets more signals through.
The full script next to the chart in the TradingView Pine Editor.
The full script next to the chart in the TradingView Pine Editor.

How it works

  1. Signals print only after the candle closes (barstate.isconfirmed), so they do not repaint.
  2. BUY needs a fast-over-slow EMA cross while price is above the Trend EMA; SELL is the mirror image.
  3. Create an alert on "EMA Trend Signals" and pick Buy or Sell, set to Once Per Bar Close.

Settings

SettingDefaultWhat it does
Fast EMA9Short-term momentum line
Slow EMA21Crossover reference line
Trend EMA200Only trade in this direction

Source code

In TradingView: open the Pine Editor, create a new indicator, paste the code, then click "Add to chart".

ema-trend-signals.pine.txtGitHubDownload
//@version=6
indicator("EMA Trend Signals", overlay = true)

// ── Inputs ─────────────────────────────
fastLen  = input.int(9,   "Fast EMA",  minval = 1)
slowLen  = input.int(21,  "Slow EMA",  minval = 1)
trendLen = input.int(200, "Trend EMA", minval = 1)

// ── Calculations ───────────────────────
fastEma  = ta.ema(close, fastLen)
slowEma  = ta.ema(close, slowLen)
trendEma = ta.ema(close, trendLen)

// ── Plots ──────────────────────────────
pFast = plot(fastEma, "Fast EMA", color.teal, 2)
pSlow = plot(slowEma, "Slow EMA", color.orange, 2)
plot(trendEma, "Trend EMA", color.gray, 3)

bullish = fastEma > slowEma
fill(pFast, pSlow, bullish ? color.new(color.teal, 80) : color.new(color.orange, 80))

// ── Signals ────────────────────────────
upTrend   = close > trendEma
downTrend = close < trendEma

buySignal  = ta.crossover(fastEma, slowEma)  and upTrend and barstate.isconfirmed
sellSignal = ta.crossunder(fastEma, slowEma) and downTrend and barstate.isconfirmed

plotshape(buySignal, "Buy", shape.triangleup, location.belowbar,
  color.teal, text = "BUY", textcolor = color.teal, size = size.small)
plotshape(sellSignal, "Sell", shape.triangledown, location.abovebar,
  color.orange, text = "SELL", textcolor = color.orange, size = size.small)

// ── Alerts ─────────────────────────────
alertcondition(buySignal,  "Buy",  "EMA Trend Signals: BUY on {{ticker}}")
alertcondition(sellSignal, "Sell", "EMA Trend Signals: SELL on {{ticker}}")

Watch it built

Every line of this indicator is written and explained in this Pine Script v6 lesson.

Need a custom indicator or strategy?

Non-repainting Pine Script v6, backtested with real costs, alert and webhook ready. Fixed quote within 24 hours.

Free and open source under the Mozilla Public License 2.0. Educational content only, not financial advice. Backtest results are historical and include the costs stated; past performance does not predict future results. © Jayadev Rana · Privacy · Terms