PipLedger
Today's forex newsNFP, CPI, FOMC and other high-impact eventsEconomic calendarCalendar →

9 and 21 EMA crossover strategy: rules, exits and a free Pine Script

The 9 and 21 EMA crossover is one of the simplest trend strategies there is: buy when the fast 9-period EMA crosses above the slower 21-period EMA, sell when it crosses below. It catches trends well and gets chopped up when the market goes sideways. Here's how it works, rules with a trend filter, a worked EURUSD example comparing two exits, and a free TradingView script.

By M. A. Horaira. Updated 5 October 2026. 11 minute read.

The rules at a glance

  • Indicators: a 9-period EMA, a 21-period EMA and a 200-period EMA as the trend filter
  • Long: the 9 EMA crosses above the 21 EMA at a candle close, with the price above the 200 EMA
  • Short: the 9 EMA crosses below the 21 EMA at a candle close, with the price below the 200 EMA
  • Stop loss: the lowest low of the last 10 candles for a long (highest high for a short), or 1.5 × ATR
  • Exit: when the EMAs cross back the other way, or at a fixed 2R target; you choose in the settings

What an EMA is

An exponential moving average (EMA) is an average of recent closing prices that gives more weight to the newest ones. Each new close moves it by a fixed share of the gap between the close and the previous EMA. That share is 2 ÷ (period + 1): 0.20 for a 9 EMA and about 0.09 for a 21 EMA. So the 9 EMA turns quickly with the price and the 21 EMA follows more slowly.

When the price starts trending up, the fast line moves first and crosses above the slow line. When the trend fades and the price turns down, the fast line crosses back below. The crossover strategy simply trades those crosses.

Why 9 and 21?

There's nothing special about these two numbers. They're popular and show up in a lot of trading courses, and 8 and 21 (both Fibonacci numbers) is also widely used. What matters is the gap between them: the fast line has to be quick enough to catch a turn, and the slow line slow enough to ignore small wiggles. The script lets you change both, so you can test 8/21, 10/20 or anything else on your own market.

The rules, step by step

1. Add three EMAs

A 9 EMA and a 21 EMA for the signals, and a 200 EMA for the trend. The 200 EMA is the filter: above it, only longs; below it, only shorts.

2. Wait for a cross at a candle close

The signal is a candle that closes with the 9 EMA on the other side of the 21 EMA from where it was on the previous close. Lines that touch during a candle and separate again don't count.

3. Place the stop

For a long, use the lowest low of the last 10 candles; for a short, the highest high. That puts the stop beyond the swing the cross came out of. The other choice in the script is 1.5 × the 14-period ATR from the entry, which adapts to how much the market is moving.

4. Choose your exit

The classic exit is the opposite cross: hold the long until the 9 EMA crosses back below the 21 EMA. It rides long trends but gives back part of the move, because the cross comes late. The other exit is a fixed target at twice the risk, which banks the profit sooner and misses the long runs. You'll see both in the example.

5. Size from the stop

Risk the same 0.5% to 1% on every trade and work out the lot size from the stop distance. The script does this automatically.

Worked example: EURUSD, 1-hour chart

2R target 1.1724Entry 1.1656Stop 1.16229 crosses above 212RExit: 9 below 21

9 EMA 21 EMA

Illustrative chart drawn for this guide to show the rules. It isn't a real day's prices. EURUSD, 1-hour candles. The 200 EMA is left out to keep it readable.

After a slide, EURUSD bases and starts to climb, and the candle that closes at 1.1656 takes the 9 EMA above the 21 EMA. The lowest low of the last 10 candles is 1.1622, 34 pips below. With $100 of risk that's $100 ÷ (34 × $10) = 0.29 lots, or $2.90 a pip, and a $98.60 loss if the stop is hit.

Same entry (1.1656) and stop (1.1622), two different exits
ExitWhere it closesTime in the tradeResult on 0.29 lots
Opposite cross1.169842 hours+42 pips, $121.80 (about 1.2R)
Fixed 2R target1.172423 hours+68 pips, $197.20 (2R)

Here the 2R target wins: the price runs through 1.1724 to about 1.1745, then stalls and turns, and by the time the 9 EMA crosses back below the 21 EMA, a good part of the move has gone. In a long, smooth trend it works the other way round, and the cross exit holds on for far more than 2R. Neither exit is better in general, which is why the script lets you test both on your own pair. The 200 EMA isn't drawn; under these rules the long only counts if the price is above it at the cross, so assume it is here. After a slide like this it often isn't, and the filter would skip the trade.

Crossovers lag, and that has a cost

Moving averages are built from past prices, so a crossover always comes after the turn has started. In a strong trend that doesn't matter much, because there's plenty of move left. In a sideways market it's the whole problem: the two lines cross back and forth, and each cross is a small loss plus the spread. For crossover systems, most losses tend to come from those flat stretches; your backtest will show how much.

You can't remove the lag, but you can avoid some of the chop:

Only the first filter is built into the script. Test the others by hand before you add them.

Risk management

Common mistakes

  1. Acting before the candle closes. The EMAs can cross and uncross several times inside one candle.
  2. Trading every cross in a range. If the two lines are flat and tangled together, there's no trend to follow.
  3. Moving the stop to break-even too soon. Trends pull back. A stop at entry gets hit by the first normal dip.
  4. Changing settings after every loss. 9/21 one week, 5/13 the next: you never learn whether any of them work. Test, choose, then stick with it for a decent sample.

Backtest it yourself on TradingView

This page doesn't quote a win rate or a profit figure, and you should be wary of anyone who does without showing the test. Results change with the market, the dates, the data feed and the costs you put in. The honest way is to run the test yourself, and the free script below does the work in a couple of minutes.

  1. Open the chart. On TradingView, open EURUSD on the 1-hour chart.
  2. Add the script. Open the Pine Editor from the Pine icon in the panel on the right of the chart (older layouts have it as a tab under the chart), delete the code that's already there, paste this strategy's code and click "Add to chart".
  3. Put in your costs. Open the strategy's settings and go to Properties. Enter your broker's commission and a little slippage. A test without costs flatters every strategy, and short-term ones most of all.
  4. Read the Strategy Tester. The panel under the chart shows the net profit, the maximum drawdown, the profit factor, the number of trades and a list of every trade. Click a few trades and check on the chart that each one follows the rules. Trade sizes are shown in units rather than lots: 100,000 units is one lot of a forex pair, and 100 ounces is one lot of gold.
  5. Change one setting at a time. Compare the two exits first, then the swing stop with the ATR stop, the 200 EMA filter on and off, and other pairs of EMA lengths such as 8/21. Run the same settings on the 15-minute and 4-hour charts; crossover systems usually behave very differently across timeframes.

As a rough guide, don't trust a result with fewer than 100 trades, a profit factor under 1 once costs are in, or a drawdown you couldn't sit through with real money. Settings tuned to look good on one stretch of history often fail on the next, so check the same settings on dates you didn't tune them on, then demo trade the strategy for a few weeks.

The script sizes each trade from the stop loss and your risk percentage, starts with $10,000 and assumes 1:100 leverage (a 1% margin setting), so the tester doesn't flag margin calls on normal forex trade sizes. Change these under Properties to match your account. By default TradingView fills orders at the open of the candle after the signal, so the fill can differ a little from the signal candle's close. In either exit mode, the script reverses straight away when an opposite cross gives a new signal in the trend's direction.

Download the free Pine Script and PDF

The script is written in Pine Script version 6 for this guide and follows the rules above. It can't read the economic calendar, so skipping news days is up to you. It's free to use, change and share. The PDF is a one-page cheat sheet with the rules, a worked example with both exits, the lot size maths and a checklist, to keep next to your chart.

Show the code (Pine Script v6, 70 lines)
//@version=6
// 9 and 21 EMA Crossover strategy by PipLedger (https://pipledgerfx.com/9-21-ema-crossover-strategy)
// Buys when the 9 EMA crosses above the 21 EMA, sells on the opposite cross, with an optional 200 EMA trend filter.
// Free to use and change. For education and backtesting only; not financial advice.
strategy("PipLedger: 9 and 21 EMA Crossover", shorttitle="9/21 EMA", overlay=true, initial_capital=10000, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=1, margin_long=1, margin_short=1, currency=currency.USD)

// ---------- Inputs
fastLen   = input.int(9, "Fast EMA", minval=1)
slowLen   = input.int(21, "Slow EMA", minval=2)
useTrend  = input.bool(true, "Only trade in the direction of the trend EMA")
trendLen  = input.int(200, "Trend EMA", minval=10)
stopType  = input.string("Swing", "Stop loss", options=["Swing", "ATR"])
swingBars = input.int(10, "Swing lookback (bars)", minval=2)
atrMult   = input.float(1.5, "ATR multiple (for the ATR stop)", minval=0.1, step=0.1)
exitMode  = input.string("Opposite cross", "Exit", options=["Opposite cross", "R multiple"])
rr        = input.float(2.0, "Target (R multiple, when used)", minval=0.5, step=0.25)
riskPct   = input.float(1.0, "Risk per trade (% of equity)", minval=0.1, maxval=5.0, step=0.1)

// ---------- Helpers
fx = strategy.convert_to_account(1.0)  // one unit of the chart's quote currency in account currency (1 on USD-quoted charts)
calcQty(float entry, float stop) =>
    float dist = math.abs(entry - stop)
    dist > 0 and not na(fx) ? strategy.equity * riskPct / 100 / (dist * syminfo.pointvalue * fx) : 0.0

emaF   = ta.ema(close, fastLen)
emaS   = ta.ema(close, slowLen)
emaT   = ta.ema(close, trendLen)
atr    = ta.atr(14)
lowSw  = ta.lowest(low, swingBars)
highSw = ta.highest(high, swingBars)
bull   = ta.crossover(emaF, emaS)
bear   = ta.crossunder(emaF, emaS)

longSig  = bull and (not useTrend or close > emaT)
shortSig = bear and (not useTrend or close < emaT)
longSl   = stopType == "Swing" ? lowSw : close - atr * atrMult
shortSl  = stopType == "Swing" ? highSw : close + atr * atrMult
longQty  = calcQty(close, longSl)
shortQty = calcQty(close, shortSl)
longGo   = longSig and longSl < close and longQty > 0
shortGo  = shortSig and shortSl > close and shortQty > 0

// ---------- Exits on the opposite cross (skipped when the same cross opens a trade the other way: that reverses the position)
if exitMode == "Opposite cross"
    if bear and strategy.position_size > 0 and not shortGo
        strategy.close("Long", comment="9 EMA crossed below 21")
    if bull and strategy.position_size < 0 and not longGo
        strategy.close("Short", comment="9 EMA crossed above 21")

// ---------- Entries (an entry against an open trade reverses it, in either exit mode)
if longGo and strategy.position_size <= 0
    strategy.entry("Long", strategy.long, qty=longQty)
    if exitMode == "R multiple"
        strategy.exit("Long exit", "Long", stop=longSl, limit=close + (close - longSl) * rr)
    else
        strategy.exit("Long stop", "Long", stop=longSl)

if shortGo and strategy.position_size >= 0
    strategy.entry("Short", strategy.short, qty=shortQty)
    if exitMode == "R multiple"
        strategy.exit("Short exit", "Short", stop=shortSl, limit=close - (shortSl - close) * rr)
    else
        strategy.exit("Short stop", "Short", stop=shortSl)

// ---------- Chart
plot(emaF, "9 EMA", color=color.new(color.teal, 0), linewidth=2)
plot(emaS, "21 EMA", color=color.new(color.orange, 0), linewidth=2)
plot(useTrend ? emaT : na, "Trend EMA", color=color.new(color.gray, 0))
plotshape(longSig, "Bullish cross", shape.triangleup, location.belowbar, color.teal, size=size.small)
plotshape(shortSig, "Bearish cross", shape.triangledown, location.abovebar, color.red, size=size.small)

Trading this from India

Residents can trade EURUSD, GBPUSD and USDJPY futures and options on NSE and BSE through a SEBI-registered broker. The contracts are quoted the same way as the spot pair, one lot is 1,000 units of the base currency, and they're cash-settled in rupees. They trade only from 9 a.m. to 7:30 p.m. IST, volumes are thin and not every broker offers them, so check the hours and the spread first. Trading forex or CFDs with offshore online platforms isn't allowed for residents under FEMA, even if the app is easy to download. Details are in is forex trading legal in India.

The script doesn't use pips, so it runs unchanged on index charts such as the Nifty 50 and Bank Nifty on TradingView.

More strategies with free Pine Scripts: London breakout, break and retest, liquidity sweep, XAUUSD scalping.

Quick answers

What is the 9 and 21 EMA crossover strategy?

It's a trend-following strategy that buys when the 9-period EMA crosses above the 21-period EMA and sells when it crosses below. A 200 EMA is often added so that you only buy above it and only sell below it.

Which timeframe is best for the 9/21 EMA crossover?

There isn't one best timeframe. Intraday traders often use the 15-minute or 1-hour chart and swing traders the 4-hour or daily. Lower timeframes give more signals, more noise and higher costs per trade. Backtest a few and pick the one that suits your schedule.

Is the 9 and 21 EMA good for scalping?

On the 1- and 5-minute charts the crosses come often and the stops are small, so the spread and commission eat a big share of each trade. It can be done, but test it with realistic costs first; the scalping guide on this site shows how costs add up.

Is an EMA crossover better than an SMA crossover?

An EMA reacts faster because it weights recent prices more, so it signals earlier and also gives more false signals. A simple moving average (SMA) is slower and smoother. Neither is better in general; it depends on the market and timeframe you trade.

What is the difference between the 9/21 cross and the golden cross?

The golden cross is the 50-day moving average crossing above the 200-day, a slow signal for long-term trends. The 9/21 cross is much faster and is mostly used for short-term trading.

Should I exit on the opposite cross or at a fixed target?

The opposite cross lets winners run in long trends but gives back part of each move. A fixed target such as 2R takes profit sooner but caps your best trades. The script has both, so you can compare them on your own market.

More guides

All 46 guides →

हिंदी में पढ़ें: Lot size kaise nikale?, Prop firm challenge kaise pass kare?, Gold trading kaise kare?, Forex trading kya hai, और India में यह legal है या नहीं?

Trading psychology

The habits that decide whether a good strategy makes money.

All 14 trading psychology guides

8 popular prop firms

Well-known firms for forex, gold and index traders that were still operating in 2026. Compare their rules before you buy a challenge.

If a link in this list is a referral link, PipLedger may earn a commission if you sign up, at no extra cost to you. This list is not a recommendation. Programs, prices and rules change often, so check each firm's own site, including its margin and drawdown rules, before you buy a challenge.