The Moving Average Crossover Strategy — and How to Backtest It on Nifty
The moving average crossover is the “hello world” of systematic trading: one fast average, one slow average, and a rule that trades when they cross. It is simple enough to understand in a minute and structured enough to backtest and automate. Here is how it works — and how to test it on Nifty and Bank Nifty end to end.
What is a moving average crossover strategy?
A moving average smooths price into a single line so you can see the trend without the noise. A crossover strategy uses two of them — a shorter, faster average and a longer, slower one:
- When the fast average crosses above the slow average, momentum has turned up — a signal to go long.
- When the fast average crosses below the slow average, momentum has turned down — a signal to exit (or go short).
That is the whole idea. The art is in the details: which averages, which timeframe, and what filters you add to avoid false signals.
SMA or EMA?
A simple moving average (SMA) weights every bar equally. An exponential moving average (EMA) weights recent bars more heavily, so it reacts faster to a turn. For intraday index trading, most traders prefer the EMA because it catches momentum shifts sooner — at the cost of a few more whipsaws in choppy markets.
The 9/21 EMA crossover on Nifty and Bank Nifty
A popular intraday setup on Indian indices is the 9/21 EMA crossover: a 9-period fast EMA against a 21-period slow EMA, often on a 5- or 15-minute chart. A long triggers when the 9 EMA crosses above the 21 EMA; the position is closed when it crosses back below. It is popular because it is responsive enough for intraday moves without reacting to every tick.
A runnable example
Here is the 9/21 EMA crossover written in the SutraLipi language, on the 15-minute Bank Nifty. The same script backtests, paper-trades and trades live — unchanged.
EquitySymbol nifty = NSE:IDX:"NIFTY BANK";
float[] emaFast;
float[] emaSlow;
onTick {
INDICATOR_EMA(emaFast, nifty, M15, 9, 1);
INDICATOR_EMA(emaSlow, nifty, M15, 21, 1);
// fast crosses ABOVE slow -> go long
if (emaFast[1] <= emaSlow[1] && emaFast[0] > emaSlow[0]) {
OrderSend(nifty, BUY, 1, 0, 0, 0, INTRADAY, DAY, "ema cross up");
}
// fast crosses BELOW slow -> exit
if (emaFast[1] >= emaSlow[1] && emaFast[0] < emaSlow[0]) {
OrderCloseBySymbol(nifty, INTRADAY, DAY, "ema cross down");
}
}The [1] and [0] compare the previous bar to the current one — that is how you detect the exact moment of a cross rather than just “fast is above slow.” See the indicators reference for the full list of built-ins.
How to backtest it
Before trusting any crossover, backtest it across trending and ranging periods:
- Run the strategy on a few years of Bank Nifty history.
- Check the win rate and the max drawdown together — not profit alone.
- Validate on out-of-sample data you did not use while choosing 9 and 21.
- Include costs and slippage before believing the numbers.
Realistic expectations
Be honest about what a bare crossover delivers. On its own, raw crossover signals typically win somewhere around 45–50% of the time, because the same responsiveness that catches trends early also produces false signals in sideways markets. That is normal — a trend-following system makes its money from a few large winners, not a high hit rate.
The crossover's weakness is the ranging market, where price chops back and forth across both averages and generates a string of small losing trades (“whipsaws”). Every trend follower suffers this — managing it is the real work.
Making it better
Traders improve the base crossover with filters that keep it out of choppy conditions:
- A trend filter — only take longs when price is above a longer average (e.g. the 200 EMA), so you trade with the bigger trend.
- A volatility or volume filter — skip signals when the market is flat.
- Time-of-day rules — avoid the first few minutes and square off before close.
- A confirming timeframe — require the higher timeframe to agree.
Each filter cuts false signals at the cost of missing some real ones — the classic trade-off you tune with backtesting.
Try it yourself
Copy the script above into the SutraLipi platform, backtest it on Bank Nifty, then add a trend filter and compare. Prefer options? The same engine powers the options strategy builder for straddles, strangles and iron condors.
Try it on SutraLipi — free
Build, backtest and paper-trade the ideas in this guide without writing code.
Get Started FreeThis article is for education only and is not investment advice. Trading and investing in securities and derivatives carry risk of loss; past performance and backtested results do not guarantee future returns. Please read our Risk Disclosure Statement and consult a SEBI-registered adviser before trading.
