Markets › Futures & Metals · ES, NQ and GC futures (1-hour bars)
EMA 9/21 Crossover Backtest: 1H Bars on ES, NQ & Gold Futures
The 9-bar exponential average crossing the 21-bar one on 1-hour bars of S&P 500, Nasdaq-100 and gold futures, around the clock, with and without a stop and a target.
Buried · No proven edgeCrossed about 5,000 times. Proved nothing.
Variants tried: 12 · Passed every gate: 0 · Holdout opened: yes (not clean)
Short answer: not in this test. We backtested the EMA 9/21 crossover on 1-hour ES, NQ and gold futures in 12 variants, with and without a stop and a target, net of costs. None passed every gate: the highest development t-statistic was 1.98 and 2.5 was needed. The long-only no-stop versions made money after costs (ES +35 R, NQ +175 R, gold +209 R), and gold came closest.How much costs took here, compared across all 54 of our tests →Did the same rules work on other markets? The cross-market scoreboard →Compare all 14 gold strategies we tested →
00The verdict in three lines
- The EMA 9/21 crossover is the most common short-term moving-average rule: buy when the 9-bar exponential average crosses above the 21-bar one, sell when it crosses below. We ran it on 1-hour bars of three futures markets (ES, NQ and gold), long only and long and short, with no stop and with a 1 R stop and a 2 R target: 12 variants in all, with the rules, gates, costs and a matched shifted-state control fixed in a dated specification before any EMA 9/21 value was computed.
- None passed. Every variant failed the development t-statistic of 2.5 (the highest was 1.98). The long-only no-stop versions made money after costs in all three markets (ES +35 R, NQ +175 R, gold +209 R); the shorts lost money in all three, and the stop and target made every long-only version worse.
- Gold came closest. The long-only and the long-and-short no-stop gold versions passed five of six gates, including the shifted-state control (percentiles 95.6 and 95.2), and failed only the development t-statistic (1.08 and 0.71). About two thirds of each result (68% and 64%) came in 2024 to 2026, when gold itself moved +$177,560 per contract (buy and hold, no costs) against +$29,810 over 2020 to 2023; the development years alone did not support the result.
01What we tested
The rule: EMA(9) and EMA(21) of the 1-hour closes (each seeded with a simple average, then ema = a x close + (1 - a) x previous ema with a = 2 / (n + 1)). A golden cross at the close of a bar (the 9 moves above the 21) opens a long at the next 1-minute open; a death cross closes it and, in the long-and-short versions, opens a short; the opposite cross is the exit. All 24 hours, positions held over weekends. Exits and R are those of our 1-hour golden cross test: 1 R = 1.5 times the 14-bar ATR at the signal bar; the stop wins a tie; a level gapped through fills at the open; slippage on every fill. The four variants per market are long only (L) and long and short (LS), each with N (no stop, no target) and T2 (stop 1 R, target 2 R). We tested one pair of periods and one timeframe on purpose; nothing else was tried.
Background. We tested an EMA 9/20 plus TDI system on ES 1-minute bars before, without a frozen specification: it lost money in every year (profit factor 0.52 to 0.79). That was a different rule, on a different timeframe, with an indicator filter and discretionary exits. The plain 9/21 crossover on 1-hour bars had not been tested under the protocol.
02Data and costs
Back-adjusted continuous 1-minute futures history from NinjaTrader, built into about 39,787 hourly bars per market, 1 Jan 2020 to 25 Sep 2026 (the same cut-off for all three). Periods: development 2020 to 2023, validation January 2024 to March 2025, holdout April 2025 to September 2026. The holdout is not clean: the ES data appeared in earlier tests on this site, and the three markets move together, so NQ and gold are not independent of ES. Costs: $5.76 commission plus one tick of slippage on each fill, which is $30.76 a trade on ES, $15.76 on NQ and $25.76 on gold, and the same amount again for each contract roll a position is held through. The same commission for the three products is an assumption, not a broker quote. For scale, one contract bought on 2 Jan 2020 and held to the end made +$187,438 on ES, +$369,260 on NQ and +$208,580 on gold, with no costs.
Engine check: before the run, em_selftest.js checked a hand-worked example of the averages and signals, matched the engine's averages and signals to a naive recomputation on the real bars of each market, and matched an independent re-implementation of the trade simulation (with each market's costs and roll dates) trade by trade for all four variants on all three markets (em_selftest_result.txt). It printed pass or fail only, no result. The shared engine was changed in three additive ways for this test (another moving average, a market's own roll dates, a narrowed variant list) and passed its own self-test again.
03Results: all 12 variants
Net R is the sum of the trades' results in R after costs, and gross R is the same before costs; the profit factor and t-statistic use net R. Dollars are per contract. The 95% range is the Wilson interval for the win rate. Every variant has between 815 and 1,720 trades, so the sample-size rule never applied.
| Variant | Trades | Net after costs | R per trade | Gross, before costs | $ per contract | Winners (95% range) | Profit factor | Holdout* net | Verdict |
|---|---|---|---|---|---|---|---|---|---|
| ES EM-L-N | 837 | +35 R | +0.04 R | +65.6 R | +$33,742 | 275 of 837 (30% to 36%) | 1.05 | +5 R | Buried |
| ES EM-L-T2 | 837 | +31 R | +0.04 R | +61.2 R | +$23,267 | 287 of 837 (31% to 38%) | 1.06 | +18 R | Buried |
| ES EM-LS-N | 1,674 | -65 R | -0.04 R | -1.9 R | -$120,548 | 484 of 1674 (27% to 31%) | 0.95 | -43 R | Buried |
| ES EM-LS-T2 | 1,674 | -28 R | -0.02 R | +34.7 R | -$63,294 | 532 of 1674 (30% to 34%) | 0.97 | -4 R | Buried |
| NQ EM-L-N | 815 | +175 R | +0.21 R | +183.0 R | +$286,041 | 286 of 815 (32% to 38%) | 1.29 | +32 R | Buried |
| NQ EM-L-T2 | 815 | +59 R | +0.07 R | +67.0 R | +$113,797 | 280 of 815 (31% to 38%) | 1.13 | +39 R | Buried |
| NQ EM-LS-N | 1,630 | +133 R | +0.08 R | +150.5 R | +$201,381 | 505 of 1630 (29% to 33%) | 1.11 | -14 R | Buried |
| NQ EM-LS-T2 | 1,630 | +38 R | +0.02 R | +55.1 R | +$85,861 | 524 of 1630 (30% to 34%) | 1.04 | +37 R | Buried |
| GC EM-L-N | 860 | +209 R | +0.24 R | +235.7 R | +$242,668 | 252 of 860 (26% to 32%) | 1.34 | +62 R | Buried |
| GC EM-L-T2 | 860 | -7 R | -0.01 R | +19.3 R | -$90 | 267 of 860 (28% to 34%) | 0.99 | -10 R | Buried |
| GC EM-LS-N | 1,720 | +160 R | +0.09 R | +212.9 R | +$280,407 | 494 of 1720 (27% to 31%) | 1.13 | +51 R | Buried |
| GC EM-LS-T2 | 1,720 | -8 R | 0.00 R | +44.3 R | +$20,592 | 534 of 1720 (29% to 33%) | 0.99 | +10 R | Buried |
Cumulative net R by month for the long-only no-stop version in each market (R is a different dollar size in each market). * Holdout already used before this test. PF = profit factor.
Net R by period
| Variant | Development 2020 to 2023 | Validation 2024 to Mar 2025 | Holdout* Apr 2025 to Sep 2026 | Development t |
|---|---|---|---|---|
| ES EM-L-N | +40 R | -10 R | +5 R | 0.75 |
| ES EM-L-T2 | +15 R | -2 R | +18 R | 0.51 |
| ES EM-LS-N | +23 R | -45 R | -43 R | 0.27 |
| ES EM-LS-T2 | -10 R | -14 R | -4 R | -0.24 |
| NQ EM-L-N | +112 R | +30 R | +32 R | 1.98 |
| NQ EM-L-T2 | +28 R | -9 R | +39 R | 0.96 |
| NQ EM-LS-N | +109 R | +38 R | -14 R | 1.38 |
| NQ EM-LS-T2 | +11 R | -10 R | +37 R | 0.27 |
| GC EM-L-N | +67 R | +80 R | +62 R | 1.08 |
| GC EM-L-T2 | -10 R | +13 R | -10 R | -0.33 |
| GC EM-LS-N | +57 R | +52 R | +51 R | 0.71 |
| GC EM-LS-T2 | +2 R | -20 R | +10 R | 0.04 |
04With and without a stop and a target, long and short
Net R over the whole period. The last column is the average gross result per trade in R before costs, then the average cost per trade in R, for the long-only no-stop version.
| Market | Long only, no stop | Long only, stop 1 R and target 2 R | How the T2 trades ended | Long and short, no stop | Long and short, T2 | Gross / cost per trade (long only, no stop) |
|---|---|---|---|---|---|---|
| ES | +35.0 R | +30.8 R | stop 394 · target 259 · signal 184 | -65.2 R | -28.0 R | +0.08 R / 0.04 |
| NQ | +174.7 R | +58.7 R | stop 399 · target 260 · signal 155 · open 1 | +133.4 R | +38.2 R | +0.22 R / 0.01 |
| GC | +209.1 R | -7.1 R | stop 390 · target 250 · signal 220 | +159.7 R | -8.3 R | +0.27 R / 0.03 |
The stop and target made every long-only version worse than the same entries with no stop: ES +31 R against +35 R, NQ +59 R against +175 R, gold -7 R against +209 R. Between 45% and 49% of the T2 trades ended at the stop and between 29% and 32% at the target. Costs are small relative to R here (about 0.04 R on ES, 0.01 R on NQ, 0.03 R on gold per trade), so they are not what decides these results.
Longs and shorts separately (long and short, no stop)
| Market | Long trades | Long net R | Short trades | Short net R |
|---|---|---|---|---|
| ES | 837 | +35.0 R | 837 | -100.2 R |
| NQ | 815 | +174.7 R | 815 | -41.3 R |
| GC | 860 | +209.1 R | 860 | -49.4 R |
The short side lost money in all three markets, all three of which rose over the period. Adding shorts took the no-stop result from +35 R to -65 R on ES, from +175 R to +133 R on NQ and from +209 R to +160 R on gold.
05Is it the signal or the market?
The benchmark is a circularly shifted state-series control, not a random-entry test. The state is +1 while the 9-bar average is above the 21-bar one and -1 while it is below; the real state series is shifted by a random offset of at least 5% of its length, so the same up and down episodes fall on other dates, while the real prices, the same entry, stop, target and exit rules and the same costs are applied and the ATR-based R (and every stop and target distance) is recomputed at the shifted signal time from the real prices. This is done 500 times with fixed seeds. The bar is the 95th percentile of the average net R per trade. In a market that rose, being long at random times already makes money: the control medians for the long-only no-stop versions are +0.06 R (ES), +0.13 R (NQ) and +0.12 R (gold) per trade.
| Variant | Trades | Real average per trade | Control median | Control 5th to 95th | Percentile (95 needed) |
|---|---|---|---|---|---|
| ES EM-L-N | 837 | +0.04 R | +0.06 R | -0.04 R to +0.18 R | 39.6 |
| ES EM-L-T2 | 837 | +0.04 R | -0.01 R | -0.08 R to +0.04 R | 92.6 |
| ES EM-LS-N | 1,674 | -0.04 R | -0.03 R | -0.13 R to +0.09 R | 45.8 |
| ES EM-LS-T2 | 1,674 | -0.02 R | -0.04 R | -0.09 R to +0.01 R | 77.4 |
| NQ EM-L-N | 815 | +0.21 R | +0.13 R | +0.02 R to +0.25 R | 88.8 |
| NQ EM-L-T2 | 815 | +0.07 R | +0.02 R | -0.04 R to +0.09 R | 90.0 |
| NQ EM-LS-N | 1,630 | +0.08 R | 0.00 R | -0.09 R to +0.12 R | 86.4 |
| NQ EM-LS-T2 | 1,630 | +0.02 R | -0.01 R | -0.06 R to +0.04 R | 86.8 |
| GC EM-L-N | 860 | +0.24 R | +0.12 R | +0.01 R to +0.23 R | 95.6 |
| GC EM-L-T2 | 860 | -0.01 R | 0.00 R | -0.06 R to +0.06 R | 44.4 |
| GC EM-LS-N | 1,720 | +0.09 R | -0.02 R | -0.13 R to +0.09 R | 95.2 |
| GC EM-LS-T2 | 1,720 | 0.00 R | -0.03 R | -0.07 R to +0.02 R | 77.6 |
Only the two gold no-stop variants cleared 95 (95.6 and 95.2), by a small margin. The best of the other ten was ES EM-L-T2 at 92.6. With 12 variants tried, chance alone is expected to clear a 95th-percentile bar about 0.6 times (12 x 5%), and the two gold variants share the same long entries, so they are not two independent results; that is why the protocol also asks for a development t-statistic of 2.5.
06The gates
| Variant | Trades | 1. PF ≥ 1.2 in validation | 2. ≥ 50 trades in each period | 3. t ≥ 2.5 on development | 4. Above the 95th percentile of the shifted-state control | 5. Positive without the 10 best trades | 6. Holdout net positive (already used) |
|---|---|---|---|---|---|---|---|
| ES EM-L-N | 837 | fail | pass | fail | fail | fail | pass |
| ES EM-L-T2 | 837 | fail | pass | fail | fail | pass | pass |
| ES EM-LS-N | 1,674 | fail | pass | fail | fail | fail | fail |
| ES EM-LS-T2 | 1,674 | fail | pass | fail | fail | fail | fail |
| NQ EM-L-N | 815 | pass | pass | fail | fail | pass | pass |
| NQ EM-L-T2 | 815 | fail | pass | fail | fail | pass | pass |
| NQ EM-LS-N | 1,630 | fail | pass | fail | fail | fail | fail |
| NQ EM-LS-T2 | 1,630 | fail | pass | fail | fail | pass | pass |
| GC EM-L-N | 860 | pass | pass | fail | pass | pass | pass |
| GC EM-L-T2 | 860 | fail | pass | fail | fail | fail | fail |
| GC EM-LS-N | 1,720 | pass | pass | fail | pass | pass | pass |
| GC EM-LS-T2 | 1,720 | fail | pass | fail | fail | fail | pass |
Gate 3 (development t-statistic of at least 2.5, raised from 2.0 because more than four variants were tried) is failed by every variant; the highest development t-statistic was 1.98 (NQ EM-L-N). The two gold no-stop variants failed only that gate. For gold long only, with no stop, the development period (2020 to 2023) made +67 R (t 1.08), while validation made +80 R and the holdout +62 R; about two thirds of the result came after 2023, when gold moved +$177,560 per contract against +$29,810 before (the same figures for ES are +$116,700 and +$71,288, for NQ +$223,730 and +$146,175).
07Verdict by variant
| Variant | Cause | Gates failed | Verdict |
|---|---|---|---|
| ES EM-L-N | No proven edge | 1, 3, 4, 5 | Buried |
| ES EM-L-T2 | No proven edge | 1, 3, 4 | Buried |
| ES EM-LS-N | No proven edge | 1, 3, 4, 5, 6 | Buried |
| ES EM-LS-T2 | No proven edge | 1, 3, 4, 5, 6 | Buried |
| NQ EM-L-N | No proven edge | 3, 4 | Buried |
| NQ EM-L-T2 | No proven edge | 1, 3, 4 | Buried |
| NQ EM-LS-N | No proven edge | 1, 3, 4, 5, 6 | Buried |
| NQ EM-LS-T2 | No proven edge | 1, 3, 4 | Buried |
| GC EM-L-N | No proven edge | 3 | Buried |
| GC EM-L-T2 | No proven edge | 1, 3, 4, 5, 6 | Buried |
| GC EM-LS-N | No proven edge | 3 | Buried |
| GC EM-LS-T2 | No proven edge | 1, 3, 4, 5 | Buried |
What this test covers, exactly: the EMA(9) and EMA(21) crossover on 1-hour bars of ES, NQ and gold futures (6.7 years, back-adjusted), around the clock, positions held over weekends, R fixed at 1.5 ATR(14), with the costs above. “No proven edge” means a convincing edge was not demonstrated; it is not proof that none exists.
What we did not test: other averages and periods, other timeframes, filters, other stop sizes, other products, and live fills.
TWhat this shows, and what to take into your own tests
What the results show
- None of the 12 variants passed. No variant reached the development t-statistic of 2.5 that the protocol asks for when many variants are tried: the highest was 1.98 (NQ EM-L-N).
- The long-only no-stop version made money after costs in ES, NQ and gold (ES +35 R, NQ +175 R, gold +209 R), but only gold finished above buy and hold in dollars (+$242,668 against +$208,580). The shorts lost money in all three markets.
- Two variants came close: gold long only with no stop and gold long and short with no stop passed five of the six gates, including the shifted-state control (percentiles 95.6 and 95.2), and failed only the development t-statistic (1.08 and 0.71).
- Adding a 1 R stop and a 2 R target made every long-only version worse than the same entries with no stop.
What remains unknown
- Other periods of the two averages, such as 20/50 or 12/26, and other timeframes. We tested one pair and one timeframe on purpose.
- Whether gold's pattern is a property of gold or of 2024 to 2026, when gold moved six times as far as in 2020 to 2023 (buy and hold): the development period alone was not convincing.
- Live fills, and other products. The same commission was assumed for the three contracts, which is not a broker quote.
Why nothing passed
The long-only version opens 121 to 128 trades a year per market and wins 29 to 35% of them, so it lives on a few big winners (the average winner of the long-only no-stop versions was 2.5 to 3.3 R against an average loser of 1.0 to 1.2 R). That is enough to make money while the market rises, but the shifted-state control also made money by being long at random times (the control medians were +0.06 R to +0.13 R per trade), and over the development years the gold and Nasdaq results were not distinguishable from luck at the 2.5 level. The short side lost money everywhere.
What you can apply to your own tests
- Test a long-only version against a matched control on the same market, so a rising market is not credited to the signal.
- Look at the development period on its own. A result that comes from the last two years is not the same evidence as one that holds from the start.
- Add the stop and target last, and check that they help: here they made things worse.
- Ask whether the best market is also the one that rose most. Here gold was the only one to beat buy and hold.
A note on the numbers: drawdown figures are measured on closed trades unless a table says it includes open losses. Open losses inside a trade are not counted in a closed-trade drawdown, so real account risk is higher, especially for systems with no stop. Backtests are not live trading.
FAQCommon questions
Does the 9 and 21 EMA crossover work?
Not in our test. On 1-hour bars of three futures markets from 2020 to 2026 the averages crossed 5,024 times and none of 12 variants passed every gate. The long-only versions with no stop made money after costs, the shorts lost money in all three markets, and no variant reached a development t-statistic of 2.5 (the highest was 1.98).
Does a stop loss and take profit help an EMA crossover strategy?
Not here. With a 1 R stop and a 2 R target the long-only versions made +31 R (ES), +59 R (NQ) and -7 R (gold), against +35 R, +175 R and +209 R with no stop on the same entries.
Does the EMA 9/21 crossover work on gold or on the Nasdaq?
Gold came closest: long only with no stop made +209 R (+$242,668 per contract, against +$208,580 for buy and hold) and passed five of six gates, failing only the development t-statistic (1.08). NQ long only made +175 R but beat the shifted-state control only at percentile 88.8, and its development t-statistic was 1.98.
Does the EMA 9/21 crossover beat random timing?
Mostly not. Against a circularly shifted state-series control (the same crossover episodes placed on other dates), two of the 12 variants, both gold with no stop, reached the 95th percentile (95.6 and 95.2); the best of the others was 92.6.
How was the EMA 9/21 crossover tested?
On 1-hour bars of ES, NQ and gold futures, around the clock, with rules written and dated before the data was run, costs included on every trade, results split into development, validation and holdout periods, a random-entry control as the benchmark, and every variant reported. The data had known holes, so we also recomputed every verdict without the trades that were open across one: nothing changed. Read the protocol.
08Check our arithmetic
em_spec.md
em_lib.js · em_run.js · em_selftest.js · gh_lib.js · ma_lib.js · control_audit_lib.js · hourly_lib.js · rsi2_protocol.js · gc_rolls.json
em_selftest_result.txt · em_results.txt · em_summary.json
ES · NQ · GC
data_manifest.md · data_holes.json · hole_sensitivity.txt · find_holes.js · hole_sensitivity.js · em_moves.js
Code provenance: our own code, written from the standard definitions of the exponential moving average and of the ATR. No third-party source code is used or published.
09Data notes
The three 1-minute files come from NinjaTrader's historical data and are used exactly as exported (hashes in data_manifest.md). Two things readers should know:
- The prices are back-adjusted. Each contract roll shifts older prices by a fixed amount so that the series has no jump at the roll (checked against the raw NQ contract: from 1 January 2020 to the first roll every price is shifted by exactly 3,596.25 points). Results in R and in dollars are right; the older prices are not the prices that traded, so any percentage change on them would be wrong. This test uses none.
- The files have holes. Windows of missing data inside sessions, missing sessions and sessions that open late or end early: ES 10, NQ 19, gold 11 (data_holes.json). The largest are a whole NQ session (23 January 2026), about 21 hours of NQ (28 to 29 August 2025) and 11 days of gold (5 to 16 April 2023). We did not fill them. Instead we removed every trade that was open across a hole and recomputed the gates and verdicts (gate 4 as in the run): 69 trade-hole overlaps summed over the 12 variants, no verdict changed, and one gate changed (GC EM-LS-N: gate 5 PASS->FAIL).
| Market | Hole windows | Trade-hole overlaps (4 variants) | Verdicts changed | Variants with a gate changed |
|---|---|---|---|---|
| ES | 10 | 19 | 0 | 0 |
| NQ | 19 | 24 | 0 | 0 |
| GC | 11 | 26 | 0 | 1 |
A hole here is a gap of more than 30 minutes inside a session, a session that opens more than 30 minutes late, a session that ends early on a day that is not on the exchange calendar, a session with fewer than 690 bars, or a weekday session that is missing in this file but present in another. Early closes on the exchange calendar are not counted. The test is deliberately strict: it removes any trade open at any time across a hole.
10Corrections
14 Oct 2026, display only: values that round to zero were shown with a sign (“-0.00 R” or “+0.00 R”); they are now shown as 0.00 R. No number changed. None yet. 18 Oct 2026, navigation: added links to the new guide that compares all 11 gold strategy tests. No result changed. 22 Oct 2026, navigation: added a link to the new guide comparing trading costs across all our tests. No result changed. 22 Oct 2026, navigation: added a link to the new cross-market scoreboard, which includes this test. No result changed. 22 Oct 2026, navigation: added a link to the new guide comparing trend following and mean reversion across all our tests. No result changed. 22 Oct 2026, navigation: added a link to the new guide comparing versions with and without a stop loss across our tests. No result changed.
+More tests and guides
- Best gold trading strategy
- Golden cross 1 hour backtest
- Macd crossover strategy backtest
- Supertrend indicator backtest
- Coppock curve backtest
- Did the stop loss help? This test next to the other with-and-without pairs
- Trend following vs mean reversion: this test next to the others of its style
- Free prop firm challenge calculator
- What all the backtests found so far
- The backtesting protocol
- How to backtest a trading strategy without fooling yourself
- Backtesting glossary