Killed at G10 · Audit

Opening Volatility Stretch on DAX, Bund and Nasdaq

The DAX and Bund results came from a frozen pre-open quote. Nasdaq is positive but unproven.

Markets
DAX 40, Bund, Nasdaq-100
Timeframe
1-minute bars, session open to close
Period
2005-01 to 2026-10
Tested
17 October 2026
DAX, as first reported
+0.293R / trade
t 5.86 on 2,496 trades
DAX, physical fills + real spread
+0.019R / trade
t 0.38
Bund, physical fills + real spread
−0.256R / trade
t −4.31

Why it failed: DAX and Bund: the 'open' bar was a stale quote one minute before the market opened. Nasdaq: not proven on unseen years. See the scorecard

The claim

Toby Crabel's opening stretch: place a buy stop a fixed distance above the session open and a sell stop the same distance below it, where the distance is the recent average excursion from the open. Hold the trade to the close.

First backtests: DAX 2,496 trades, +0.293R, t 5.86, 12 of 12 years; Bund +0.287R, t 4.63; Nasdaq 2,388 trades, +0.151R, t 3.57.

Source: Toby Crabel, Day Trading with Short Term Price Patterns and Opening Range Breakout (1990); first backtested by two of our research agents

What we tested

  • Stretch: the average over the previous 10 days of the smaller move away from the day's open (open to high, or open to low). 1R = the stretch.
  • Buy stop at the open + stretch, sell stop at the open - stretch; the first one triggered is taken, and a minute bar that touches both is skipped.
  • Entries only early in the session (DAX until 10:00 Berlin, Nasdaq until 11:00 New York); the stop is the session open price.
  • Exit at the close (DAX 17:30 Berlin, Nasdaq 15:55 New York).
  • Sessions as the first backtests defined them: DAX from the bar stamped 08:00, Bund from the bar stamped 07:00, Nasdaq from 09:30 New York.

Costs and fills

  • The first backtests charged a flat 0.030R per trade. The audit uses each file's own bid/ask, which costs 0.064R a trade on DAX and 0.22R on the Bund CFD.

Data

  • DE40 and Bund CFD minute bid/ask
  • US100 CFD minute bid/ask, true clock
  • LSE NQ futures minute bars 2016-2026

DAX: the money came from one stale minute

The DAX file is stamped in Berlin local time at the end of each minute. The first script read it as UTC, so its '08:00 open' was the minute 07:59 to 08:00 Berlin: the last minute before Frankfurt opened, until extended hours reached this feed in 2018-2019. In 2015 to 2018, 24% to 58% of those minutes are flat: almost nobody was trading.

When the market opened, the price jumped straight over the trigger, and the simulator filled at the trigger anyway. Those 369 gap entries earn +521.9R of the +806.9R gross. Fill at the real open price, check the stop on the entry bar and charge the file's own spread, and the edge is +0.019R a trade, t 0.38. At the real Frankfurt opens on the correct clock it is −0.013R (futures open) and +0.032R (cash open).

Bund: the same mechanism, worse

The Bund test used the 06:59 Berlin minute, an hour before Eurex opened; 84% to 96% of those minutes were flat in 2015-2018. Gap entries carried +573.5R of +640.9R gross. With physical fills the gross edge is −0.036R, and the 0.22R spread takes it to −0.256R a trade, t −4.31, 1 of 12 years positive.

Nasdaq: real clock, unresolved minute, not enough evidence

The Nasdaq test used the correct clock. Its one optimistic assumption was never checking the stop in the entry minute: when one minute bar touches both the trigger and the stop, the first test booked a winner. Minute data cannot say which came first, so the truth lies between two bounds.

On 21 years of an independent data vendor: +0.058R (t 2.03) to +0.113R (t 3.86) a trade. On the 11 years the first test never saw (2005 to mid-2016): +0.038R (t 0.98) to +0.059R (t 1.50), 7 of 12 years positive. That is not enough to trade, and at roughly +0.09R per trade it would take about ten years of trades to tell.

The rest of the batch tested the wrong hour

The same batch also ran the stretch on the S&P 500, the Dow, the US 10-year note, gold, the Euro Stoxx 50, the Nikkei and the Russell 2000. Each file is stamped in its exchange's local time and was read as UTC, so the 'open' was the wrong hour: the S&P 500 'open' was a bar in the New York afternoon, the Nikkei 'open' was the Tokyo afternoon. Those results say nothing either way, so we list them as void, not as killed.

The 12-gate scorecard

0 passed · 6 failed · 6 not run or not reached. A gate is "not reached" when the strategy had already failed a veto: there is nothing left for it to test.

Is the backtest real?

Absolute veto. These gates look for bugs and physical limits, not for statistical evidence, so one failure ends the test.

  • DAX and Bund: local timestamps read as UTC, end-of-minute stamps not shifted; the anchor minute was a stale pre-open quote (DAX 24-58%, Bund 84-96% flat minutes in 2015-2018).

  • Stop entries filled at the trigger after a gap: gap entries carry 65% of DAX gross and 89% of Bund gross. Nasdaq: stop never checked on the entry minute (110 of 2,388 trades).

  • G7Engine parityNot reached

Is the edge more than luck?

G12, one pre-registered holdout, is the only statistical veto. G1 to G5 and the regime test G6 are always reported; G6 vetoes only a regime that is significantly negative. A strategy with no edge after costs never reaches G12, because there is nothing to confirm.

Can it survive a prop-firm account?

Absolute veto, for strategies meant for funded accounts. The account rules are simulated event by event, not at the end of the day.

Lesson

A minute where nobody trades will make you rich in a backtest

Check the share of flat bars at every anchor minute, year by year, and never fill a stop order at the trigger when the bar opened beyond it. Our simulator now refuses stale anchor minutes and fills gaps at the open; on a random walk with a stale pre-open quote the old loop shows t 10.5, the new one about zero.

Receipts

Every number on this page comes from one of these files: the test script, its saved output, the trade list and, where the test was pre-registered, the registration and its hash lock. Download them and check our work. Numbers that also appear in the chart are recomputed from the trade list when this page is built, and the build fails if they disagree.

FileKindSizeStatussha256
CRABEL_STRETCH_AUDIT_2026-10-17.md
reports/2026-10/CRABEL_STRETCH_AUDIT_2026-10-17.md
Report10 KB8 lines withheld (private strategy)3e6380e85d4a
_audit_crabel_stretch_20261017.py
experiments/_audit_crabel_stretch_20261017.py
Script27 KB8 lines withheld (private strategy)2365d7be1726
_audit_crabel_stretch_20261017.out
experiments/_audit_crabel_stretch_20261017.out
Saved output18 KB5 lines withheld (private strategy)da79ca164dc1
hdam_selftest.out
hdam/hdam_selftest.out
Saved output2 KBComplete59644303904d

Price data is not included: the vendors' licences do not allow it, so the scripts run only with your own copy of the data, and the trade lists show dates, direction, R and costs, not prices. Lines that refer to the lab's private live strategy are replaced by a marker; the receipts page explains the rules and lists the sha256 of every original file.

Related tests