Tested by BacktestingMax
ADX / DMI crossover strategy backtest
Does the ADX / DMI crossover strategy make money?
Mostly no. With the standard rules, 7 of 30 backtests made money from 2019 to 2025, after trading costs. Only USD/JPY on the 4-hour chart made money in both 2019–2022 and 2023–2025. The DMI is an indicator with three lines. +DI measures how strongly price has been moving up, -DI measures how strongly it has been moving down, and ADX measures how strong the trend is, from 0 to 100. The standard rules buy when +DI crosses above -DI, and sell short (sell first, to make money if price falls) when -DI crosses above +DI. They trade only if ADX is above 25: this is the ADX filter. Each trade closes at the next cross the other way, or at its stop-loss. We tested 10 markets (5 currency pairs, gold, silver and 3 stock indices) on 15-minute, 1-hour and 4-hour charts. All 10 lost money on 15-minute charts, and 5 of the 10 made money on 4-hour charts. The ADX filter was not reliably better than trading every cross: it did worse in 2019–2022 and better in 2023–2025. In 96.6% of the crosses with ADX above 25, ADX was already falling. So the high ADX came mostly from the move before the cross, not from the new one.
30 backtests 2019–2025 Trading costs included Tested 26 October 2026
Where it worked 30 backtests- Made money
- 7 of 30 tests, with the standard rules
- Made money in both periods
- 1 2019–2022 and again 2023–2025
- Best backtest
- +18% USD/JPY, 4-hour chart: account growth 2019–2025
- No ADX filter: every cross
- 5 tests made money in both periods, compared with 1 with the standard rules
Made money in both periods
- USD/JPY, 4-hour
Lost money on every market
- 15-minute charts
The results
Results on every market
Each box shows one backtest of the ADX / DMI crossover with the standard rules, from 2019 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 2019–2022 and 2023–2025, or passed all four of our checks (see "How a test passes" further down).
| Market | 15-minute | 1-hour | 4-hour |
|---|---|---|---|
| EUR/USD | −96% Lost money. Account down 90% by Jun 2023 | −38% Lost money | +3% Made money overall, lost in one period |
| GBP/USD | −93% Lost money. Account down 90% by May 2025 | −32% Lost money | −0.4% Lost money |
| USD/JPY | −91% Lost money. Account down 90% by Mar 2024 | −38% Lost money | +18% Passed all four checks |
| AUD/USD | −92% Lost money. Account down 90% by Aug 2025 | −19% Lost money | −11% Lost money |
| GBP/JPY | −96% Lost money. Account down 90% by Apr 2024 | −48% Lost money | +11% Made money overall, lost in one period |
| Gold | −88% Lost money | +3% Made money overall, lost in one period | +16% Made money overall, lost in one period |
| Silver | −96% Lost money. Account down 90% by Jan 2021 | −63% Lost money | +7% Made money overall, lost in one period |
| S&P 500 | −66% Lost money | −42% Lost money | −15% Lost money |
| Nasdaq 100 | −23% Lost money | −20% Lost money | −6% Lost money |
| DAX | −83% Lost money | +0.9% Made money overall, lost in one period | −8% Lost money |
All the numbers, test by test
| Market | Chart | Trades | Win rate | Profit factor | Result | Max drawdown | 2019–2022 | 2023–2025 | Monte Carlo drawdown | Trading costs |
|---|---|---|---|---|---|---|---|---|---|---|
| EUR/USD | 15-minute | 2,447 | 25.2% | 0.71 | −96.0% | −96.5% | −86.4% | −70.8% | −96.8% | $5,220 |
| EUR/USD | 1-hour | 720 | 27.6% | 0.83 | −38.2% | −42.2% | −31.4% | −9.9% | −54.9% | $1,798 |
| EUR/USD | 4-hour | 167 | 34.7% | 1.05 | +3.3% | −7.8% | +10.3% | −6.4% | −19.7% | $253 |
| GBP/USD | 15-minute | 2,284 | 25.5% | 0.79 | −92.9% | −93.8% | −61.6% | −81.5% | −94.7% | $6,622 |
| GBP/USD | 1-hour | 635 | 30.2% | 0.86 | −32.1% | −44.4% | −12.6% | −22.3% | −51.9% | $1,905 |
| GBP/USD | 4-hour | 185 | 30.8% | 0.99 | −0.4% | −27.5% | +7.8% | −7.7% | −21.6% | $302 |
| USD/JPY | 15-minute | 2,406 | 24.5% | 0.73 | −90.7% | −91.1% | −81.5% | −49.7% | −93.7% | $5,782 |
| USD/JPY | 1-hour | 702 | 26.8% | 0.79 | −37.6% | −44.7% | −33.0% | −6.8% | −52.5% | $1,432 |
| USD/JPY | 4-hour | 160 | 30% | 1.31 | +17.5% | −11.9% | +3.4% | +13.6% | −15.8% | $214 |
| AUD/USD | 15-minute | 2,427 | 24.3% | 0.73 | −91.9% | −92.7% | −78.9% | −61.4% | −93.9% | $7,396 |
| AUD/USD | 1-hour | 634 | 27.3% | 0.89 | −19.1% | −45.2% | −40.3% | +35.6% | −44.7% | $2,077 |
| AUD/USD | 4-hour | 149 | 28.2% | 0.76 | −10.9% | −16.2% | −3.7% | −7.5% | −18.8% | $281 |
| GBP/JPY | 15-minute | 2,344 | 24.3% | 0.72 | −95.7% | −96.2% | −79.4% | −79.2% | −96.5% | $7,924 |
| GBP/JPY | 1-hour | 638 | 26.2% | 0.67 | −48.3% | −54.3% | −53.6% | +11.4% | −57.6% | $1,808 |
| GBP/JPY | 4-hour | 151 | 31.8% | 1.21 | +11.4% | −9.7% | +13.2% | −1.6% | −16.6% | $342 |
| Gold | 15-minute | 2,170 | 25.2% | 0.74 | −87.8% | −88.5% | −77.8% | −44.9% | −91.3% | $6,614 |
| Gold | 1-hour | 661 | 27.5% | 1.01 | +2.8% | −22.0% | −2.8% | +5.8% | −41.2% | $2,144 |
| Gold | 4-hour | 168 | 33.3% | 1.36 | +16.2% | −12.6% | −4.7% | +22.0% | −12.2% | $226 |
| Silver | 15-minute | 1,044 | 15.9% | 0.24 | −96.1% | −96.1% | −94.9% | −24.9% | −96.5% | $7,072 |
| Silver | 1-hour | 611 | 23.4% | 0.54 | −62.8% | −63.7% | −44.4% | −33.0% | −66.7% | $3,355 |
| Silver | 4-hour | 167 | 24.6% | 1.13 | +6.5% | −9.6% | −3.3% | +10.1% | −17.7% | $649 |
| S&P 500 | 15-minute | 2,377 | 26.9% | 0.84 | −66.2% | −76.6% | −72.3% | +22.0% | −83.8% | $5,201 |
| S&P 500 | 1-hour | 692 | 28.5% | 0.80 | −42.1% | −45.4% | −23.4% | −24.4% | −56.2% | $1,153 |
| S&P 500 | 4-hour | 198 | 26.8% | 0.79 | −14.5% | −17.9% | −10.3% | −4.7% | −26.6% | $180 |
| Nasdaq 100 | 15-minute | 2,429 | 27.5% | 0.96 | −23.0% | −67.0% | −59.5% | +90.2% | −71.4% | $5,972 |
| Nasdaq 100 | 1-hour | 756 | 29.4% | 0.91 | −19.9% | −31.7% | −27.5% | +10.4% | −46.4% | $1,184 |
| Nasdaq 100 | 4-hour | 188 | 34% | 0.91 | −5.7% | −13.8% | −3.5% | −2.2% | −21.2% | $146 |
| DAX | 15-minute | 2,352 | 26.7% | 0.79 | −82.6% | −85.6% | −71.5% | −38.9% | −88.4% | $2,603 |
| DAX | 1-hour | 639 | 27.5% | 1.00 | +0.9% | −38.5% | −23.6% | +32.1% | −36.5% | $631 |
| DAX | 4-hour | 169 | 27.8% | 0.88 | −7.5% | −17.9% | −0.9% | −6.7% | −23.6% | $101 |
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. 2019–2022 and 2023–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 30 backtests show
With the standard rules, 7 of the 30 tests made money from 2019 to 2025, after trading costs, and 5 of them were on 4-hour charts. On 4-hour charts, USD/JPY grew the account by 17.5%, gold by 16.2%, GBP/JPY by 11.4%, silver by 6.5% and EUR/USD by 3.3%. Of all 30 tests, only USD/JPY on the 4-hour chart made money in both 2019–2022 (+3.4%) and 2023–2025 (+13.6%). It also passed all four of our checks (see 'How a test passes' further down), but 1 test out of 30 is not enough to rely on. On 1-hour charts, only gold (+2.8%) and the DAX (+0.9%) made money. The 3 stock indices lost money on 4-hour charts, from −5.7% to −14.5%, even though they rose 132% to 298% from 2019 to 2025. R is the money one trade risks: 1% of the account at the time of the trade. On the 4-hour charts of these 3 indices, the sell trades lost 38.3R in total, and the buy trades made 12.1R. Overnight fees are not included, and on 4-hour charts, half of the trades stayed open for more than a day.
Over 2019–2025, crosses with ADX above 25 did not lead to better trades. To test the ADX filter on its own, we also traded every cross of +DI and -DI, at any ADX value. Then we grouped the trades by the ADX on the candle of the cross (see the first table below). On 1-hour and 4-hour charts, the 7,804 trades after a cross with ADX above 25 lost 0.036R per trade on average, after trading costs. That is 3.6% of the money each trade risked. The 30,533 trades after the other crosses lost 0.011R per trade. The result was different in the two periods. In 2019–2022, the crosses with ADX above 25 did worse: −0.063R per trade, against +0.009R for the others. In 2023–2025, they did better: +0.001R, against −0.039R. We left out the 15-minute charts here: every ADX group lost money on them (see the note under the table).
When +DI and -DI cross, ADX is usually falling: it was falling in 90.1% of the 192,723 crosses in our 30 tests. ADX is a slow average of the gap between the two DI lines, and at a cross that gap is close to zero. ADX was above 25 on 43.7% of all candles, but at only 17.8% of the crosses. In 96.6% of the crosses with ADX above 25, ADX was lower than on the candle before. In 61.8% of them, the line that was crossed had been the higher DI line for at least the 14 candles before the cross. So in most of these crosses, the high ADX came from the candles before the cross, when the other line was on top. After the cross, ADX kept falling: in half of these crosses, for 7 candles or more. It got back above 25 before the next cross in only 33.5% of them (see 'What ADX shows at a cross' below).
Shorter charts did worse. With the standard rules, 0 of the 10 markets made money on 15-minute charts, 2 on 1-hour charts and 5 on 4-hour charts. Costs were one reason: on 15-minute charts the spread (the gap between the buy price and the sell price) took 6.8% of what each trade risked, against 1.6% on 4-hour charts. But counted in R, the 15-minute trades lost money on 8 of the 10 markets even before costs. Daily charts gave only 30 to 51 trades per market from 2014 to 2025; all 10 markets together lost 8.5R in 411 trades (see the last table below).
The ADX filter
Every cross, grouped by the ADX on the candle of the cross
To test the ADX filter on its own, we traded every cross of +DI and -DI, at any ADX value. We did this on the 20 tests with 1-hour and 4-hour charts, from 2019 to 2025. Each trade ran from one cross to the next cross, or to the stop-loss. Then we grouped the trades by the ADX on the candle of the cross. Each result is the average result of one trade after trading costs, in R. R is the money one trade risks: 1% of the account at the time of the trade. For example, −0.036R means that these trades lost, on average, 3.6% of the money they risked. Each trade counts in the period in which it closed.
| ADX on the candle of the cross | Trades | 2019–2022 | 2023–2025 | 2019–2025 |
|---|---|---|---|---|
| 15 or lower | 10,774 | +0.043R | −0.005R | +0.022R |
| Above 15, up to 20 | 11,905 | −0.004R | −0.073R | −0.033R |
| Above 20, up to 25 | 7,854 | −0.015R | −0.037R | −0.024R |
| Above 25, up to 30 | 4,248 | −0.059R | −0.021R | −0.043R |
| Above 30, up to 40 | 2,964 | −0.071R | +0.020R | −0.032R |
| Above 40 | 592 | −0.049R | +0.052R | −0.005R |
| Above 25: the crosses the standard rules trade | 7,804 | −0.063R | +0.001R | −0.036R |
| 25 or lower: the crosses the standard rules skip | 30,533 | +0.009R | −0.039R | −0.011R |
On these charts, the standard rules trade only the crosses with ADX above 25: about 1 cross in 5. Every group was close to break-even, between −0.073R and +0.052R per trade in each period, and the order of the groups changed between the two periods. On 15-minute charts, every group lost money from 2019 to 2025, from −0.103R to −0.055R per trade.
What ADX shows at a cross
When +DI and -DI cross with ADX above 25, ADX is almost always falling
These numbers come from all 192,723 crosses of +DI and -DI in our 30 tests: 10 markets on 15-minute, 1-hour and 4-hour charts, from 2019 to 2025. The first number covers every cross. The other three cover only the 34,280 crosses with ADX above 25.
- Crosses with ADX above 25
- 17.8% 34,280 out of 192,723 crosses. ADX was above 25 on 43.7% of all candles.
- ADX falling at those crosses
- 96.6% 33,107 out of 34,280: ADX was lower than on the candle before the cross.
- Crossed line on top for 14+ candles
- 61.8% The DI line that was crossed had been the higher one for at least the 14 candles before the cross.
- ADX back above 25 before the next cross
- 33.5% About 1 cross in 3. After a typical cross (the median), ADX kept falling for 7 more candles, to about 22.6.
ADX is Wilder's average, over 14 candles, of the gap between +DI and -DI (as a share of the two lines together). At a cross, that gap is close to zero, so ADX falls. A high ADX at the cross comes from the candles before it, when the other line was on top.
Daily charts
The same rules on daily charts, from 2014 to 2025
Each result is the change in the account from January 2014 to December 2025, after trading costs, risking 1% of the account on each trade. The standard rules trade a cross only if ADX is above 25. 'Every cross' trades every cross of +DI and -DI.
| Market | Standard rules: trades | Standard rules: result | Every cross: trades | Every cross: result |
|---|---|---|---|---|
| EUR/USD | 40 | +6.4% | 236 | +5.4% |
| GBP/USD | 33 | −2.6% | 237 | −5.0% |
| USD/JPY | 51 | +8.0% | 255 | −7.0% |
| AUD/USD | 45 | −8.4% | 261 | −19.5% |
| GBP/JPY | 44 | +1.7% | 235 | −13.2% |
| Gold | 45 | −3.1% | 224 | +12.7% |
| Silver | 40 | +5.7% | 218 | +0.6% |
| S&P 500 | 38 | −0.1% | 250 | −8.0% |
| Nasdaq 100 | 45 | −8.0% | 236 | +0.6% |
| DAX | 30 | −8.2% | 251 | −15.6% |
| All 10 markets, in R | 411 | −8.5R | 2,403 | −45.0R |
We also tested two of the changes explained further down. With ADX above 20, the daily rules made 74 to 95 trades per market, 864 in total, and these lost 8.3R together. Waiting for ADX to rise above 25 made 70 to 93 trades per market, 829 in total, and these lost 42.7R together. With the standard rules, the test skipped 13 daily signals on gold, silver, the Nasdaq 100 and the DAX. A trade that risked 1% would have been smaller than the smallest trade size.
The strategy
What the ADX / DMI crossover is
The DMI (Directional Movement Index) is an indicator that J. Welles Wilder published in 1978. It draws three lines under the chart, each calculated over the last 14 candles with Wilder's average (a slow moving average). +DI (the plus directional indicator) measures how strongly price has been moving up: how far the highs rose above the highs before them. -DI (the minus directional indicator) measures how strongly price has been moving down: how far the lows fell below the lows before them. Both lines are divided by the ATR (average true range: how far price moves in an average candle, over the last 14 candles). So they compare each move with the normal movement. ADX (the average directional index) measures how strong the trend is, up or down, on a scale from 0 to 100. It is high when one DI line has stayed far above the other, and low when the two lines are close together. ADX does not show the direction: only the DI lines do. Many traders read ADX above 25 as a strong trend, and ADX below 20 as no trend. The ADX / DMI crossover strategy trades the crosses of the two DI lines, but only when ADX is above 25. Wilder's own system in his book had more rules: for example, the stop-loss of a buy was the low of the candle where the lines crossed. We tested the simpler rules most traders use today.
- DMI and ADX
- 14 candles for +DI, -DI and ADX, with Wilder's average: the usual default on TradingView and other charting platforms
- ADX level
- Above 25, on the candle where +DI and -DI cross
- Stop-loss
- 2 × ATR(14) from the close of the last candle before the trade opens. The stop-loss does not move.
- Exit
- The next cross of +DI and -DI the other way, at any ADX value. The trade closes at the next candle's open.
- Take-profit
- None
- Risk per trade
- 1% of the account, which started at $10,000. The trade size is calculated at the close of the last candle before the trade opens, and rounded down to a size the market allows. The trade then opens at the next candle's open. So most stop-loss losses were between 0.8% and 1% of the account, before costs. When price jumped past the stop-loss, for example over a weekend, the loss was bigger. With the standard rules, 55 of the 30,670 trades hit their stop-loss with a loss of more than 1.5%: 45 on 15-minute charts and 10 on 1-hour charts. The biggest, 5.8%, was an S&P 500 trade on the 15-minute chart, over the weekend of 3 to 5 May 2019.
- Trading costs
- The spread, which is the gap between the buy price and the sell price. On currency pairs, the spread is in pips: a pip is 0.0001 on EUR/USD, GBP/USD and AUD/USD, and 0.01 on the pairs with the Japanese yen. The spread is 0.8 pips on EUR/USD, 1.2 on GBP/USD, 0.9 on USD/JPY, 1.0 on AUD/USD and 2.5 on GBP/JPY. It is $0.30 an ounce on gold and $0.020 on silver, and 0.4 points on the S&P 500, 1.5 on the Nasdaq 100 and 1.0 on the DAX. For silver, the Nasdaq 100 and the DAX, these are wider than our backtest engine's own spreads, to match a typical retail broker. Our test treats chart prices as the middle between the buy price and the sell price. These rules use only market orders and stop-losses, so every trade pays half the spread when it opens and half when it closes. On average, the spread cost a trade 6.8% of the money it risked on 15-minute charts, 3.4% on 1-hour charts and 1.6% on 4-hour charts. There is no commission.
- Smallest trade size
- A trade that risks 1% can be smaller than the smallest trade size a market allows. The smallest sizes are 1,000 units of a currency pair, 1 ounce of gold, 50 ounces of silver and 0.1 of an index contract. On an index, 0.1 of a contract gains or loses 0.10 dollars or euros per point. Then the test skips the signal. With the standard rules, this happened 31 times on 1-hour and 4-hour charts. 27 of them were on silver from October to December 2025, when silver's volatility rose: its candles became about 3 times bigger than before. The other 4 were on the Nasdaq 100 and the DAX in April 2025. On 15-minute charts, it happened 1,404 times, always after the account had lost more than half of its starting balance. A very close stop-loss can also need a bigger trade than our backtest engine allows: 30 times the account balance on currency pairs, and 20 times on metals and indices. Then the trade uses the biggest size allowed and risks less than 1%. This happened in 6 trades, all on 15-minute charts.
- Price data
- CFD prices: the prices a broker quotes for a CFD (contract for difference), the product most brokers outside the US offer for trading these markets. The rules leave two kinds of candle out, and these candles don't count for +DI, -DI, ADX or the ATR. First, on some Fridays, our S&P 500, Nasdaq 100 and DAX data has a few minutes of prices after the weekly close at 17:00 New York time. These make a tiny extra candle. Second, some candles show no price change at all (the high equals the low), for example on market holidays. In the 30 tests from 2019 to 2025, these were less than 1% of the candles in every test. In the daily tests from 2014 to 2025, they were 5.7% of the S&P 500 candles, 5.3% of the Nasdaq 100 candles and 2.7% of the DAX candles. Most of them were tiny Friday candles from 2014 to 2018. When no candle is left out, the strategy's +DI, -DI and ADX are the same as those of the ADX indicator in BacktestingMax.
- Overnight fees
- Not included. Brokers charge a fee (a swap), or sometimes pay one, for each night a trade stays open. With the standard rules, half of the trades were open for 75 minutes or less on 15-minute charts. On 1-hour charts, half were open for 6 hours or less. On 4-hour charts, half were open for more than 27 hours, so most of these trades would pay or earn at least one night's fee.
The rules we tested
- Use the DMI with its usual setting, 14: +DI, -DI and ADX each use Wilder's 14-candle average. We check the lines when each candle closes. A trade opens at the next candle's open.
- Buy when +DI crosses above -DI, if ADX is above 25 on that candle. Sell short when -DI crosses above +DI, if ADX is above 25 on that candle. If ADX is 25 or lower, skip the cross.
- Close the trade when the two lines cross the other way, at any ADX value. A buy closes when -DI crosses above +DI, and a sell closes when +DI crosses above -DI. The trade closes at the next candle's open.
- If ADX is above 25 on the candle where the lines cross the other way, that cross also opens a new trade in the new direction. This trade opens one candle later than usual (two candles after the cross), because our test opens a new trade only after the old trade has closed. It opens only if the lines have not crossed again by then.
- ATR is an indicator of how far price moves in an average candle, over the last 14 candles. Put the stop-loss 2 times the ATR away from the close of the last candle before the trade opens. The stop-loss does not move. After a stop-loss, wait for the next cross that meets the rules.
- Size every trade so that a loss at the stop-loss costs 1% of the account.
The method
How we tested it
The test
- Markets
- EUR/USD, GBP/USD, USD/JPY, AUD/USD, GBP/JPY, Gold, Silver, S&P 500, Nasdaq 100 and DAX
- Charts
- 15-minute, 1-hour and 4-hour candles
- Dates
- January 2019 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 2019 to 2022 and again from 2023 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 2023 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 ADX / DMI crossover be improved?
We tried three changes traders argue about: no ADX filter at all, a lower ADX level of 20, and waiting for ADX to rise above 25 after the cross. Each change ran on the same 30 tests. If you choose a change on some years and judge it on the same years, it will almost always look good. So we chose the change that made money in the most tests in 2019–2022. Then we checked it on 2023–2025, years we did not use to choose it.
| Version | Made money 2019–2022years used to pick the best version | Made money 2023–2025years not used to pick it | Made money in both periods | Passed all four checks |
|---|---|---|---|---|
| Standard rules: a cross with ADX above 25 The rules under 'The rules we tested', with nothing changed. | 4 of 30middle test −29.4% | 10 of 30middle test −6.8% | 1 | 1 |
| No ADX filter: every crossBest on 2019–2022 Trade every cross of +DI and -DI, at any ADX value. A cross the other way closes the trade and opens a new trade the other way, so a trade is open almost all the time. This is the DMI crossover on its own. | 12 of 30middle test −36.3% | 6 of 30middle test −27.9% | 5 | 1 |
| A lower ADX level: 20 Trade a cross only if ADX is above 20 on that candle, instead of 25. Many traders use 20. ADX is above 20 at about twice as many crosses as above 25. | 7 of 30middle test −48.5% | 5 of 30middle test −13.2% | 2 | 1 |
| Wait for ADX to rise above 25 When a cross comes with ADX at 25 or lower, don't skip it: wait. Buy when ADX rises above 25 while +DI is still above -DI, or sell short when ADX rises above 25 while -DI is still above +DI. A cross with ADX already above 25 still opens a trade at once. The next cross the other way closes the trade. | 8 of 30middle test −20.9% | 5 of 30middle test −22.9% | 2 | 1 |
Every change made money in more tests than the standard rules in 2019–2022, and in fewer tests in 2023–2025. With no ADX filter, 12 of 30 tests made money in 2019–2022, the years we used to choose, compared with 4 with the standard rules. In 2023–2025, the years we kept for the check, it made money in only 6 of 30, compared with 10 of 30. In 2023–2025, the no-filter version's middle test (half of the 30 did better, half did worse) lost 27.9%, compared with 6.8% with the standard rules. From 2019 to 2025, 8 of 30 no-filter tests made money, compared with 7 of 30. With no filter, 5 tests made money in both periods (USD/JPY, gold and the DAX on 1-hour charts, and gold and the S&P 500 on 4-hour charts). With the standard rules, only 1 did (USD/JPY on the 4-hour chart). With ADX above 20, 7 of 30 tests made money in 2019–2022 and 5 in 2023–2025. Waiting for ADX to rise above 25 made money in 8 tests in 2019–2022 and 5 in 2023–2025. Each of these two changes made money in both periods in the same 2 tests: gold on the 4-hour chart and the DAX on the 1-hour chart. So no change made the strategy reliably better.
Passed all four checks with no ADX filter: every cross
- Gold, 4-hour
Questions
Questions traders ask
Does the ADX / DMI crossover strategy work?
Mostly no. The standard rules buy or sell short at a cross of +DI and -DI, if ADX is above 25. In our backtest from 2019 to 2025, after trading costs, they made money in 7 of 30 tests. Only USD/JPY on the 4-hour chart made money in both 2019–2022 and 2023–2025. The 4-hour charts did best: 5 of the 10 markets made money there. On 15-minute charts, all 10 lost money.
What does ADX above 25 mean?
ADX measures how strong a trend is, from 0 to 100, but not its direction. Many traders read ADX above 25 as a strong trend, and below 20 as no trend. But ADX is slow. In our 30 tests, ADX was above 25 at only 17.8% of the crosses of +DI and -DI, and in 96.6% of those crosses, ADX was falling. So when the lines cross, a high ADX mostly comes from the move before the cross, not from the new one.
Is ADX 20 or 25 better for the DMI crossover?
Neither was clearly better in our backtest. With a level of 20, the rules trade about twice as many crosses: ADX was above 20 at 37.2% of the crosses, and above 25 at 17.8%. With a level of 20, 5 of 30 tests made money from 2019 to 2025, and 2 made money in both 2019–2022 and 2023–2025. With 25, 7 of 30 made money, and 1 in both periods. We also traded every cross on 1-hour and 4-hour charts. There, the trades after a cross with ADX above 20, up to 25, lost 2.4% of the money they risked, on average. The trades after a cross with ADX above 25 lost 3.6%. So over 2019–2025, the extra crosses that a level of 20 adds did no worse than the crosses above 25.
Should ADX be rising when +DI and -DI cross?
No: requiring it would skip almost every trade. In 96.6% of the crosses with ADX above 25 in our test, ADX was lower than on the candle before. Another common rule waits on the crosses that come with ADX at 25 or lower: it buys once ADX rises above 25, if +DI is still above -DI. Crosses with ADX already above 25 still trade at once. When this rule had to wait, ADX took 10 candles or more to rise above 25 in half of the cases. It made money in 8 of 30 tests in 2019–2022 and 5 of 30 in 2023–2025, compared with 4 and 10 with the standard rules. So waiting did better in 2019–2022 and worse in 2023–2025.
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 AdxDmiCrossover(Strategy):
"""The ADX / DMI crossover (Welles Wilder's directional movement system), as most traders
trade it today, plus the changes traders argue about.
The DMI (directional movement index) has three lines, each smoothed over 14 candles with
Wilder's average:
+DI how strong the upward movement was: how far each high rose above the high before it
-DI how strong the downward movement was: how far each low fell below the low before it
ADX how strong the trend is, up or down, from 0 to 100: the smoothed gap between +DI
and -DI, as a share of the two together
+DI and -DI are divided by the ATR (the average true range: how far price moves in an
average candle), so they are percentages of the normal movement.
Standard (all switches off): buy when +DI crosses above -DI while ADX is above 25; sell
short when -DI crosses above +DI while ADX is above 25. The opposite cross closes the
trade at the next candle's open. If ADX is above 25 at that cross, a trade the other way
opens one candle later, once the old trade has closed (dropped if the lines crossed back).
A stop-loss 2 x ATR(14) away caps each trade; size so that the stop costs 1% of the
account. After a stop-loss, wait for the next signal.
Skipped candles: a candle that opens on a Friday at 17:00 New York time or later (the
markets in this test are closed then, but some S&P 500 and DAX data has a few minutes of
prices after the close, which make a tiny extra candle), and a flat candle (high = low: no
price change at all, for example on a market holiday). The strategy ignores them: they do
not go into +DI, -DI, ADX or the ATR, and they can't be a signal. That is why the lines are
worked out here instead of with the built-in indicator (builtin:adx gives the same numbers
when no candle is skipped). On a market that trades at the weekend, remove the Friday skip.
The changes, one at a time:
adx_min = 0 no ADX filter: trade every +DI / -DI cross
adx_min = 20 a lower ADX level: 20 instead of 25
wait_adx = 1 don't skip a cross when ADX is 25 or lower: wait, and buy when ADX rises
above 25 while +DI is still above -DI (sell when -DI is above +DI). A cross
while ADX is above 25 still trades at once.
"""
params = {"period": Param(type=int, default=14, min=2, max=100),
"adx_min": Param(type=float, default=25.0, min=0.0, max=100.0),
"wait_adx": Param(type=int, default=0, min=0, max=1),
"atr_mult": Param(type=float, default=2.0, min=0.5, max=10.0)}
lookback = 2
def init(self, ctx):
self.ny = ctx.clock("America/New_York")
self.prev_candle = None # high, low and close of the last candle used
self.atr = None # Wilder's average of the true range (the ATR)
self.plus_dm = None # Wilder's average of the upward movement
self.minus_dm = None # Wilder's average of the downward movement
self.adx = None # Wilder's average of DX
self.candles = 0
self.dx_count = 0
self.prev = None # +DI, -DI and ADX on the last candle used
self.reverse_to = None # "long" / "short": open this once the closing trade is gone
def skip(self, ctx):
"""A tiny candle after the Friday close, or a flat candle (see above)."""
friday_evening = self.ny.weekday == 4 and self.ny.hour >= 17
return friday_evening or ctx.high[0] == ctx.low[0]
def update_dmi(self, ctx):
"""+DI, -DI and ADX on this candle, exactly as Wilder defined them."""
n = ctx.params.period
high, low, close = ctx.high[0], ctx.low[0], ctx.close[0]
if self.prev_candle is None:
true_range, up_move, down_move = high - low, 0.0, 0.0
else:
prev_high, prev_low, prev_close = self.prev_candle
true_range = max(high - low, abs(high - prev_close), abs(low - prev_close))
up = high - prev_high
down = prev_low - low
up_move = up if up > down and up > 0 else 0.0
down_move = down if down > up and down > 0 else 0.0
self.prev_candle = (high, low, close)
if self.atr is None:
self.atr, self.plus_dm, self.minus_dm = true_range, up_move, down_move
else:
self.atr += (true_range - self.atr) / n
self.plus_dm += (up_move - self.plus_dm) / n
self.minus_dm += (down_move - self.minus_dm) / n
self.candles += 1
if self.candles < n:
return None
plus = 100.0 * self.plus_dm / self.atr if self.atr > 0 else 0.0
minus = 100.0 * self.minus_dm / self.atr if self.atr > 0 else 0.0
dx = 100.0 * abs(plus - minus) / (plus + minus) if plus + minus > 0 else 0.0
self.adx = dx if self.adx is None else self.adx + (dx - self.adx) / n
self.dx_count += 1
if self.dx_count < n:
return None
return plus, minus, self.adx
def on_bar(self, ctx):
if self.skip(ctx):
return
now = self.update_dmi(ctx)
prev, self.prev = self.prev, now
if now is None or prev is None:
return
plus, minus, adx = now
prev_plus, prev_minus, prev_adx = prev
cross_up = prev_plus <= prev_minus and plus > minus # +DI crosses above -DI
cross_down = prev_plus >= prev_minus and plus < minus # -DI crosses above +DI
level = ctx.params.adx_min
strong = level <= 0 or adx > level
if ctx.params.wait_adx == 1:
# A signal is the first candle with both: the DIs in the trade's direction and ADX
# above the level, whichever came last.
was_strong = level <= 0 or prev_adx > level
long_signal = plus > minus and strong and not (prev_plus > prev_minus and was_strong)
short_signal = minus > plus and strong and not (prev_minus > prev_plus and was_strong)
else:
long_signal = cross_up and strong
short_signal = cross_down and strong
pos = ctx.position
if pos is not None:
if pos.is_long and cross_down:
ctx.close_position()
self.reverse_to = "short" if short_signal else None
elif pos.is_short and cross_up:
ctx.close_position()
self.reverse_to = "long" if long_signal else None
return
# A reversal waits one candle for the close to fill. Drop it if the DIs crossed back.
pending, self.reverse_to = self.reverse_to, None
if pending == "long" and plus > minus:
long_signal = True
if pending == "short" and minus > plus:
short_signal = True
entry = ctx.close[0]
distance = ctx.params.atr_mult * self.atr
if ctx.gate("buy_signal", long_signal):
stop = entry - distance
ctx.buy(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop, tag="dmi_long")
elif ctx.gate("sell_signal", short_signal):
stop = entry + distance
ctx.sell(size=ctx.size_by_risk_pct(0.01, stop=stop, entry=entry), sl=stop, tag="dmi_short")
Your turn
Test the ADX / DMI crossover yourself
Change the settings, the market or the stop-loss and see the result in seconds. Ask the BacktestingMax AI: Backtest the ADX / DMI crossover on USD/JPY, 4-hour chart, with and without the ADX 25 filter
.
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 26 October 2026.