Tested by BacktestingMax
Order block strategy backtest
Do order blocks work?
Mostly no. With our standard rules, only 5 of our 30 backtests made money after trading costs. We tested 10 markets (4 currency pairs, gold, silver and 4 stock indices), each on 15-minute, 1-hour and 4-hour charts, from 2020 to 2025. An order block is the last candle in the opposite direction before a fast move. For a buy, it is the last down candle before price moves up fast and closes above a recent high. Only 2 tests made money in both 2020–2023 and the newer years, 2024–2025: USD/JPY and GBP/USD on 4-hour charts. Price came back to 77.5% of the blocks within 100 candles, but it did not turn there often enough to make money. Blocks with a fair value gap (a gap that the fast move leaves between candles), blocks that swept a recent low first, and deeper entries did not win more often. And one result goes against what most teachers say. The fast move mattered, but the break of a recent high or low within 3 candles did not. Without that rule, 7 of the 30 tests made money, though the average trade still lost after costs.
30 backtests 2020–2025 Trading costs included Tested 2 November 2026
Where it worked 30 backtests- Made money
- 5 of 30 tests, with the standard rules
- Made money in both periods
- 2 2020–2023 and again 2024–2025
- Best backtest
- +29% USD/JPY, 4-hour chart: account growth 2020–2025
- Only blocks that swept liquidity first
- 0 tests made money in both periods, compared with 2 with the standard rules
Made money in both periods
- GBP/USD, 4-hour
- USD/JPY, 4-hour
The results
Results on every market
Each box shows one backtest of the order block strategy with the standard rules, 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 | −39% Lost money | −10% Lost money | −22% Lost money |
| GBP/USD | −77% Lost money | −31% Lost money | +16% Passed all four checks |
| USD/JPY | +24% Made money overall, lost in one period | +6% Made money overall, lost in one period | +29% Passed all four checks |
| GBP/JPY | −86% Lost money. Account down 90% by Oct 2025 | −40% Lost money | −10% Lost money |
| Gold | −72% Lost money | −38% Lost money | +9% Made money overall, lost in one period |
| Silver | −74% Lost money | −61% Lost money | −18% Lost money |
| Nasdaq 100 | −84% Lost money | −14% Lost money | −18% Lost money |
| S&P 500 | −49% Lost money | −25% Lost money | −6% Lost money |
| Dow Jones | −85% Lost money | −6% Lost money | −12% Lost money |
| DAX | −37% Lost money | −28% Lost money | −21% 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 | 2,047 | 34.4% | 0.97 | −38.6% | −56.8% | +18.3% | −48.1% | −72.5% | $9,136 |
| EUR/USD | 1-hour | 574 | 33.6% | 0.97 | −10.4% | −22.2% | −10.0% | −0.4% | −44.3% | $1,261 |
| EUR/USD | 4-hour | 165 | 29.1% | 0.80 | −22.3% | −34.8% | −16.1% | −7.4% | −34.6% | $246 |
| GBP/USD | 15-minute | 1,973 | 32.9% | 0.90 | −76.6% | −79.7% | −61.3% | −39.5% | −85.3% | $5,851 |
| GBP/USD | 1-hour | 572 | 32.2% | 0.89 | −31.0% | −45.3% | −41.6% | +18.0% | −52.2% | $1,090 |
| GBP/USD | 4-hour | 159 | 37.1% | 1.15 | +15.6% | −20.6% | +0.2% | +15.4% | −20.1% | $265 |
| USD/JPY | 15-minute | 1,914 | 35.2% | 1.01 | +23.6% | −43.8% | +53.8% | −19.6% | −59.1% | $9,916 |
| USD/JPY | 1-hour | 549 | 34.6% | 1.02 | +6.0% | −35.6% | −8.3% | +15.6% | −39.3% | $1,385 |
| USD/JPY | 4-hour | 140 | 40% | 1.32 | +29.4% | −9.3% | +6.1% | +22.0% | −16.1% | $188 |
| GBP/JPY | 15-minute | 1,946 | 32.7% | 0.88 | −86.4% | −90.9% | −72.6% | −50.2% | −90.8% | $7,959 |
| GBP/JPY | 1-hour | 550 | 32% | 0.84 | −39.6% | −49.2% | −47.1% | +14.2% | −56.7% | $1,429 |
| GBP/JPY | 4-hour | 115 | 31.3% | 0.88 | −9.5% | −24.1% | −10.2% | +0.9% | −24.7% | $232 |
| Gold | 15-minute | 1,921 | 33.2% | 0.92 | −72.3% | −78.3% | −46.6% | −48.2% | −83.7% | $7,222 |
| Gold | 1-hour | 510 | 31.6% | 0.86 | −37.5% | −40.8% | −33.5% | −6.0% | −54.4% | $1,091 |
| Gold | 4-hour | 129 | 36.4% | 1.11 | +9.0% | −10.4% | +11.4% | −2.2% | −18.9% | $175 |
| Silver | 15-minute | 1,708 | 35.7% | 0.89 | −74.3% | −81.1% | −65.2% | −26.0% | −84.3% | $12,942 |
| Silver | 1-hour | 490 | 30% | 0.76 | −60.6% | −65.0% | −43.0% | −31.0% | −67.2% | $2,809 |
| Silver | 4-hour | 143 | 30.1% | 0.81 | −18.3% | −21.5% | −2.7% | −16.0% | −30.7% | $580 |
| Nasdaq 100 | 15-minute | 1,952 | 31.4% | 0.87 | −83.7% | −86.2% | −55.8% | −63.1% | −89.0% | $3,343 |
| Nasdaq 100 | 1-hour | 608 | 33.2% | 0.96 | −13.8% | −27.2% | −8.7% | −5.6% | −46.0% | $889 |
| Nasdaq 100 | 4-hour | 200 | 30.5% | 0.86 | −17.5% | −23.9% | −10.6% | −7.7% | −33.5% | $163 |
| S&P 500 | 15-minute | 1,934 | 33.5% | 0.95 | −49.3% | −59.4% | −22.9% | −34.2% | −74.9% | $6,053 |
| S&P 500 | 1-hour | 605 | 32.6% | 0.93 | −24.8% | −34.3% | −0.6% | −24.3% | −51.5% | $1,036 |
| S&P 500 | 4-hour | 174 | 32.8% | 0.94 | −6.3% | −24.4% | −12.4% | +7.0% | −27.4% | $184 |
| Dow Jones | 15-minute | 1,972 | 31.1% | 0.86 | −85.0% | −85.7% | −67.5% | −53.9% | −89.5% | $2,313 |
| Dow Jones | 1-hour | 594 | 33.5% | 0.99 | −5.5% | −36.4% | −7.8% | +2.4% | −42.0% | $669 |
| Dow Jones | 4-hour | 191 | 31.4% | 0.90 | −11.5% | −18.2% | −10.2% | −1.5% | −29.2% | $119 |
| DAX | 15-minute | 1,992 | 32.8% | 0.97 | −37.2% | −48.3% | −0.6% | −36.8% | −73.3% | $4,290 |
| DAX | 1-hour | 565 | 30.6% | 0.92 | −28.3% | −36.0% | +1.3% | −29.2% | −53.6% | $628 |
| DAX | 4-hour | 154 | 28.6% | 0.78 | −20.7% | −20.8% | −14.1% | −7.7% | −32.4% | $97 |
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 30 backtests show
With the standard rules, 5 of the 30 tests made money from 2020 to 2025, after trading costs. 3 of the 5 were on 4-hour charts: USD/JPY (+29.4%), GBP/USD (+15.6%) and gold (+9.0%). On the other charts, only USD/JPY made money: +23.6% on the 15-minute chart and +6.0% on the 1-hour chart. USD/JPY and GBP/USD on 4-hour charts made money in both 2020–2023 and 2024–2025, and both passed all four of our checks (see 'How a test passes'). But each had only about 25 trades a year, and each lost money in 2 or 3 years out of the 6. The other 25 tests lost between 5.5% (the Dow Jones, 1-hour chart) and 86.4% of the account (GBP/JPY, 15-minute chart).
Price came back to most blocks, but it did not turn there often enough to make money. Within 100 candles, price came back to the entry of 77.5% of the blocks: for a buy, it traded at the block's high again. Only 33.0% of the 26,546 trades reached the take-profit, which is about the break-even rate when the take-profit is twice as far as the stop-loss. Results are in R: 1R is 1% of the account at the time of the trade. Before costs, the average trade lost 0.003R, almost exactly zero. On 15-minute charts, the average trade made +0.003R before costs, the best of the three charts. But trading costs took 0.051R per trade there, and 9 of the 10 markets lost money. Our test charged trading costs only on trades that hit the stop-loss (see 'Trading costs'). So with a real broker, the costs would be a little higher.
Which of the two order block rules mattered: the fast move (displacement) or the break of structure? Displacement is a close at least 1.5 ATR beyond the block within 3 candles. ATR is the average size of a candle over the last 14 candles. The break of structure is a close beyond the last swing high (for a buy), the most recent peak on the chart, within the same 3 candles. We ran the same 30 tests three more times: without the fast-move rule, without the break-of-structure rule, and without either (see 'Which rule made a difference?'). Without the fast move, 32.4% of the trades reached the take-profit, and only 3 of the 30 tests made money. Without the break of structure, 33.9% did, and 7 of the 30 tests made money, 6 of them in both 2020–2023 and 2024–2025. In that run, the blocks whose fast move did not reach the last swing high (for a sell, the last swing low) did best. 35.2% of their 10,231 trades reached the take-profit, and before costs the average trade made +0.059R. For the blocks in that run whose move did break it, the average trade made +0.002R before costs. The blocks whose move did not reach it did better on 8 of the 10 markets and in both periods. We found this split after the test, so treat it as a reason to test further, not as a rule.
Entering deeper inside the block, closer to the stop-loss, did not help. With the limit order (an order that waits at a set price) at the block's open, 32.5% of the trades reached the take-profit. The open is the top of the candle's body, for a buy. At the middle of the block, 32.6% did, compared with 33.0% at the block's high. In many winning trades, price never went that deep. In 4,983 out of 8,769 winning trades at the high (56.8%), it never reached the middle of the block. A deeper entry is also closer to the stop-loss, so the same trading cost is a bigger part of the risk. Costs took 0.061R per trade at the open and 0.075R at the middle, compared with 0.044R at the high. After costs, the average trade lost 0.073R at the open and 0.081R at the middle, compared with 0.047R at the high (see 'Where to enter the block').
Coming back is not the same as turning
Price came back to 77.5% of the blocks, but it did not turn there often enough
- Blocks that price came back to within 100 candles
- 77.5% 28,695 out of 37,027 blocks, with the standard rules
- Of these blocks, the ones where price went on to the middle of the block
- 93.6% 26,869 out of 28,695, within the same 100 candles
- Trades that reached the take-profit
- 33.0% 8,769 out of 26,546 trades, with the standard rules
Price came back to a block when it traded at the block's entry price: its high for a bullish block, and its low for a bearish one. We followed each block for the same 100 candles that its limit order waited. The 37,054 blocks fall into four groups. The test traded 26,546 of them. Price came back to 2,149 more while another trade was open, or when the trade would have been too small. It did not come back to 8,332 within 100 candles. 27 blocks near the end of 2025 had fewer than 100 candles left, and price had not come back by then, so the first number leaves them out.
Which rule made a difference?
In our test, the fast move mattered. The break of structure did not
Each main row is the same 30 tests: 10 markets, each on 15-minute, 1-hour and 4-hour charts, from 2020 to 2025. The rows differ only in the order block rules: both, one of them, or neither. Displacement is the fast move: a close at least 1.5 ATR (one and a half times the average candle) beyond the block within 3 candles. The break of structure is a close beyond the last swing high (for a buy) or swing low (for a sell) within those 3 candles. The rows that start with '…' split the trades of the displacement-only run into three groups. Everything else stays the same: the entry at the block's edge, the stop-loss beyond the block and the take-profit twice as far as the stop-loss. Results are in R: 1R is 1% of the account at the time of the trade.
| Rules | Trades | Reached the take-profit | Average trade before costs | Average trade after costs | Tests that made money | Tests that made money in both periods |
|---|---|---|---|---|---|---|
| Both rules (the standard rules) | 26,546 | 33.0% | −0.003R | −0.047R | 5 of 30 | 2 |
| Displacement only, no break of structure needed | 41,683 | 33.9% | +0.021R | −0.021R | 7 of 30 | 6 |
| … of these, the move broke the last swing high (or low) | 23,986 | 33.2% | +0.002R | −0.042R | ||
| … of these, the last swing high (or low) had already been broken before the block | 7,464 | 34.1% | +0.028R | −0.010R | ||
| … of these, the move did not reach the last swing high (or low) | 10,231 | 35.2% | +0.059R | +0.019R | ||
| Break of structure only, no displacement needed | 64,386 | 32.4% | −0.022R | −0.066R | 3 of 30 | 1 |
| Neither rule: any down candle followed by a close above its high (for a sell, an up candle followed by a close below its low) | 109,391 | 32.3% | −0.024R | −0.061R | 0 of 30 | 0 |
'Tests that made money in both periods' counts tests with at least 100 trades that made money in 2020–2023 and again in 2024–2025. The '…' rows split the displacement-only trades into three groups. The split is by what the fast move had done to the last swing high (for a sell, the last swing low) before the block. We checked this on the candle that confirmed the block. We made this split after the test. The blocks whose move did not reach that swing point did better before costs on 8 of the 10 markets. They also did better in both periods: +0.063R per trade in 2020–2023 and +0.052R in 2024–2025, compared with +0.011R and −0.016R for the blocks whose move broke it. 2 trades came from blocks with no swing point before them, so the three '…' rows add up to 41,681 trades. Without displacement, the accounts on 15-minute charts fell fast: 9 of the 10 tests lost more than 90% of the account, and all 10 without either rule. After that, 1% of what was left was too small for many trades, so these two runs skipped many blocks, and some of their trades risked less than 1%.
Where to enter the block
Deeper entries filled almost as often, won about as often and paid more in costs
Each row is one version, run on the same 30 tests from 2020 to 2025. The limit order waits at the block's high (the standard rules), at its open (the top of the candle's body, for a buy) or at its middle. The stop-loss is the same in all three, just beyond the block. The take-profit is twice as far from the entry as the stop-loss. Results are in R: 1R is 1% of the account at the time of the trade.
| Entry | Blocks that price came back to within 100 candles | Trades | Reached the take-profit | Average trade before costs | Trading costs per trade | Average trade after costs | Tests that made money |
|---|---|---|---|---|---|---|---|
| The block's high (the standard rules) | 77.5% | 26,546 | 33.0% | −0.003R | 0.044R | −0.047R | 5 of 30 |
| The block's open (the top of its body) | 74.9% | 25,955 | 32.5% | −0.012R | 0.061R | −0.073R | 4 of 30 |
| The middle of the block (halfway between its high and low) | 72.6% | 25,473 | 32.6% | −0.006R | 0.075R | −0.081R | 5 of 30 |
For a sell, the entries are the mirror image: the block's low, its open (the bottom of the body) and its middle. With the standard rules, in 2,837 out of 8,769 winning trades, price never came back as far as the block's open. In every losing trade, price went through the whole block, because the stop-loss is beyond it. A deeper entry needs a bigger trade for the same 1% risk. Many of those trades hit the size limit of our backtest engine (see 'Trade size limits' under 'What the order block strategy is'). So more of their trades risked less than 0.8% of the account. That happened to 4,605 out of 25,473 trades at the middle and 3,189 out of 25,955 at the open, compared with 1,081 out of 26,546 at the high. Smaller trades win and lose less, so the averages in R of the deeper entries are a little closer to zero than they would be at a full 1% risk.
The strategy
What the order block strategy is
An order block is an idea from ICT and smart money concepts (SMC). ICT stands for The Inner Circle Trader, the online name of the trading teacher Michael Huddleston. SMC is a way of trading that came from his teaching. A bullish order block is the last down candle (a candle that closed lower than it opened) before a strong move up. A bearish order block is the last up candle before a strong move down. ICT teaches that big banks and funds leave orders at these candles, so price tends to come back to them and turn there again. Most teachers count a candle as an order block only when two things follow it. The move away from it must be big and fast: they call this displacement. And the move must break market structure. For a bullish block, a candle closes above the most recent swing high (a peak on the chart). For a bearish block, a candle closes below the most recent swing low (a dip). Traders then wait for price to come back to the block. They place a limit order (an order that waits at a set price) at the near edge of the block. That is the top of a bullish block, or the bottom of a bearish one. The stop-loss goes just past the far edge. They buy at a bullish block, and they sell short (sell first, to profit if price falls) at a bearish one. Teachers draw order blocks in different ways: from the whole candle, wicks included, or from its body only (open to close). Some also want a fair value gap after the block (a gap between candles that the fast move leaves), and they use different rules for the move. 'The rules we tested' lists our exact version.
- Swing points
- 3 candles on each side
- Order block
- One candle: the last down candle before a move up (for a buy), or the last up candle before a move down (for a sell). The block runs from the candle's high to its low, wicks included. Some teachers use the body only, or the whole run of down candles
- Break of structure
- Within the 3 candles after the block, a close beyond the most recent swing high (for a buy) or swing low (for a sell) before the block
- Displacement
- Within the same 3 candles, a close at least 1.5 × ATR(14) beyond the block's high (for a buy) or low (for a sell)
- Entry
- A limit order at the block's high (buy) or low (sell), filled the first time price comes back to it
- Stop-loss
- 1 pip beyond the block: below its low for a buy, above its high for a sell. 1 pip is 0.0001 on EUR/USD and GBP/USD, 0.01 on USD/JPY and GBP/JPY, $0.01 on gold, $0.001 on silver and 0.1 point on the indices
- Take-profit
- Twice the distance from the entry to the stop-loss. We use this same fixed distance in every test, so that all tests are judged the same way. Many ICT traders aim for the next swing high or low instead. We did not test that
- Block valid for
- The 100 candles after the candle that confirmed it: about 1 day on 15-minute charts, 4 days on 1-hour charts and 3 weeks on 4-hour charts
- Time of day
- Any time the market is open. No time-of-day filter
- Trend filter
- None. The test trades every block, with or against the bigger trend. It uses no higher-timeframe chart, no premium or discount zone and no signal on a shorter chart
- Order of events inside a candle
- We use 1-minute data to see which price came first. On the candle where an order fills, only the prices after the fill count. If the stop-loss is reached in the same minute as the entry or as the take-profit, the test counts the trade as a loss
- Risk per trade
- 1% of the account balance at the time of the trade. The account started at $10,000
- Trading costs
- The spread: the gap between the buy price and the sell price. Currency pairs: 0.8 pips on EUR/USD, 1.2 on GBP/USD, 0.9 on USD/JPY and 2.5 on GBP/JPY. Metals: $0.30 on gold and $0.020 on silver. Stock indices: 1.5 points on the Nasdaq 100, 0.4 on the S&P 500, 2.0 on the Dow Jones and 1.0 on the DAX. For silver, the Nasdaq 100, the Dow Jones 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. The entry (a limit order) and the take-profit fill at their own price and pay no spread. A trade that closes at the stop-loss pays half the spread. With a real broker, a buy limit order fills only when the price you buy at (the ask) comes down to it. A take-profit fills only when the price you sell at (the bid) reaches it. So with a real broker, some orders would not fill, and winning trades would pay about half a spread more. No commission
- Trade size limits
- Each market has a smallest trade size: 1,000 units of a currency pair, 1 ounce of gold, 50 ounces of silver, or 0.1 of an index contract. A trade that risks 1% can be smaller than that. Then the test skips that block. With the standard rules, this happened to 24 out of 37,054 blocks. Some trades also risked less than 1%, for three reasons. First, trade sizes are rounded down to the smallest step the market allows. Second, a very small block puts the stop-loss close to the entry, and a stop-loss that close needs a big trade for a 1% risk. Our backtest engine allows trades worth up to 30 times the account balance for currency pairs, and 20 times for gold, silver and the indices. A trade that would be bigger than that uses the biggest size allowed. Third, a few orders filled at a better price than planned, when a candle opened past the order's price (below it, for a buy). The order then filled at that open, closer to the stop-loss. With the standard rules, 1,081 out of 26,546 trades (4.1%) risked less than 0.8% of the account, 970 of them on 15-minute charts
- Overnight (swap) fees
- Not included. Brokers charge (or sometimes pay) a fee for each night a trade stays open. Half of the trades closed within 0.5 hours on 15-minute charts, 1.8 hours on 1-hour charts and 6.2 hours on 4-hour charts. On 4-hour charts, 19.1% of the trades stayed open longer than a day, so with a real broker those results could be a little higher or lower
- 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. Some of our data has a few minutes of prices after the weekly close on Fridays, which make a tiny extra candle. The rules leave these candles out
The rules we tested
- A swing high is a candle whose high is higher than the highs of the 3 candles before it and the 3 candles after it. A swing low is a candle whose low is lower than the lows of the 3 candles before it and the 3 candles after it. So a swing point is known only 3 candles after it forms.
- A bullish order block is a down candle (it closed lower than it opened). Two things must follow it within the next 3 candles, with no other down candle in between. First, a candle closes above the most recent swing high that formed before the block. That swing high must still be unbroken: no candle between it and the block closed above it. This is the break of structure.
- Second, a candle closes at least 1.5 ATR above the block's high. ATR (average true range) is the average height of a candle, from high to low, over the 14 candles up to the block. A jump from the previous candle's close counts too. This is the displacement. The block is confirmed on the candle where both things have happened.
- A bearish order block is the opposite: an up candle. Within the next 3 candles, with no other up candle in between, a candle closes below the most recent swing low. A candle also closes at least 1.5 ATR below the block's low.
- When a bullish block is confirmed, a buy limit order waits at the block's high. The stop-loss goes 1 pip below the block's low. The take-profit goes above the entry, twice as far from it as the stop-loss. For a bearish block, a sell limit order waits at the block's low. Its stop-loss goes 1 pip above the block's high, and its take-profit below the entry, again twice as far as the stop-loss.
- A block is valid for the 100 candles after the candle that confirmed it. Trade each block only once: the first time price comes back to its entry price. If price comes back to a block while another trade is open, skip that block.
- Take one trade at a time. While no trade is open, only two orders wait. One is a buy order at the nearest bullish block below the price. The other is a sell order at the nearest bearish block above it. When one order fills, the other is cancelled.
- Size every trade so that, if the stop-loss is hit, the trade loses 1% of the account.
- Leave out flat candles, where the high equals the low (the price did not move, for example on a holiday). Also leave out candles that open after the weekly close, on a Friday at 17:00 New York time or later. They are never blocks, swing points or signals, and they do not count in the ATR or in any count of candles.
The method
How we tested it
The test
- Markets
- EUR/USD, GBP/USD, USD/JPY, GBP/JPY, Gold, Silver, Nasdaq 100, S&P 500, Dow Jones 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 order block strategy be improved?
We tried four changes that traders often make, one at a time, on the same 30 tests. Two are stricter kinds of block: only blocks with a fair value gap, and only blocks that swept liquidity first. Two move the entry deeper into the block, closer to the stop-loss: to the block's open and to its middle. The table below explains each one. If you pick the best change and judge it on the same years you used to pick it, it almost always looks better than it really is. So we picked the best change using 2020–2023 only: the change that made money in the most tests. In a tie, we would pick the one with the better middle test (the median: half of the tests did better, half did worse). 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 |
|---|---|---|---|---|
| Standard rules The rules under 'The rules we tested'. Every block needs a break of structure and displacement. A limit order waits at the block's high (buy) or low (sell), and the take-profit is twice as far from the entry as the stop-loss. | 6 of 30middle test −10.4% | 8 of 30middle test −7.7% | 2 | 2 |
| Only blocks with a fair value gap Only trade a block if the fast move away from it left a fair value gap within the 3 candles after the block. A fair value gap is three candles in a row where the third candle's low is above the first candle's high, so the two do not overlap. The block itself can be the first of the three. For a sell, the third candle's high is below the first candle's low. Many teachers say a valid order block must leave a gap like this, which they also call an imbalance. | 6 of 30middle test −14.0% | 11 of 30middle test −8.5% | 1 | 1 |
| Only blocks that swept liquidity firstBest on 2020–2023 Only trade a bullish block if its low went below the most recent swing low before it. For a bearish block, its high must have gone above the most recent swing high. Many traders keep stop-loss orders just beyond these points, and SMC traders call them liquidity. Price going past them and then turning is a liquidity sweep. Many teachers say the best order blocks sweep liquidity before price turns. | 12 of 30middle test −1.3% | 14 of 30middle test −0.7% | 0 | 0 |
| Entry at the open of the block The limit order waits at the block's open instead of its high: the top of the candle's body for a buy, and the bottom of the body for a sell. This is how traders who draw the block from the candle's body enter. The stop-loss stays the same. The take-profit is twice as far from the new entry as the stop-loss. | 5 of 30middle test −19.4% | 9 of 30middle test −10.4% | 3 | 2 |
| Entry at the middle of the block The limit order waits halfway between the block's high and low. ICT calls the middle of a block its mean threshold, and many traders enter there; some measure it on the candle's body only. The stop-loss stays the same, so it is half as far from the entry as with the standard rules. The take-profit is twice as far from the new entry as the stop-loss. | 9 of 30middle test −16.4% | 5 of 30middle test −13.8% | 2 | 0 |
In 2020–2023, the years we used to pick the best change, the version with only blocks that swept liquidity first did best. 12 of 30 tests made money with it, compared with 6 with the standard rules. In 2024–2025, the years we kept for the check, it made money in 14 of 30, compared with 8. But it took only 6,862 trades, about a quarter of the 26,546 with the standard rules. With fewer trades, each test's result stayed closer to zero, so more of them ended a little above it. Its trades did not win more often: 33.0% reached the take-profit, the same as with the standard rules, and before costs the average trade lost 0.003R with both. All 10 of its 4-hour tests had fewer than 100 trades (14 to 39), too few to judge. Counting only tests with at least 100 trades, it made money in 7 of 20 in 2020–2023 and in 6 of 20 in 2024–2025. None of them made money in both periods, compared with 2 with the standard rules. With only blocks that had a fair value gap, 33.0% of the trades also reached the take-profit, and 3 of 30 tests made money from 2020 to 2025. The entries at the open and at the middle lost more after costs (see 'Where to enter the block'). So in our test, none of the four changes made order blocks clearly better. Dropping the break-of-structure rule is not one of these changes (see 'Which rule made a difference?'), and we did not pick it on 2020–2023. It made money in 12 of 30 tests in 2020–2023 and in 12 of 30 in 2024–2025, and in both periods in 6. But its average trade still lost 0.021R after costs.
Questions
Questions traders ask
Do order blocks work?
Mostly no, in our backtest. With our standard rules, order blocks made money in 5 of 30 tests from 2020 to 2025, after trading costs. We tested 10 markets, each on 15-minute, 1-hour and 4-hour charts. Only USD/JPY and GBP/USD on 4-hour charts made money in both 2020–2023 and 2024–2025. Price came back to most blocks, but it did not turn there often enough to make money. The extra rules traders add did not help. We tried two filters and two deeper entries. The first filter kept only blocks followed by a fair value gap: a gap between candles that the fast move leaves. The second kept only blocks that swept liquidity first: for a buy, price first went past a recent low. The deeper entries were the block's open and its middle. The fast move away from the block did matter: without it, only 3 of the 30 tests made money. And blocks whose fast move did not reach the last swing high did better than blocks whose move broke it. That is the opposite of what most teachers say. We found it after the test, so it needs more testing before anyone trades it.
What is the win rate of order blocks?
With our standard rules, 33.0% of the trades reached the take-profit before the stop-loss. The take-profit was twice as far from the entry as the stop-loss. The win rate hardly changed from chart to chart: 33.2% on 15-minute charts, 32.4% on 1-hour charts and 32.5% on 4-hour charts. The filters traders add did not change it either. It was 33.0% with only blocks that left a fair value gap, and 33.0% with only blocks that swept liquidity first. The two parts of the order block rule moved it more. Without the fast move (displacement), 32.4% of the trades reached the take-profit. Without the break of structure (a close beyond the last swing high within 3 candles), 33.9% did. And in that run, the blocks whose move did not reach the last swing high won 35.2% of the time.
Where should you enter an order block: at the high, the open or the middle?
In our backtest, entering at the block's high (for a sell, its low) lost the least, but no entry made money on most tests. At the high, 33.0% of the trades reached the take-profit. After costs, the average trade lost 4.7% of the money it was sized to risk. At the block's open (the top of its body), 32.5% reached it, and the average trade lost 7.3%. At the middle of the block, close to what ICT calls the mean threshold, 32.6% reached it, and the average trade lost 8.1%. A deeper order fills almost as often. Within 100 candles, price came back to the high of 77.5% of the blocks, to the open of 74.9% and to the middle of 72.6%. But a deeper entry is closer to the stop-loss, so the same trading cost is a bigger part of the risk.
Does price always come back to an order block?
Most of the time. But price coming back did not mean the trade won. In our backtest, price came back to the entry of 77.5% of the order blocks within 100 candles, and of 92.8% within 1,000 candles. The shares were about the same on 15-minute, 1-hour and 4-hour charts. When price came back within 100 candles, it went on to the middle of the block 93.6% of the time. Price coming back is common. What matters is whether it turns there. It did not turn often enough to make money: with the standard rules, 25 of the 30 tests lost money.
Keep exploring
Related strategies we tested
ICT & smart money ICT Power of 3 (AMD) backtest on NQ, ES and gold futures Made money in 4 of 10 tests, 2 of them in both periods. Best: YM (Dow futures), 15-minute, +46% ICT & smart money Change of character (CHoCH) and market structure shift (MSS) backtest Made money in 7 of 40 tests, 5 of them in both periods. Best: USD/JPY, 1-hour, +66% ICT & smart money ICT Silver Bullet backtest on NQ and ES futures Made money in 0 of 10 tests, 0 of them in both periods. Best: MGC (Micro Gold), 5-minute, −2% ICT & smart money Fair value gap (FVG) retest strategy backtest Made money in 5 of 24 tests, 2 of them in both periods. Best: S&P 500, 15-minute, +124% ICT & smart money ICT New York killzone backtest on NQ and ES futures Made money in 4 of 10 tests, 1 of them in both periods. Best: MGC (Micro Gold), 15-minute, +36%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 OrderBlock(Strategy):
"""Order block, the ICT / smart money concepts (SMC) entry: buy when price comes back to
a bullish order block, sell when it comes back to a bearish one. Educators draw order
blocks in different ways; this is ours.
Swing points. A swing high is a candle whose high is higher than the highs of the 3
candles before it and the 3 candles after it, so it is only known 3 candles later. A
swing low is the mirror image.
A bullish order block is the last down candle (it closed below its open) before a fast
move up that breaks structure. Within the 3 candles after it, with no down candle among
them:
- a candle closes above the most recent swing high before the block (the break of
structure), and
- a candle closes at least 1.5 x ATR(14) above the block's high (the displacement).
ATR(14) is the average size of the 14 candles up to and including the block (average
true range, Wilder's smoothing). The block is confirmed on the candle where both are
true. A bearish order block is the mirror image: the last up candle before a move down
that closes below the most recent swing low and at least 1.5 x ATR(14) below the
block's low.
Standard (all switches at their defaults):
1. When a bullish block is confirmed, a buy limit order waits at the block's high.
Stop-loss 1 pip below the block's low. Take-profit at 2R: twice the distance from
the entry to the stop-loss. A bearish block mirrors it: a sell limit order at the
block's low, stop-loss 1 pip above its high.
2. A block counts for the 100 candles after it is confirmed. It is used up the first
time price comes back to its entry price: traded, or skipped if a trade is open.
3. One trade at a time. While no trade is open, one buy order waits at the nearest
bullish block below the price and one sell order at the nearest bearish block
above it, because price reaches those blocks first.
4. Size every trade so that the stop-loss costs 1% of the account.
Skipped candles: flat candles (high = low: no price moved, e.g. a holiday in the data)
and candles that open on a Friday at 17:00 New York time or later (a few minutes of
prices after the weekly close in some data). They are never blocks, swing points or
signals, and they don't count in the ATR or in any candle count.
The changes, one at a time:
gap = 1 only blocks whose move up (down) left a fair value gap within those 3
candles: three candles in a row, the first one of them the block or later,
where the third candle's low is above the first candle's high (for a
bearish block, the third candle's high is below the first candle's low)
sweep = 1 only blocks that took liquidity first: the block's low went below the most
recent swing low before it (for a bearish block, its high above the most
recent swing high)
entry = 1 the limit order waits at the middle of the block (halfway between its high
and low) instead of its high (low); same stop-loss, take-profit 2R from there
entry = 2 the limit order waits at the block's open, the top of its body for a down
candle (the bottom for an up candle), instead of its high (low)
The page also checks what the definition itself adds: bos = 0 (no break of structure
needed) and disp = 0 (no displacement: any close above the block's high counts).
"""
params = {"disp": Param(type=float, default=1.5, min=0.0, max=10.0),
"bos": Param(type=int, default=1, min=0, max=1),
"gap": Param(type=int, default=0, min=0, max=1),
"sweep": Param(type=int, default=0, min=0, max=1),
"entry": Param(type=int, default=0, min=0, max=2),
"rr": Param(type=float, default=2.0, min=0.5, max=10.0),
"expiry": Param(type=int, default=100, min=1, max=1000)}
lookback = 5
def init(self, ctx):
self.ny = ctx.clock("America/New_York")
self.n = 0 # candles counted so far (skipped candles are not counted)
self.recent = [] # the last 7 counted candles: [n, open, high, low, close]
self.highs = [] # recent swing highs: [n, price, n of the first close above it]
self.lows = [] # recent swing lows: [n, price, n of the first close below it]
self.atr = None
self.trs = []
self.cand = {1: None, -1: None} # the last down (up) candle that can still become a block
self.blocks = [] # confirmed blocks that price has not come back to yet
self.orders = {} # side -> [block, order] resting now
def on_bar(self, ctx):
p = ctx.params
o, h, l, c = ctx.open[0], ctx.high[0], ctx.low[0], ctx.close[0]
# Blocks price came back to on this candle are used up: traded, or skipped because a
# trade was open.
self.blocks = [b for b in self.blocks
if not (l <= b["entry"] if b["side"] > 0 else h >= b["entry"])]
after_close = (self.ny.weekday == 4 and self.ny.minute_of_day >= 17 * 60) or self.ny.weekday == 5
if h > l and not after_close:
self.count_candle(ctx, o, h, l, c)
# A block counts for the 100 candles after the one that confirmed it.
self.blocks = [b for b in self.blocks if self.n - b["formed"] < p.expiry]
if ctx.position is not None:
# One trade at a time: no other order waits while a trade is open.
for side, (block, order) in list(self.orders.items()):
ctx.cancel_order(order.order_id)
self.orders = {}
return
for side in (1, -1):
mine = [b for b in self.blocks if b["side"] == side]
# The nearest block: the highest bullish entry below the price, the lowest
# bearish entry above it.
best = None
if mine:
best = max(mine, key=lambda b: b["entry"]) if side > 0 else min(mine, key=lambda b: b["entry"])
current = self.orders.get(side)
if current is not None and current[0] is not best:
ctx.cancel_order(current[1].order_id) # filled, used up, or a nearer block formed
del self.orders[side]
if not ctx.gate("block_waiting", best is not None) or side in self.orders:
continue
entry, stop = best["entry"], best["stop"]
size = ctx.size_by_risk_pct(0.01, stop=stop, entry=entry)
if not ctx.gate("size_at_least_the_minimum", size > 0):
self.blocks.remove(best) # too small to trade at 1% risk: skip this block
continue
target = entry + side * p.rr * abs(entry - stop)
if side > 0:
order = ctx.buy(size=size, limit=entry, sl=stop, tp=target, tag="ob_buy")
else:
order = ctx.sell(size=size, limit=entry, sl=stop, tp=target, tag="ob_sell")
if order is None:
self.blocks.remove(best) # rejected by the broker rules: skip this block
else:
self.orders[side] = [best, order]
def count_candle(self, ctx, o, h, l, c):
"""Add one counted candle: ATR, swing points, and the order block candidates."""
p = ctx.params
self.n += 1
n = self.n
prev_close = self.recent[-1][4] if self.recent else None
tr = h - l if prev_close is None else max(h - l, abs(h - prev_close), abs(l - prev_close))
if self.atr is None:
self.trs.append(tr)
if len(self.trs) == 14:
self.atr = sum(self.trs) / 14
else:
self.atr = (self.atr * 13 + tr) / 14
self.recent = (self.recent + [[n, o, h, l, c]])[-7:]
# Swing points: the candle 3 back, once the 3 candles after it have closed.
if len(self.recent) == 7:
mid = self.recent[3]
others = self.recent[:3] + self.recent[4:]
if all(mid[2] > x[2] for x in others):
self.highs = (self.highs + [[mid[0], mid[2], None]])[-10:]
if all(mid[3] < x[3] for x in others):
self.lows = (self.lows + [[mid[0], mid[3], None]])[-10:]
for s in self.highs:
if s[2] is None and c > s[1]:
s[2] = n
for s in self.lows:
if s[2] is None and c < s[1]:
s[2] = n
for side in (1, -1):
# The block is the last candle that went the other way: a down candle before a
# move up (side 1), an up candle before a move down (side -1).
if (c - o) * side < 0:
self.cand[side] = self.new_candidate(side, n, o, h, l, c)
continue
cand = self.cand[side]
if cand is None or cand["done"]:
continue
if n - cand["n"] > 3:
self.cand[side] = None
continue
cand["extreme"] = c if cand["extreme"] is None else (max(cand["extreme"], c) if side > 0 else min(cand["extreme"], c))
first = self.recent[-3] if len(self.recent) >= 3 else None
if first is not None and first[0] >= cand["n"]:
if (l > first[2]) if side > 0 else (h < first[3]):
cand["gap"] = True
if cand["atr"] is None:
continue
edge = cand["h"] if side > 0 else cand["l"]
moved = (cand["extreme"] - edge) * side
displaced = moved > 0 and moved >= p.disp * cand["atr"]
# The structure the move breaks: the most recent swing high (low) before the block,
# if no candle closed beyond it before the move.
swings = self.highs if side > 0 else self.lows
level = None
for s in reversed(swings):
if s[0] < cand["n"]:
level = s
break
broke = (level is not None and (level[2] is None or level[2] > cand["n"])
and (cand["extreme"] - level[1]) * side > 0)
if (displaced and (broke or p.bos == 0) and (cand["gap"] or p.gap == 0)
and (cand["swept"] or p.sweep == 0)):
cand["done"] = True
self.new_block(ctx, side, cand)
def new_candidate(self, side, n, o, h, l, c):
"""A candle that went the other way: it becomes a block if the move after it qualifies."""
# Did the block take liquidity first? Its low below the most recent swing low before
# it (for a bearish block, its high above the most recent swing high).
swings = self.lows if side > 0 else self.highs
before = [s for s in swings if s[0] < n]
swept = bool(before) and ((l < before[-1][1]) if side > 0 else (h > before[-1][1]))
return {"n": n, "o": o, "h": h, "l": l, "c": c, "atr": self.atr, "extreme": None,
"gap": False, "swept": swept, "done": False}
def new_block(self, ctx, side, cand):
"""A confirmed block: the order's entry and stop-loss."""
p = ctx.params
pip = ctx.pip_size
if side > 0:
entry = (cand["h"], (cand["h"] + cand["l"]) / 2, cand["o"])[p.entry]
stop = cand["l"] - pip
else:
entry = (cand["l"], (cand["h"] + cand["l"]) / 2, cand["o"])[p.entry]
stop = cand["h"] + pip
if (ctx.close[0] - entry) * side <= 0:
return # price is already back at the entry: no first return left to trade
self.blocks.append({"side": side, "entry": entry, "stop": stop, "formed": self.n,
"time": ctx.bar_time, "block_n": cand["n"], "high": cand["h"],
"low": cand["l"], "open": cand["o"], "atr": cand["atr"],
"gap": cand["gap"], "swept": cand["swept"]})
Your turn
Test the order block strategy yourself
Change the settings, the market or the stop-loss and see the result in seconds. Ask the BacktestingMax AI: Backtest order blocks on USD/JPY, 4-hour chart: buy limit at the high of the last down candle before a move that closes 1.5 ATR above it and above the last swing high within 3 candles; mirror for sells; stop 1 pip beyond the block; take-profit at twice the stop distance
.
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 2 November 2026.