SMA Crossover Backtest: 25 Variants Tested on EUR/USD 4H (2013–2026)
60-Second Summary
- XZero survivors from 25 SMA crossover variants tested
- X48% killed by negative expectancy — slow MAs lag so severely entries arrive after the move is spent
- X44% killed by IS/OOS drift — win rates learned in-sample do not transfer out-of-sample (mean drift 17.3pp)
- +Best performer: SMA 30/200 (+0.862 Sharpe, +23.56 pips net expectancy) — failed drift in all 6 windows
- +Sweet spot: fast 25–75 against slow 50 — the only group with consistently positive gross expectancy
The simple moving average crossover is the oldest systematic trading signal in widespread use. Whether it translates into a statistically robust edge under modern market conditions and realistic transaction costs is a different question entirely. This article answers it with 13 years of walk-forward validated data across 25 parameter configurations.
1. Methodology
All articles in this series use identical methodology. Results are directly comparable across parts.
| Instrument | EUR/USD 4H |
| Dataset | January 1, 2013 to April 18, 2026 (22,193 bars) |
| Walk-forward windows | 6 non-overlapping (2-year in-sample / 1-year out-of-sample) |
| Transaction cost | 2.0 pip round-trip (1.5 pip spread + 0.5 pip slippage) |
| Entry | Fast SMA crosses above slow SMA, long at next bar open |
| Exit | Fixed 8-bar hold (uniform across all SMA variants) |
| Ranking metric | OOS Sharpe ratio, net of transaction costs |
Walk-Forward Windows
| Window | In-Sample | Out-of-Sample |
|---|---|---|
| 1 | 2013-01-01 to 2015-01-01 | 2015-01-01 to 2016-01-01 |
| 2 | 2015-01-01 to 2016-12-31 | 2016-12-31 to 2017-12-31 |
| 3 | 2016-12-31 to 2018-12-31 | 2018-12-31 to 2019-12-31 |
| 4 | 2018-12-31 to 2020-12-30 | 2020-12-30 to 2021-12-30 |
| 5 | 2020-12-30 to 2022-12-30 | 2022-12-30 to 2023-12-30 |
| 6 | 2022-12-30 to 2024-12-29 | 2024-12-29 to 2025-12-29 |
Five-Stage Kill Filter
Net Expectancy
Kill if net expectancy is 0 pips or less after transaction costs
Effective Sample Size
Kill if ESS-adjusted OOS trade count is under 50
IS/OOS Drift
Kill if win rate drift exceeds 5pp in any single window — per-window check, not aggregate
Binomial Test
Kill if OOS win rate is not statistically significant (p at or above 0.05)
Sharpe Variance
Kill if Sharpe std dev exceeds Sharpe mean across windows
Stage 3 uses a per-window check, not an aggregate average. A signal with mean drift of 2pp that has one window at 49pp is killed. Aggregate drift averaging conceals window-specific overfitting.
2. Parameter Grid
25 variants tested across 10 fast periods and 4 slow periods. All use an 8-bar fixed exit. The grid spans short-term (10/50) to long-term (150/200) combinations, covering both the commonly cited golden cross class and faster tactical entries.
| Fast Period | Slow Periods Tested |
|---|---|
| 10 | 50, 100, 200 |
| 12 | 50, 100 |
| 15 | 50, 100, 200 |
| 20 | 50, 100, 200 |
| 25 | 50, 100, 200 |
| 30 | 50, 100, 200 |
| 50 | 100, 150, 200 |
| 75 | 150, 200 |
| 100 | 150, 200 |
| 150 | 200 |
3. Results — Kill Filter Breakdown
25 variants tested. 0 survivors.
The failure splits almost evenly between two distinct modes — and the split matters for what to do next.
| Kill Stage | Count | % of 25 |
|---|---|---|
| Stage 1 — Net expectancy 0 or less | 12 | 48.0% |
| Stage 2 — Effective sample size under 50 | 2 | 8.0% |
| Stage 3 — IS/OOS drift above 5pp | 11 | 44.0% |
| Stage 4 — Binomial test | 0 | — |
| Stage 5 — Sharpe variance | 0 | — |
Stage 1 (48%): Nearly half the variants never produce positive expectancy after 2-pip round-trip costs. These are primarily the slow-MA variants (100 and 200 bars) where entries arrive too late to capture meaningful residual momentum.
Stage 3 (44%): The remaining failing group clears the expectancy hurdle but collapses at the drift check. These signals have real gross edge — but the win rate learned in-sample does not transfer to out-of-sample windows consistently enough to trust.
Stage 2 (8%): Two variants — 25/200 and 75/150 — fire so infrequently that 6 years of out-of-sample data does not accumulate 50 effective trades. Statistical inference on these sample sizes is not meaningful.
4. All 25 Variants — Ranked by OOS Sharpe
| Rank | Fast | Slow | OOS Sharpe | Kill Stage |
|---|---|---|---|---|
| 1 | 30 | 200 | +0.862 | Drift |
| 2 | 20 | 50 | +0.837 | Drift |
| 3 | 25 | 50 | +0.770 | Drift |
| 4 | 50 | 100 | +0.709 | Drift |
| 5 | 75 | 200 | +0.571 | Drift |
| 6 | 50 | 150 | +0.563 | Drift |
| 7 | 30 | 100 | +0.390 | Drift |
| 8 | 12 | 50 | +0.309 | Drift |
| 9 | 10 | 100 | +0.271 | Net Exp |
| 10 | 25 | 200 | +0.158 | Eff Sample |
| 11 | 30 | 50 | +0.133 | Drift |
| 12 | 150 | 200 | +0.088 | Drift |
| 13 | 75 | 150 | +0.071 | Eff Sample |
| 14 | 25 | 100 | +0.027 | Net Exp |
| 15 | 15 | 50 | +0.015 | Drift |
| 16 | 10 | 50 | -0.008 | Net Exp |
| 17 | 15 | 200 | -0.052 | Net Exp |
| 18 | 50 | 200 | -0.108 | Net Exp |
| 19 | 20 | 200 | -0.122 | Net Exp |
| 20 | 100 | 150 | -0.136 | Net Exp |
| 21 | 12 | 100 | -0.139 | Net Exp |
| 22 | 10 | 200 | -0.186 | Net Exp |
| 23 | 15 | 100 | -0.350 | Net Exp |
| 24 | 20 | 100 | -0.471 | Net Exp |
| 25 | 100 | 200 | -0.707 | Net Exp |
Blue = best performer. Green = sweet spot group (fast 25–75, slow 50). Red = worst performer.
5. Best Performer: SMA 30/200
A 30-period fast MA against a 200-period slow MA — a 6.7x separation ratio producing a low-frequency, trend-only signal.
Avg OOS Sharpe
+0.862
Avg Net Expectancy
+23.56 pips
Total OOS Trades
34
Kill Stage
IS/OOS Drift
At 34 total OOS trades across 6 years — roughly 5 to 6 trades per year — this is a highly selective signal. The aggregate numbers look encouraging. The per-window data exposes the reality.
Per-Window Breakdown
| Win | OOS Period | OOS Sharpe | Drift | Status |
|---|---|---|---|---|
| 1 | 2015 | +1.021 | +5.5pp | DRIFT |
| 2 | 2017 | +1.680 | +22.9pp | DRIFT |
| 3 | 2019 | +0.002 | -7.1pp | DRIFT |
| 4 | 2021 | +1.729 | +49.2pp | DRIFT |
| 5 | 2023 | +0.534 | -26.7pp | DRIFT |
| 6 | 2025 | +0.208 | +33.9pp | DRIFT |
| Aggregate | +0.862 | — | KILLED | |
Window 4 (2021), drift +49.2pp: IS win rate was 30.8%. OOS win rate was 80.0%. A 49.2pp swing. Five trades in the OOS window means a single win or loss moves the win rate by 20pp. The signal is not learning anything stable — it is fitting IS noise that happens to partially align with OOS performance.
Window 5 (2023), drift -26.7pp: IS win rate 66.7%, OOS win rate 40.0%. The reverse collapse in the following period. Statistical inference on 5 trades is coin-flip territory regardless of how many years of IS data preceded it.
The aggregate looks useful (+0.862 Sharpe, +23.56 pips). The per-window data reveals drift values ranging from -26.7pp to +49.2pp across six windows. A signal with that variance profile is not a deployable edge — it is variance that occasionally produces skill-looking outcomes.
Testing the Next Step
The 30/200 crossover has real gross edge — +23.56 pips average net expectancy — but unstable IS/OOS win rate transfer. The logical next test is conditioning the entry on a regime filter: only take the crossover signal when ADX is above 25, confirming a trend is present. Building that combination in MQL5 requires code most traders cannot write themselves. StratForge generates it from plain English in about 3 minutes.
Generate a custom SMA + ADX EA with StratForge6. Worst Performer: SMA 100/200
The slowest combination in the grid. 27 OOS trades across 6 years. Loses money in five of six windows.
Avg OOS Sharpe
-0.707
Avg Net Expectancy
-19.39 pips
Total OOS Trades
27
Kill Stage
Net Expectancy
| Win | OOS Period | OOS Sharpe | Status |
|---|---|---|---|
| 1 | 2015 | -1.354 | NET EXP |
| 2 | 2017 | -0.882 | NET EXP |
| 3 | 2019 | -0.516 | NET EXP |
| 4 | 2021 | -1.203 | NET EXP |
| 5 | 2023 | -0.555 | NET EXP |
| 6 | 2025 | +0.268 | NET EXP |
Structural interpretation: A 100/200 crossover fires during confirmed macro trend changes — moves that have already travelled hundreds of pips before the signal triggers. By the time both averages agree on direction, the move is typically exhausted. The signal enters late into tired trends and exits on a fixed 8-bar timer, collecting whatever residual momentum remains. Against a 2-pip round-trip cost, late entries on tired trends produce losses by construction.
7. Parameter Analysis
Performance by Slow Period
| Slow Period | Variants | Avg OOS Sharpe | Avg Net Exp (pips) |
|---|---|---|---|
| 50 | 6 | +0.342 | +4.02 |
| 100 | 7 | +0.063 | -0.96 |
| 150 | 3 | +0.166 | +3.13 |
| 200 | 9 | +0.056 | -0.23 |
Slow=50 outperforms clearly. Average Sharpe +0.342, average net expectancy +4.02 pips. All failures in this group die at drift rather than expectancy — the signals have real gross edge that IS/OOS instability kills. This is a remediable problem.
Slow=100 and slow=200 are structurally weak. The majority of kills in these groups occur at Stage 1 (negative expectancy). These signals are not overfitting a marginal edge — they simply do not produce positive gross expectancy after costs.
Performance by Fast Period
| Fast Period | Variants | Avg OOS Sharpe | Avg Net Exp (pips) |
|---|---|---|---|
| 10 | 3 | +0.026 | -3.20 |
| 12 | 2 | +0.085 | -2.34 |
| 15 | 3 | -0.129 | -4.87 |
| 20 | 3 | +0.081 | -2.89 |
| 25 | 3 | +0.318 | +3.81 |
| 30 | 3 | +0.462 | +10.48 |
| 50 | 3 | +0.388 | +8.98 |
| 75 | 2 | +0.321 | +7.61 |
| 100 | 2 | -0.421 | -11.64 |
| 150 | 1 | +0.088 | +0.52 |
There is a clear fast-period sweet spot between 25 and 75. Fast periods below 20 produce negative or near-zero average net expectancy — too sensitive to intraday noise, generating frequent false crossovers with thin individual move capture. Fast periods of 25 to 75 produce the only consistently positive group. Fast=100 collapses to -0.421 average Sharpe — it converges too close to the slow period and fires too late into already-established moves.
8. Regime Analysis
Aggregating performance across all 25 variants by window reveals a consistent pattern — and one result that contradicts conventional SMA wisdom.
| Window | OOS Period | Avg Sharpe |
|---|---|---|
| 1 | 2015 | +0.186 |
| 2 | 2017 | +0.402 |
| 3 | 2019 | +0.232 |
| 4 | 2021 | -0.308 |
| 5 | 2023 | -0.117 |
| 6 | 2025 | +0.444 |
Windows 4 and 5 are hostile (2021 and 2023). Window 4 captures EUR/USD sustained multi-year decline — exactly where an SMA crossover should theoretically excel. Average Sharpe across all 25 variants: -0.308. The explanation is timing: 4H crossover entries arrive late in leg moves, after the trend is already visible to all participants. The profitable part of the move has passed by the time the crossover fires.
Drift does not improve in friendly windows. Even in Window 2 (average Sharpe +0.402), average drift is 16.6pp. The signals overfit their IS win rates regardless of whether the OOS period is favourable or hostile. Regime-friendly conditions improve the absolute Sharpe but do not reduce the IS/OOS instability that the kill filter correctly identifies.
9. The Structural Problem with SMA Crossovers on 4H FX
1. The 4H Bar Contains Too Much Noise for Trend Confirmation
SMA crossovers were developed on daily data, where each bar represents a full trading session and noise is partially averaged out. On 4H, each bar is a single session segment. The signal-to-noise ratio is materially lower. A fast MA crossing a slow MA on 4H is frequently reacting to session-specific flow rather than genuine directional change. The signal fires, the session-specific move reverses, and the 8-bar exit captures a retracement rather than a continuation.
2. Transaction Costs Consume the Edge at High Signal Frequency
The variants with the most frequent signals — fast=10, 12, 15 against slow=50, producing 120 to 133 OOS trades — are exactly the variants with the worst average net expectancy. At 2-pip round-trip, a signal that averages 3 to 5 pips gross per trade is left with 1 to 3 pips net. Any reduction in win rate or average move size in an OOS window tips net expectancy negative. The cost-to-edge ratio for high-frequency SMA crossovers on 4H is structurally unfavourable.
3. The In-Sample Window Blends Multiple Regimes That Do Not Persist
A 2-year IS window on EUR/USD 4H contains trending periods, ranging periods, and regime transitions. The SMA parameters that best fit this blend are not the parameters that best fit any specific future regime. When the OOS year presents a single dominant regime, the IS-optimised parameters are typically miscalibrated for it. This is what the large IS/OOS drift values — mean 17.3pp across all windows — are measuring: systematic IS-to-OOS parameter misalignment driven by regime composition shifts between windows.
The Logical Next Step
The pattern from Part 1 points toward an obvious hypothesis: if SMA crossovers have real gross edge in the 25 to 75 fast period range but fail on IS/OOS drift, can a second indicator stabilise the win rate transfer? Testing that manually means choosing indicator pairs, parameterising both, and running walk-forward validation on every combination. That is weeks of work per hypothesis. StratForge generates the MQL5 EA code for combination strategies from plain English — describe the logic, receive the code, run the backtest in MetaTrader 5.
Generate a custom combination EA with StratForge10. Cross-Series Comparison
This table accumulates with each instalment. All entries use identical methodology.
| Part | Indicator | Variants | Mean Drift | Drift Kill % |
|---|---|---|---|---|
| 1 | SMA Crossover | 25 | 17.3pp | 44% |
| 2 | MACD | 75 | See Part 2 | See Part 2 |
11. Frequently Asked Questions
What is the best SMA crossover setting for MT5?v
Why do SMA crossover strategies fail in live trading?v
Does the golden cross (50/200) SMA work on forex?v
What SMA period combination shows the most promise?v
Is SMA or MACD better for trend following on MT5?v
12. Next in the Series
This is Part 1 of the MT5 Indicator Backtest Series. Every study uses the same walk-forward methodology, the same dataset, and the same 5-stage kill filter — making results directly comparable across indicator families.
Part 1 — You are here
SMA Crossover Analysis
25 variants · 13 years · 0 survivors · Split failure: 48% expectancy, 44% drift
Part 2 — Read next
MACD Configuration Analysis
75 variants · Same methodology · Drift dominates at 90.7% kill rate
Build on This Research
The fast 25 to 75 against slow 50 group has genuine gross edge that fails on IS/OOS drift. The natural next step — combining with a regime filter or second confirmation signal — requires multi-indicator MQL5 code most traders cannot write themselves. StratForge generates it from a conversational strategy interview. No coding required. Your own Anthropic API key means you pay Anthropic directly — typically a few cents per generation.
Generate a Custom SMA EA