Tested by BacktestingMax
MACD crossover strategy backtest
Does the MACD crossover strategy make money?
No, not on most markets. We ran 21 backtests: 7 markets, each on 15-minute, 1-hour and 4-hour charts, after trading costs. With no filter, the crossover lost money in 15 of the 21, including all 7 markets on 15-minute charts. Only 4 tests made money in 2020–2023 and again in 2024–2025, the newer years: the DAX and the Nasdaq 100 on 1-hour charts, and USD/JPY and EUR/USD on 4-hour charts. With a 200 EMA trend filter, 8 tests made money in both periods instead of 4.
21 backtests 2020–2025 Trading costs included Tested 11 October 2026
Where it worked 21 backtests- Made money
- 6 of 21 tests, with no filter
- Made money in both periods
- 4 2020–2023 and again 2024–2025
- Best backtest
- +294% DAX, 1-hour chart: account growth 2020–2025
- With a 200 EMA trend filter
- 8 tests made money in both periods, compared with 4 with no filter
Made money in both periods
- EUR/USD, 4-hour
- USD/JPY, 4-hour
- Nasdaq 100, 1-hour
- DAX, 1-hour
Lost money on every market
- 15-minute charts
The results
Results on every market
Each box shows one backtest of the MACD crossover with no filter, from 2020 to 2025, after trading costs: the % result, and a small chart of the account balance. The solid line is the account balance and the dashed line is the starting balance. Green results made money; red results lost money. Under each result: whether it made money in both 2020–2023 and 2024–2025, or passed all four of our checks (see "How a test passes" further down).
| Market | 15-minute | 1-hour | 4-hour |
|---|---|---|---|
| EUR/USD | −99% Lost money. Account down 90% by May 2021 | −62% Lost money | +13% Made money in both periods |
| GBP/USD | −99% Lost money. Account down 90% by May 2021 | −70% Lost money | +0.2% Made money overall, lost in one period |
| USD/JPY | −99% Lost money. Account down 90% by Sept 2021 | +124% Made money overall, lost in one period | +56% Made money in both periods |
| Gold | −98% Lost money. Account down 90% by May 2021 | −31% Lost money | −6% Lost money |
| Nasdaq 100 | −82% Lost money | +58% Made money in both periods | −0.3% Lost money |
| S&P 500 | −94% Lost money. Account down 90% by Feb 2024 | −24% Lost money | −17% Lost money |
| DAX | −97% Lost money. Account down 90% by May 2022 | +294% Made money in both periods | −6% Lost money |
All the numbers, test by test
| Market | Chart | Trades | Win rate | Profit factor | Result | Max drawdown | 2020–2023 | 2024–2025 | Monte Carlo drawdown | Trading costs |
|---|---|---|---|---|---|---|---|---|---|---|
| EUR/USD | 15-minute | 5,653 | 28.8% | 0.81 | −99.4% | −99.5% | −99.3% | −22.6% | −99.6% | $7,814 |
| EUR/USD | 1-hour | 2,759 | 32.4% | 0.91 | −62.3% | −63.0% | −57.0% | −12.3% | −79.6% | $4,524 |
| EUR/USD | 4-hour | 684 | 36.4% | 1.04 | +12.8% | −20.8% | +1.6% | +11.1% | −33.1% | $1,052 |
| GBP/USD | 15-minute | 4,869 | 28.7% | 0.83 | −99.3% | −99.3% | −99.1% | −21.7% | −99.5% | $8,492 |
| GBP/USD | 1-hour | 2,760 | 32.3% | 0.93 | −69.8% | −76.3% | −37.5% | −51.7% | −82.3% | $7,062 |
| GBP/USD | 4-hour | 680 | 35.9% | 1.00 | +0.2% | −25.9% | +9.7% | −8.7% | −37.0% | $1,173 |
| USD/JPY | 15-minute | 10,064 | 31.2% | 0.87 | −98.6% | −98.8% | −96.8% | −56.9% | −99.3% | $13,791 |
| USD/JPY | 1-hour | 2,619 | 33.4% | 1.10 | +124.0% | −44.1% | −8.1% | +143.7% | −52.7% | $7,835 |
| USD/JPY | 4-hour | 635 | 36.2% | 1.15 | +55.6% | −24.0% | +54.2% | +0.9% | −28.2% | $1,124 |
| Gold | 15-minute | 3,897 | 29.2% | 0.79 | −97.9% | −98.2% | −97.8% | −4.1% | −98.4% | $6,925 |
| Gold | 1-hour | 2,568 | 32.4% | 0.96 | −30.9% | −49.4% | −31.2% | +0.5% | −68.1% | $5,719 |
| Gold | 4-hour | 680 | 31.8% | 0.97 | −6.4% | −35.8% | −13.1% | +7.7% | −38.4% | $877 |
| Nasdaq 100 | 15-minute | 9,462 | 31.9% | 0.97 | −81.7% | −86.4% | −63.3% | −50.3% | −95.3% | $21,986 |
| Nasdaq 100 | 1-hour | 2,499 | 34.5% | 1.04 | +57.9% | −32.3% | +29.9% | +21.5% | −57.2% | $5,657 |
| Nasdaq 100 | 4-hour | 667 | 35.7% | 1.00 | −0.3% | −16.4% | −5.0% | +4.9% | −36.5% | $454 |
| S&P 500 | 15-minute | 9,614 | 32% | 0.95 | −93.5% | −94.7% | −85.2% | −55.7% | −97.9% | $16,617 |
| S&P 500 | 1-hour | 2,548 | 33.3% | 0.99 | −24.1% | −61.8% | +30.4% | −41.8% | −69.6% | $7,187 |
| S&P 500 | 4-hour | 674 | 35.9% | 0.94 | −17.2% | −25.6% | −3.0% | −14.7% | −45.3% | $591 |
| DAX | 15-minute | 7,113 | 30.7% | 0.90 | −97.3% | −98.2% | −96.3% | −26.2% | −98.5% | $5,328 |
| DAX | 1-hour | 2,547 | 34.7% | 1.10 | +294.1% | −29.6% | +130.9% | +70.7% | −44.6% | $7,935 |
| DAX | 4-hour | 731 | 32.7% | 0.98 | −5.7% | −28.0% | +1.7% | −7.2% | −39.4% | $410 |
Profit factor is the money won divided by the money lost. Above 1 means the test made money. Max drawdown is the biggest fall from the highest balance. 2020–2023 and 2024–2025 show the result in each period on its own. Monte Carlo drawdown: we shuffled the trades into a random order 1,000 times; in 95% of those runs, the worst drawdown was this number or less. Result is the change in the account, with the risk of each trade set to 1% of the account at that time.
The account balance
The best test and the middle test
What we found
What the 21 backtests show
On 15-minute charts, the MACD crossover lost money on all 7 markets. In 6 of those 7 tests, the account lost more than 90% of its starting balance. A 15-minute trade catches only a small price move, so trading costs take a big share of it. On the Nasdaq 100, the 15-minute trades made $13,813 before costs and paid $21,986 in costs.
On 1-hour and 4-hour charts, the crossover with no filter made money in 6 of 14 tests. 4 of them made money in both 2020–2023 and 2024–2025: the DAX and the Nasdaq 100 on 1-hour charts, and USD/JPY and EUR/USD on 4-hour charts. The best backtest result was the DAX on 1-hour charts: +294% from 2020 to 2025.
In all 21 tests, only about 1 trade in 3 was a winner: the win rate was between 29% and 36%. So the strategy needs a few big winning trades to pay for the many losing ones.
We tried 3 common changes to the crossover. The one that helped most in this backtest was a 200 EMA trend filter: only buy when price is above the 200 EMA, and only sell when it is below. With it, 11 of 21 tests made money, compared with 6 with no filter, and 8 tests made money in both periods, compared with 4. But we picked this filter using 2020–2023, and on 2024–2025 alone the difference was small: 9 tests made money, compared with 8. On 15-minute charts the filter did not help: all 7 markets still lost money.
The strategy
What the MACD crossover is
MACD is an indicator that measures momentum: how fast, and in which direction, price is moving. The MACD line is the gap between two moving averages of the price: one over the last 12 candles and one over the last 26. The signal line is the average of the MACD line over its last 9 values, so it moves more smoothly. The crossover strategy opens a trade every time these two lines cross.
- MACD
- 12, 26, 9 (the standard settings)
- Stop-loss
- 2 × ATR(14)
- Take-profit
- None. The next cross in the other direction closes the trade.
- Risk per trade
- 1% of the account
The rules we tested
- Buy when the MACD line crosses above the signal line.
- Sell (go short) when the MACD line crosses below the signal line.
- When the MACD line crosses back over the signal line, close the open trade and open a new trade in the new direction. After a stop-loss, wait for the next cross.
- ATR is an indicator of how far price moves in an average candle, measured over the last 14 candles. Put the stop-loss 2 times the ATR away from the entry price.
- Size every trade so that, if the stop-loss is hit, the trade loses 1% of the account.
The method
How we tested it
The test
- Markets
- EUR/USD, GBP/USD, USD/JPY, Gold, Nasdaq 100, S&P 500 and DAX
- Charts
- 15-minute, 1-hour and 4-hour candles
- Dates
- January 2020 to December 2025
- Account
- $10,000, risking 1% of the account on each trade
- Trading costs
- Included. Every trade pays that market's normal trading cost: the spread, which is the gap between the buy price and the sell price.
How a test passes
We call a test passed only if it meets all four checks. A strategy can make money in one backtest and still fail one of these checks.
- At least 100 trades. With fewer trades, a good result could be luck.
- It made money from 2020 to 2023 and again from 2024 to 2025. This shows whether the strategy kept working in the newer years, not only in the older ones.
- A profit factor (the money won divided by the money lost) of at least 1.2 from 2024 to 2025, after trading costs.
- In 95% of 1,000 random shuffles of the trades, the account must not fall more than 30% from its highest point.
Improvements
Can the MACD crossover be improved?
We tried three changes traders often make to the MACD crossover, to see if any of them make it better. Each change ran on the same 21 tests. A change picked on the same years it is judged on will almost always look good, so we picked the best one using 2020–2023 only. Then we checked it on 2024–2025, the years we did not use to pick it.
| Version | Made money 2020–2023years used to pick the best version | Made money 2024–2025years not used to pick it | Made money in both periods | Passed all four checks |
|---|---|---|---|---|
| Crossover only, no filter The rules under 'The rules we tested', with nothing added. | 7 of 21middle test −13.1% | 8 of 21middle test −8.7% | 4 | 0 |
| With a 200 EMA trend filterBest on 2020–2023 Only buy when the price is above the 200 EMA, a moving average of the last 200 candles that gives more weight to recent candles. Only sell when it is below. | 13 of 21middle test +4.7% | 9 of 21middle test −1.2% | 8 | 2 |
| Buy only below zero, sell only above zero The MACD line is below zero when the 12-candle average is below the 26-candle average, which means price has been falling. Only buy when the lines cross below zero. Only sell when they cross above zero. | 6 of 21middle test −22.5% | 7 of 21middle test −5.2% | 2 | 0 |
| Fixed 2:1 take-profit Close the trade when it has made 2 times what it would lose at the stop-loss. A cross in the other direction no longer closes the trade; the next trade starts at the next cross after this one has closed. | 5 of 21middle test −19.0% | 9 of 21middle test −6.4% | 3 | 1 |
On 2020–2023, the years we used to pick the best change, the 200 EMA trend filter did best: 13 of 21 tests made money with it, compared with 7 with no filter. On 2024–2025, the years we kept for the check, the difference was small: 9 of 21 tests made money, compared with 8. In 2024–2025, the middle test (half of the 21 did better, half did worse) was −1.2% with the filter and −8.7% without it. Over both periods, 8 tests made money with the filter, compared with 4. So in this backtest the filter helped, but most tests still lost money in 2024–2025.
Passed all four checks with a 200 EMA trend filter
- Gold, 4-hour
- Nasdaq 100, 4-hour
Questions
Questions traders ask
Does the MACD crossover strategy work?
No, not on most markets. In our backtest from 2020 to 2025, with trading costs, the 12, 26, 9 crossover with no filter lost money in 15 of 21 tests (7 markets, each on 15-minute, 1-hour and 4-hour charts). Only 4 tests made money in both 2020–2023 and 2024–2025: the DAX and the Nasdaq 100 on 1-hour charts, and USD/JPY and EUR/USD on 4-hour charts.
What is the best timeframe for a MACD crossover?
In our tests, 1-hour and 4-hour charts did better than 15-minute charts. But even on those charts, the crossover with no filter made money in only 6 of 14 tests. On 15-minute charts it lost money on all 7 markets, with or without the 200 EMA trend filter: trading costs took a big share of each small trade, and on 4 of the 7 markets the trades lost money even before costs. The best single backtest was the DAX on 1-hour charts, +294% from 2020 to 2025.
Does a 200 EMA filter improve the MACD crossover?
In our backtest it helped, but less on the newer years. A 200 EMA filter means: only buy when price is above the 200 EMA (a moving average of the last 200 candles), and only sell when it is below. Over 2020–2025, it raised the number of tests that made money from 6 to 11 of 21. We picked this filter using 2020–2023 only. On 2024–2025, the years we did not use to pick it, 9 of 21 tests made money with the filter, compared with 8 without it.
What are the best MACD settings?
This test can't tell you, because we tested only the standard settings, 12, 26 and 9. They are the default on most charting platforms. Be careful if you choose settings only because they gave the best backtest result. Settings chosen that way fit the past data, so they often do worse in live trading than in the backtest. You can test other settings in BacktestingMax.
Keep exploring
Related strategies we tested
Supertrend Supertrend (10, 3) strategy backtest Made money in 10 of 36 tests, 4 of them in both periods. Best: USD/JPY, 1-hour, +104% Moving averages 9/21 EMA crossover backtest: from 5-minute to daily charts Made money in 10 of 40 tests, 5 of them in both periods. Best: USD/JPY, 1-hour, +539%The strategy code we ran
This is the exact code from the BacktestingMax strategy engine. Paste it into the strategy editor in the app to run it on any market.
class MacdCrossover(Strategy):
"""The classic MACD crossover, as most traders learn it, plus three common improvements.
Standard (all switches off): buy when the MACD line (12/26) crosses above its signal
line (9), sell short when it crosses below. The opposite cross closes the trade and
opens the opposite one (the exit fills at the next candle's open, the new trade one
candle later). A protective stop 2 x ATR(14) away caps each trade; size so that stop
costs 1% of the account.
The improvements, one at a time:
trend_filter = 1 only buy above the 200 EMA, only sell below it
zero_filter = 1 only buy on a cross below the zero line, only sell on one above it
exit_rr = 2 take profit at 2 times the risk; the opposite cross no longer exits
"""
params = {"fast": Param(type=int, default=12, min=2, max=50),
"slow": Param(type=int, default=26, min=5, max=100),
"signal": Param(type=int, default=9, min=2, max=50),
"atr_mult": Param(type=float, default=2.0, min=0.5, max=5.0),
"trend_filter": Param(type=int, default=0, min=0, max=1),
"zero_filter": Param(type=int, default=0, min=0, max=1),
"exit_rr": Param(type=float, default=0.0, min=0.0, max=10.0)}
lookback = 220
def init(self, ctx):
self.macd = ctx.indicator("builtin:macd", fast=ctx.params.fast, slow=ctx.params.slow,
signal=ctx.params.signal)
self.atr = ctx.atr(period=14)
self.ema = ctx.ema(source=ctx.close, period=200)
self.reverse_to = None # "long" / "short": open this once the closing trade is gone
def on_bar(self, ctx):
m0, m1 = self.macd.macd[0], self.macd.macd[1]
s0, s1 = self.macd.signal[0], self.macd.signal[1]
a = self.atr.value
if m0 is None or m1 is None or s0 is None or s1 is None or a is None:
return
trend = ctx.params.trend_filter == 1
if trend and self.ema.value is None:
return
rr = ctx.params.exit_rr
cross_up = m1 <= s1 and m0 > s0
cross_down = m1 >= s1 and m0 < s0
pos = ctx.position
if pos is not None:
if rr > 0:
return # the fixed target or the stop ends the trade
if pos.is_long and cross_down:
ctx.close_position()
self.reverse_to = "short"
elif pos.is_short and cross_up:
ctx.close_position()
self.reverse_to = "long"
return
# A reversal waits one candle for the close to fill. Drop it if MACD crossed back.
pending, self.reverse_to = self.reverse_to, None
if pending == "long" and m0 > s0:
cross_up = True
if pending == "short" and m0 < s0:
cross_down = True
entry = ctx.close[0]
long_ok = (not trend or entry > self.ema.value) and (ctx.params.zero_filter == 0 or m0 < 0)
short_ok = (not trend or entry < self.ema.value) and (ctx.params.zero_filter == 0 or m0 > 0)
if ctx.gate("macd_crosses_up", cross_up) and ctx.gate("long_filters", long_ok):
stop = entry - ctx.params.atr_mult * a
tp = entry + rr * (entry - stop) if rr > 0 else None
ctx.buy(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop, tp=tp, tag="macd_long")
elif ctx.gate("macd_crosses_down", cross_down) and ctx.gate("short_filters", short_ok):
stop = entry + ctx.params.atr_mult * a
tp = entry - rr * (stop - entry) if rr > 0 else None
ctx.sell(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop, tp=tp, tag="macd_short")
Your turn
Test the MACD crossover yourself
Change the settings, the market or the stop-loss and see the result in seconds. Ask the BacktestingMax AI: Backtest a MACD crossover with a 200 EMA filter on the Nasdaq 100, 4-hour chart
.
Free account. No credit card needed.
See every strategy we tested Browse strategies shared by tradersBacktest on historical data with trading costs, run by BacktestingMax. Past results do not guarantee future results, and nothing here is financial advice. Updated 11 October 2026.