Markets › Futures · ES futures, 1-minute
Gap Fill Strategy Backtest: Do ES Opening Gaps Fill? 6 Years of S&P 500 Futures
“Gaps always fill” is one of the oldest sayings in trading. We measured how often S&P 500 futures opening gaps really fill, by size, and then traded the fade on every session since 2020, with costs and against random days.
Buried · CostsThree small gaps in four filled. The trade still lost.
Variants tried: 3 · Passed every gate: 0 · Small gaps filled the same day: 73.8% · Holdout opened: yes (already used)
Short answer: small gaps usually fill, but trading the fill did not pay. On ES from 2020 to 2026, 74% of opening gaps of 0.10% to 0.25% filled the same day, falling to 19% for gaps of 1% or more; fading every gap at the open lost -$14 a trade after costs with a one-gap stop.How much costs took here, compared across all 54 of our tests →
00The verdict in three lines
- Do gaps fill? Small ones mostly do: on ES from 2020 to 2026, 73.8% of opening gaps of 0.10% to 0.25% traded back to the previous close the same day, 52.3% of gaps of 0.25% to 0.50%, 32.8% of gaps of 0.5% to 1%, and 19.1% of gaps of 1% or more.
- Does the gap fill strategy pay? Not after costs. Fading the gap at the open with the previous close as the target lost -$14 a trade with a one-gap stop, -$21 with no stop (61.7% winners) and -$22 on small gaps only, over 907 to 1,391 trades.
- Buried, cause Costs, for all three. The fill rate is real; the profit is not.
01What is a gap fill?
An opening gap is the jump between the previous session's close and today's open. For S&P 500 futures (ES) we use the regular session: yesterday's 16:00 New York close and today's 09:30 open; the overnight trading in between is what creates the gap. The gap fills when the price trades back to yesterday's close.
The gap fill strategy bets on that: sell a gap up and buy a gap down at the open, with yesterday's close as the target. Traders also say small gaps fill more often than large ones, which often run on in the direction of the gap. Both claims can be measured.
02How often do ES gaps fill? The statistics
| Gap size (share of the previous close) | Gaps up | Filled | Gaps down | Filled | Median time to fill (up / down) |
|---|---|---|---|---|---|
| 0.10% to 0.25% | 249 | 72.7% | 193 | 75.1% | 22 / 26 min |
| 0.25% to 0.50% | 277 | 50.2% | 188 | 55.3% | 47 / 49 min |
| 0.50% to 1.00% | 184 | 33.2% | 148 | 32.4% | 143 / 147 min |
| 1.00% or more | 68 | 19.1% | 84 | 19.0% | 143 / 209 min |
Filled means the previous close traded at any time from the 09:30 open to the session close. Gaps smaller than 0.10% (345 of 1,736 sessions, about one in five) were left out: they are too small to trade against a round-trip cost. The gap fill percentage falls steadily with size, and gaps up and gaps down behave much the same. Small gaps that fill usually do so in the first half hour.
03The gap fill strategies we tested
- Entry: at the 09:30 open (the first 1-minute bar), sell a gap up, buy a gap down, if the gap is at least 0.10% of the previous close.
- Target: the previous close, the gap filled.
- GF-1X: every gap of 0.10% or more, stop one gap beyond the entry (as far from the entry as the target).
- GF-SMALL: only gaps of 0.10% to 0.50%, the ones said to fill most often; stop one gap away.
- GF-NS: every gap of 0.10% or more, no stop.
- All three: a trade still open at the session close (16:00, or the exchange's early close) is closed there. One contract, $30.76 a round trip.
We fixed these versions on 22 October 2026, before computing a single gap. A related test, the Bitcoin CME gap fill, was buried too.
04How we tested it
ES (E-mini S&P 500 futures), NinjaTrader 1-minute history, back-adjusted, January 2020 to 25 September 2026: 1,737 trading days, with exchange early closes from our futures calendar. Costs: $30.76 a round trip per contract (commission plus one tick of slippage on each fill), as in all our ES tests. Periods: 2020 to 2023, 2024 to March 2025, and a holdout from April 2025 already used by earlier ES tests. First-period bar t ≥ 2.0. Control: every trade moved to another day, entered at that day's 09:30 open with the same direction and the same target and stop distances, 500 times. Engine check: gaps up and down, the previous close after an early close, the size bounds, the target, the stop, a minute reaching both, the session-close exit, missing bars, and an independent re-implementation that matched every one of the 3,689 trades (gf_selftest_result.txt).
05Results: does the gap fill strategy work?
| Variant | Rule | Trades | Win rate (95% range) | Gross per trade | Net per trade | Net total, 1 contract | Profit factor | Verdict |
|---|---|---|---|---|---|---|---|---|
| GF-1X | Every gap of 0.10% or more; stop one gap away (risk = reward) | 1,391 | 50.0% (47% to 53%) | +$17 | -$14 | -$19,787 | 0.97 | Buried |
| GF-SMALL | Only gaps of 0.10% to 0.50%; stop one gap away | 907 | 51.3% (48% to 55%) | +$8 | -$22 | -$20,274 | 0.94 | Buried |
| GF-NS | Every gap of 0.10% or more; no stop | 1,391 | 61.7% (59% to 64%) | +$9 | -$21 | -$29,887 | 0.96 | Buried |
Cumulative net dollars per contract by month. * Holdout already used before this test.
How the trades ended
| Variant | Gap filled (target) | Stopped | Closed at the session close | Median gap | Median minutes held | Largest drawdown (closed trades) |
|---|---|---|---|---|---|---|
| GF-1X | 40.4% | 36.7% | 22.9% | 19.50 pts (+$975) | 74 | -$58,229 |
| GF-SMALL | 47.7% | 42.9% | 9.4% | 13.75 pts (+$688) | 31 | -$31,388 |
| GF-NS | 50.8% | – | 49.2% | 19.50 pts (+$975) | 318 | -$69,627 |
By gap size (net per trade)
| Gap size | GF-1X (trades) | GF-NS (trades) |
|---|---|---|
| 0.10% to 0.25% | +$22 (442) | +$7 (442) |
| 0.25% to 0.50% | -$65 (465) | -$33 (465) |
| 0.50% to 1.00% | -$43 (332) | -$111 (332) |
| 1.00% or more | +$96 (152) | +$127 (152) |
The trades were close to a coin flip with equal stakes: with the one-gap stop, 40.4% reached the target and 36.7% the stop, and the cost tipped the balance. Without a stop, 61.7% of trades won, but the gaps that kept running were held to the close and cost more than the fills earned.
06Gap fade or random day?
| Variant | Trades | Real net per trade | Random days, median | Random, 5th to 95th | Percentile (95 needed) |
|---|---|---|---|---|---|
| GF-1X | 1,391 | -$14 | -$34 | -$79 to +$14 | 72.8 |
| GF-SMALL | 907 | -$22 | -$33 | -$71 to +$6 | 68.2 |
| GF-NS | 1,391 | -$21 | -$46 | -$107 to +$13 | 77.2 |
The control takes each trade, with its direction and distances, to another day's open. The real fades did somewhat better than the median random day, and none reached the 95th percentile.
07By period and by year
| Variant | 2020 to 2023 (trades) | 2024 to Mar 2025 (trades) | Holdout* Apr 2025 to Sep 2026 (trades) | t, first period | PF, second period |
|---|---|---|---|---|---|
| GF-1X | -$48,908 (852) | +$9,408 (233) | +$19,712 (306) | -1.38 | 1.09 |
| GF-SMALL | -$7,534 (542) | +$4,207 (168) | -$16,947 (197) | -0.49 | 1.07 |
| GF-NS | -$52,933 (852) | +$9,158 (233) | +$13,887 (306) | -1.24 | 1.07 |
| Year | GF-1X net (trades) | GF-SMALL net (trades) | GF-NS net (trades) |
|---|---|---|---|
| 2020 | -$22,763 (228) | +$4,179 (123) | -$21,613 (228) |
| 2021 | -$14,770 (201) | +$3,821 (157) | -$22,445 (201) |
| 2022 | -$5,443 (218) | -$3,665 (109) | -$8,293 (218) |
| 2023 | -$5,931 (205) | -$11,869 (153) | -$581 (205) |
| 2024 | -$1,660 (184) | -$77 (137) | -$4,735 (184) |
| 2025 | +$23,346 (196) | -$2,158 (125) | +$30,359 (196) |
| 2026 (to 25 Sep) | +$7,434 (159) | -$10,506 (103) | -$2,578 (159) |
GF-1X lost money in every year from 2020 to 2024 and made money in 2025; one good year after five losing ones is not a pattern to trade.
08The gates
| Variant | Trades | 1. PF ≥ 1.2 in validation | 2. ≥ 50 trades in each period | 3. t ≥ 2.0 on development | 4. Above the 95th percentile of the moved-entry control | 5. Positive without the 10 best trades | 6. Holdout net positive (already used) |
|---|---|---|---|---|---|---|---|
| GF-1X | 1,391 | fail | pass | fail | fail | fail | pass |
| GF-SMALL | 907 | fail | pass | fail | fail | fail | fail |
| GF-NS | 1,391 | fail | pass | fail | fail | fail | pass |
| Variant | Cause | Gates failed | Verdict |
|---|---|---|---|
| GF-1X | Costs | 1, 3, 4, 5 | Buried |
| GF-SMALL | Costs | 1, 3, 4, 5, 6 | Buried |
| GF-NS | Costs | 1, 3, 4, 5 | Buried |
The data-gap check removed 8, 3 and 8 trades on sessions touching a known hole in the data; no verdict changed. Costs: positive before costs, negative after.
TWhat this shows, and what to take into your own tests
What the results show
- Small ES opening gaps do usually fill: 73.8% of gaps between 0.10% and 0.25% traded back to the previous close the same day, most within half an hour. Larger gaps filled far less often (19.1% of gaps of 1% or more).
- Fading every gap of 0.10% or more at the open, with the previous close as the target, still lost money after costs: -$14 a trade with a one-gap stop, -$21 with no stop, -$22 on the small gaps only.
- A high fill rate is not an edge. The target is the gap itself, a median of 13.75 points on the small gaps, so the winners are small, and the gaps that do not fill cost at least as much.
What remains unknown
- Other entries: waiting for the first few minutes, fading only after a failed push, or scaling out before the full fill. We tested the plain fade at the open.
- Other markets and periods. This is ES from 2020, a period with large gaps around 2020 and 2022; the cash index and older data may differ.
- Partial fills. A trader who takes half the gap as the target changes the arithmetic; that is a different rule.
Why it was buried
Before costs the fade earned +$17 a trade on average (0.026 R in units of the gap); one contract's $30.76 round trip turned that into -$14. The small-gap version, which fills most often, paid the same cost on smaller targets and lost the most in the holdout (-$16,947). None of the versions beat the same trades placed on random days at the 95% level.
What you can apply to your own tests
- Separate "how often does it happen" from "does trading it pay". A 75% fill rate with a target the size of the gap can still lose.
- Put the cost next to the target. A $30.76 round trip is about 0.6 of an ES point; on a 5-point gap it is an eighth of the whole target.
- Check the misses: the gaps that do not fill are the trades that decide the result.
A note on the numbers: drawdown figures are measured on closed trades unless a table says it includes open losses. Open losses inside a trade are not counted in a closed-trade drawdown, so real account risk is higher, especially for systems with no stop. Backtests are not live trading.
FAQCommon questions
Do gaps always fill?
No. On ES opening gaps from 2020 to 2026, the same-day fill rate was 74% for gaps of 0.10% to 0.25%, 52% for 0.25% to 0.50%, 33% for 0.5% to 1% and 19% for gaps of 1% or more.
How often do ES gaps fill?
Small ones most of the time, and quickly: gaps of 0.10% to 0.25% filled 74% of the time, with a median of about 25 minutes after the open. Large gaps filled far less often and later in the day.
Is the gap fill strategy profitable?
Not in our ES test: fading the gap at the open with the previous close as the target lost -$14 a trade with a one-gap stop, -$21 with no stop and -$22 on small gaps only, after $30.76 a round trip per contract.
Why does a high fill rate not make money?
Because the target is the gap itself, a few points, and the gaps that do not fill cost at least as much as the fills earn; one contract's round-trip cost is about 0.6 of a point, a large share of a small gap.
How was the strategy tested?
On ES futures 1-minute data from 2020 to 2026, entering at the 09:30 open against every gap of 0.10% or more, one contract, with rules written and dated before the data was run, costs included on every trade, results split into development, validation and holdout periods, a random-entry control as the benchmark, and every variant reported. Read the protocol.
09Check our arithmetic
gf_spec.md
gf_lib.js · gf_ref.js · gf_selftest.js · gf_run.js
control_audit_lib.js · em_lib.js · gh_lib.js · hourly_lib.js · ma_lib.js · rb_lib.js · rsi2_protocol.js
gf_selftest_result.txt · gf_results.txt · gf_summary.json
Code provenance: our own code, written from the specification.
10Data notes
Source. NinjaTrader ES 1-minute history, back-adjusted continuous contract, on the New York clock. Back-adjustment shifts both prices of a gap equally within a contract, so gap sizes in points are unchanged; gaps across a roll are measured on the adjusted series, as in all our ES tests. Fills: the open of the 09:30 minute; target and stop at their level, or a minute's open if it gapped through; one tick of slippage per fill is in the cost.
11Corrections
22 Oct 2026, navigation: added a link to the new guide comparing trading costs across all our tests. No result changed. 22 Oct 2026, navigation: added a link to the new guide comparing trend following and mean reversion across all our tests. No result changed. 22 Oct 2026, navigation: added a link to the new guide comparing versions with and without a stop loss across our tests. No result changed.
+More tests and guides
- Bitcoin cme gap
- Initial balance breakout es
- Vwap strategy backtest
- Noise area breakout es
- Did the stop loss help? This test next to the other with-and-without pairs
- Trend following vs mean reversion: this test next to the others of its style
- Free prop firm challenge calculator
- What all the backtests found so far
- The backtesting protocol
- How to backtest a trading strategy without fooling yourself
- Backtesting glossary