MoTradeSystems — Clarity, not certainty.

Trading the opening-range breakout

The rule

The market's first half hour sets a high and a low. When price closes beyond one of them, the reasoning goes, the day has picked a direction and you go with it. It is the most traded intraday pattern there is, and it has an honest story behind it: the opening range is where the overnight disagreement gets settled.

NQ intraday chart, June 9, 2026: opening range with breakout trigger, stop and 1R target marked
NQ, June 9, 2026 — the most recent complete session in our dataset, not a selected one. Trigger, stop and 1R target drawn as the rule defines them.

The verdict

No measurable edge — and we did not stop at one test. Five separate versions of this idea, each with the filter someone swears by: volatility regime, order flow, the two of them stacked with a clear-path condition, a trailing runner on high-gamma days, a volume spike with an ADX trend filter. Sixty-three pre-registered parameter combinations. Not one passed.

Hypothetical backtest results. Read the full disclaimer at the bottom of this page.

What we actually tested

We wrote each configuration down, committed it, and only then ran it. That order matters: if you fix the rules after seeing the results, you are no longer testing an idea, you are describing one. Here it matters twice, because five tests give you five chances to fool yourself.

The base setup, identical in all five: the opening range is 09:30–10:00 ET. Entry is the first close beyond the range high or low, long and short, filled on the next bar. The stop is one opening-range width. Flat at the end of the day. Costs — one point round turn plus one tick of adverse slippage — are charged on every fill.

The five variants:

  1. Volatility regime. Only take the break when the day is expansive: yesterday's ATR above its 14-day average, or VIX above 18, or both. Four reward-to-risk targets each.
  2. Order flow. Only take the break when cumulative bar delta makes a new extreme at the same moment — the "confirmed breakout". Plus the mirror version: fade the break when confirmation is missing.
  3. All of it at once. Regime and a clear path to target (no prior-day point of control in the way) and order-flow confirmation. This is the version most traders actually believe in — the one where the edge is supposed to come from the combination.
  4. Let the winner run. On days when the dealer-gamma proxy says moves extend: take half off at +2R and trail the rest, instead of a fixed target. Three trailing methods, three caps.
  5. Volume and trend. Break of the session high or low, but only with volume above twice its 20-bar average and ADX above 25.

What ties them together: every one of the 63 cells was written down before the run, and every one is reported — including the ten that came out positive. The instrumented runs we exported these numbers from reproduce the original engines trade for trade, maximum deviation zero, in all five families.

What the numbers say
Bar chart of sixteen pre-registered opening-range filter cells; five positive on average, none passed
Sixteen cells, five of them positive, none passed.

Hypothetical backtest results. Read the full disclaimer at the bottom of this page.

Ten of the 63 cells made money on average. None of them passed.

That sounds like a contradiction and it is the most useful thing on this page. A cell passes only if it also beats its own control — the same days, the same costs, entries placed at random. The volatility family's headline cell — VIX above 18, a 1.5R target, 959 trades and +0.0135 R — landed at the 63rd percentile of that control distribution. We require the 95th. So the filter did something real: it picked days that moved. It just did not pick entries that were better than chance on those days. The volatility filter is exposure selection, not a trigger edge — it changes when you are in the market, not whether your entry is worth anything.

Three findings we did not expect and are not going to bury:

The confirmation hurt. Waiting for order flow to confirm the break did not improve anything — it made it worse. At a 2R target the confirmed breakouts averaged −0.0975 R against −0.0587 R for taking every break. Roughly four hundredths of an R worse, per trade, for being patient. The confirmation arrives when the move is already paid for.

Stacking made it look better and hold worse. The version with everything switched on — regime and clear path and confirmation — produced the second-best average in the whole study, +0.0119 R. It also produced 345 trades where taking every break in the same family produced 2,288, and it sat at the 18th percentile of its null distribution and the 10th of the random-entry control. That is what stacking does: each filter removes trades, the survivors look handpicked because they were, and the result does not survive contact with a control. We tested the thing everyone means by "confluence", and it is the weakest result we have.

Bar chart of eleven runner and trailing cells; none positive, all below the plain 2R baseline
Eleven cells, none positive — all nine runner variants below the plain 2R baseline.

The runner never showed up. The "let your winners run" version takes half off at +2R and trails the rest, which costs a third fill on every trade. Of 1,572 breakouts on those days, 168 — under 11 % — ever reached the +2R scale-out at all, and 55 ran far enough to hit the 3R cap. The remaining 1,404 paid for a runner they never got. All nine runner cells came out below the plain 2R baseline. The fat tail is real; it is just rarer than the cost of fishing for it.

And the one from the volume-and-ADX version, which we put in words rather than in a picture because it needs its window named: on IS 2015–21, a random entry on the same volume-and-ADX days averaged +0.30 R, while the filtered breakout averaged −0.02 R. The filter found the days. The trigger then gave the day back.

This is what a single chart can never show you. One session shows the mechanics. Sixty-three versions across nine years show the outcome.

What this means for your account

Here is the thing worth taking away: the trigger was never the interesting part.

Look at what actually carried information in all five tests. Not the entry — the day. Whether volatility was expanding. Whether the path to your target was clear. Whether the session had any range to give in the first place. Every filter that helped was a statement about the environment, and every attempt to turn that statement into an entry signal failed.

That is a useful split, because the environment is knowable before you trade and the entry is not. Our Regime Lab reads it off the market and shows the distribution of realised daily ranges in the current regime, with the sample size next to it — so you can see how thin the evidence is when it is thin. It is free, it is published on TradingView with the same measurement we use ourselves, and it deliberately does not tell you to enter anything.

Open Regime Lab on TradingView
All 63 cells

Hypothetical backtest results. Read the full disclaimer at the bottom of this page.

N=39Volatility regime

Reference window: Test window: in-sample + validation, 2015-2023

Frozen configuration (original, German): OR 09:30-10:00 ET; Entry erster Close jenseits OR-H/L (next bar), long+short; Stop 1,0x OR-Range; RRR-Sweep {1; 1,5; 2; 3}R; EOD-flat; Filter {all, atr_exp, vix_gt18, both}; Kosten 1,0 Pkt Roundturn + 1 Tick adverse; SL zuerst, TP erst bei >=1 Tick Durchgang

In English: Opening range 09:30-10:00 ET. Entry on the first close beyond the range high or low, filled on the next bar, long and short. Stop 1.0x the opening-range width. Reward-to-risk sweep over {1; 1.5; 2; 3}R. Flat at the end of the day. Filters {all, atr_exp, vix_gt18, both}. Costs 1.0 point round turn plus 1 tick of adverse slippage. On the same bar the stop is checked first; the target only fills on a move of at least 1 tick beyond it.

Constant in this family: OR window 09:30-10:00 ET · stop 1.0x OR-Range

CellSetupTradesAvg per tradeShare of winning tradesProfit factorVerdict
all_r10filter all · RRR 12294-0.0441 R48.6 %0.90REJECT
all_r15filter all · RRR 1.52294-0.0260 R44.8 %0.94REJECT
all_r20filter all · RRR 22294-0.0286 R43.4 %0.94REJECT
all_r30filter all · RRR 32294-0.0257 R42.7 %0.95REJECT
atr_exp_r10filter atr_exp · RRR 11033-0.0523 R47.8 %0.88REJECT
atr_exp_r15filter atr_exp · RRR 1.51033-0.0486 R43.3 %0.90REJECT
atr_exp_r20filter atr_exp · RRR 21033-0.0512 R42.0 %0.89REJECT
atr_exp_r30filter atr_exp · RRR 31033-0.0490 R41.2 %0.90REJECT
vix_gt18_r10filter vix_gt18 · RRR 1959-0.0009 R51.7 %1.00REJECT
vix_gt18_r15filter vix_gt18 · RRR 1.5959+0.0135 R47.2 %1.03REJECT
vix_gt18_r20filter vix_gt18 · RRR 2959+0.0125 R45.7 %1.03REJECT
vix_gt18_r30filter vix_gt18 · RRR 3959+0.0136 R44.7 %1.03REJECT
both_r10filter both · RRR 1494+0.0160 R51.8 %1.04REJECT
both_r15filter both · RRR 1.5494+0.0017 R46.0 %1.00REJECT
both_r20filter both · RRR 2494-0.0034 R44.7 %0.99REJECT
both_r30filter both · RRR 3494-0.0044 R43.7 %0.99REJECT

N=41Order flow

Reference window: Test window: in-sample + validation, 2015-2023

Frozen configuration (original, German): OR 09:30-10:00 ET; Entry erster Close-Break; Stop 1,0x OR-Range; RRR-Sweep {1; 1,5; 2; 3}R; Bar-Delta-Proxy v*(2*(c-l)/(h-l)-1), kumuliert ab 09:30; CONFIRM = kum. Delta macht am Break ein neues Hoch (long) bzw. Tief (short), sonst DIVERGENZ; Modi {all, confirm, diverg_fade (Gegenrichtung)}; EOD-flat; Kosten 1,0 Pkt Roundturn + 1 Tick adverse

In English: Opening range 09:30-10:00 ET. Entry on the first close-break. Stop 1.0x the opening-range width. Reward-to-risk sweep over {1; 1.5; 2; 3}R. Bar-delta proxy v*(2*(c-l)/(h-l)-1), accumulated from 09:30. CONFIRM = the cumulative delta makes a new high (long) or a new low (short) at the break, otherwise DIVERGENCE. Modes {all, confirm, diverg_fade (opposite direction)}. Flat at the end of the day. Costs 1.0 point round turn plus 1 tick adverse.

Constant in this family: OR window 09:30-10:00 ET · stop 1.0x OR-Range · delta Bar-Delta-Proxy (kum. ab 09:30)

CellSetupTradesAvg per tradeShare of winning tradesProfit factorVerdict
all_r10mode all · RRR 12294-0.0441 R48.6 %0.90REJECT
all_r15mode all · RRR 1.52294-0.0260 R44.8 %0.94REJECT
all_r20mode all · RRR 22294-0.0286 R43.4 %0.94REJECT
all_r30mode all · RRR 32294-0.0257 R42.7 %0.95REJECT
confirm_r10mode confirm · RRR 11010-0.0553 R48.6 %0.88REJECT
confirm_r15mode confirm · RRR 1.51010-0.0344 R45.0 %0.93REJECT
confirm_r20mode confirm · RRR 21010-0.0398 R43.8 %0.92REJECT
confirm_r30mode confirm · RRR 31010-0.0332 R43.4 %0.93REJECT
diverg_fade_r10mode diverg_fade · RRR 11284-0.0591 R48.1 %0.86REJECT
diverg_fade_r15mode diverg_fade · RRR 1.51284-0.0262 R44.9 %0.94REJECT
diverg_fade_r20mode diverg_fade · RRR 21284-0.0248 R43.4 %0.95REJECT
diverg_fade_r30mode diverg_fade · RRR 31284-0.0133 R42.9 %0.97REJECT

N=43All of it at once

Reference window: Test window: in-sample + validation, 2015-2023

Frozen configuration (original, German): OR 09:30-10:00 ET; Entry erster Close-Break; Stop 1,0x OR-Range; RRR-Sweep {1; 1,5; 2; 3}R; Masken {user_matrix = Regime UND frei UND confirm; learned(vix&free) = Regime UND frei; free&confirm; all_break = ungefiltert}; Regime = VIX-Vortagsclose > 18; frei = kein gestriger POC zwischen Entry und Ziel; confirm = kum. Bar-Delta-Proxy macht am Break ein neues Extrem; EOD-flat; Kosten 1,0 Pkt Roundturn + 1 Tick adverse

In English: Opening range 09:30-10:00 ET. Entry on the first close-break. Stop 1.0x the opening-range width. Reward-to-risk sweep over {1; 1.5; 2; 3}R. Masks {user_matrix = regime AND clear path AND confirm; learned(vix&free) = regime AND clear path; free&confirm; all_break = unfiltered}. Regime = prior day's VIX close above 18. Clear path = no prior-day point of control between entry and target. Confirm = the cumulative bar-delta proxy makes a new extreme at the break. Flat at the end of the day. Costs 1.0 point round turn plus 1 tick adverse.

Constant in this family: OR window 09:30-10:00 ET · stop 1.0x OR-Range · bedingungen ORB-Break + VIX>18 + freier Weg (kein POC) + CVD-Proxy-Confirm, je nach Maske

CellSetupTradesAvg per tradeShare of winning tradesProfit factorVerdict
user_matrix_r10mask user_matrix · RRR 1362+0.0097 R53.0 %1.02REJECT
user_matrix_r15mask user_matrix · RRR 1.5345+0.0119 R48.4 %1.03REJECT
user_matrix_r20mask user_matrix · RRR 2334+0.0044 R47.6 %1.01REJECT
user_matrix_r30mask user_matrix · RRR 3324-0.0035 R47.5 %0.99REJECT
learned_vix_free_r10mask learned(vix&free) · RRR 1785-0.0213 R50.7 %0.95REJECT
learned_vix_free_r15mask learned(vix&free) · RRR 1.5731-0.0102 R46.4 %0.98REJECT
learned_vix_free_r20mask learned(vix&free) · RRR 2703-0.0053 R45.7 %0.99REJECT
learned_vix_free_r30mask learned(vix&free) · RRR 3674+0.0004 R45.5 %1.00REJECT
free_confirm_r10mask free&confirm · RRR 1814-0.0502 R48.8 %0.88REJECT
free_confirm_r15mask free&confirm · RRR 1.5768-0.0161 R45.4 %0.96REJECT
free_confirm_r20mask free&confirm · RRR 2738-0.0202 R44.3 %0.96REJECT
free_confirm_r30mask free&confirm · RRR 3720-0.0153 R44.4 %0.97REJECT
all_break_r10mask all_break · RRR 12288-0.0456 R48.5 %0.89REJECT
all_break_r15mask all_break · RRR 1.52288-0.0282 R44.7 %0.94REJECT
all_break_r20mask all_break · RRR 22288-0.0309 R43.3 %0.93REJECT
all_break_r30mask all_break · RRR 32288-0.0278 R42.6 %0.94REJECT

N=44Let the winner run

Reference window: Test window: in-sample + validation, 2015-2023

Frozen configuration (original, German): Nur Neg-Gamma-Proxy-Tage (ATR_prev > ATR_SMA_prev ODER VIX_prev > 18 UND steigend); 5-min-Bars; OR 09:30-10:00 ET; Entry erster 5-min-Close jenseits OR-H/L nach 10:00; Stop 1,0x OR-Range; Baseline festes Ziel {2R; 3R}; Runner-Sweep Cap {3R; 5R; offen} x Trailing {EMA21; Chandelier 3xATR; 3-Bar}; Scale-Out 50 % bei +2R; EOD-flat; Kosten Baseline 1,0 Pkt Roundturn, Runner ~3 Fills (1,5 x Roundturn)

In English: Negative-gamma-proxy days only (ATR_prev > ATR_SMA_prev, OR VIX_prev > 18 and rising). 5-minute bars. Opening range 09:30-10:00 ET. Entry on the first 5-minute close beyond the range high or low after 10:00. Stop 1.0x the opening-range width. Baseline with a fixed target {2R; 3R}. Runner sweep: cap {3R; 5R; open} x trailing {EMA21; chandelier 3xATR; 3-bar}. 50 % scale-out at +2R. Flat at the end of the day. Costs: baseline 1.0 point round turn; the runner takes about three fills (1.5x round turn).

Constant in this family: tage nur Neg-Gamma-Proxy-Tage (Vol-Expansion ODER VIX>18 steigend) · OR window 09:30-10:00 ET auf 5-min-Bars · stop 1.0x OR-Range

CellSetupTradesAvg per tradeShare of winning tradesProfit factorVerdict
fix_2rengine simulate (eine Position, festes Ziel) · runner cap — · cap/target 2R · trailing —1238-0.0314 R44.2 %0.93REJECT
fix_3rengine simulate (eine Position, festes Ziel) · runner cap — · cap/target 3R · trailing —1238-0.0331 R43.4 %0.93REJECT
cap3r_ema21engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap 3R · cap/target 3R · trailing ema211238-0.0417 R43.9 %0.91REJECT
cap3r_chand3engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap 3R · cap/target 3R · trailing chand31238-0.0442 R43.9 %0.91REJECT
cap3r_bar3engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap 3R · cap/target 3R · trailing bar31238-0.0446 R43.9 %0.91REJECT
cap5r_ema21engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap 5R · cap/target 5R · trailing ema211238-0.0418 R43.9 %0.91REJECT
cap5r_chand3engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap 5R · cap/target 5R · trailing chand31238-0.0440 R43.9 %0.91REJECT
cap5r_bar3engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap 5R · cap/target 5R · trailing bar31238-0.0461 R43.9 %0.90REJECT
open_ema21engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap open · cap/target open · trailing ema211238-0.0444 R43.9 %0.91REJECT
open_chand3engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap open · cap/target open · trailing chand31238-0.0455 R43.9 %0.90REJECT
open_bar3engine simulate_runner (Scale-Out 50 % @ +2R, Runner trailt) · runner cap open · cap/target open · trailing bar31238-0.0475 R43.9 %0.90REJECT

N=47Volume and trend

Reference window: Test window: in-sample + validation, 2015-2023

Frozen configuration (original, German): NQ 5-min RTH; Signal = erster 5-min-Close ueber dem bisherigen Session-Hoch (long) bzw. unter dem Session-Tief (short), nur ab Bar 20 und nur wenn Volumen > 2 x SMA20(Volumen) UND ADX(14) > 25; Entry auf der Eroeffnung der FOLGEBAR + 1 Tick adverse; Stop-Sweep {Bar-Extrem des Signalbars; 1 x ATR(14)}; Ziel-Sweep {3R; 4R; 5R; EOD}; EOD-flat; Kosten 1,0 Pkt (run_n47.COST)

In English: NQ 5-minute bars, regular trading hours. Signal = the first 5-minute close above the session high so far (long) or below the session low so far (short), only from bar 20 on and only when volume > 2 x SMA20(volume) AND ADX(14) > 25. Entry at the open of the NEXT bar plus 1 tick adverse. Stop sweep {bar extreme of the signal bar; 1 x ATR(14)}. Target sweep {3R; 4R; 5R; EOD}. Flat at the end of the day. Costs 1.0 point (run_n47.COST).

Constant in this family: signal erster 5-min-Close ueber Session-Hoch / unter Session-Tief · filter Volumen > 2 x SMA20(Volumen) UND ADX(14) > 25 · entry Eroeffnung der FOLGEBAR + 1 Tick adverse

CellSetupTradesAvg per tradeShare of winning tradesProfit factorVerdict
bar_tp30stop mode bar · target R 3.0 · stop Bar-Extrem des Signalbars464-0.1023 R35.3 %0.85REJECT
bar_tp40stop mode bar · target R 4.0 · stop Bar-Extrem des Signalbars464-0.1004 R34.1 %0.85REJECT
bar_tp50stop mode bar · target R 5.0 · stop Bar-Extrem des Signalbars464-0.0933 R33.6 %0.87REJECT
bar_tpeodstop mode bar · target R EOD · stop Bar-Extrem des Signalbars464-0.0949 R33.2 %0.86REJECT
atr_tp30stop mode atr · target R 3.0 · stop 1 x ATR(14) auf 5-min464-0.0427 R33.0 %0.94REJECT
atr_tp40stop mode atr · target R 4.0 · stop 1 x ATR(14) auf 5-min464-0.0129 R30.4 %0.98REJECT
atr_tp50stop mode atr · target R 5.0 · stop 1 x ATR(14) auf 5-min464-0.0378 R28.9 %0.95REJECT
atr_tpeodstop mode atr · target R EOD · stop 1 x ATR(14) auf 5-min464+0.0102 R28.2 %1.01REJECT

Everything above can be checked right here, cell by cell — no signup. If you want to run the numbers yourself, the trade-by-trade logs of all three studies and their frozen configurations are available as a data bundle on the Free Tools page.

These results are based on simulated or hypothetical performance results that have certain inherent limitations. Unlike the results shown in an actual performance record, these results do not represent actual trading. Also, because these trades have not actually been executed, these results may have under- or over-compensated for the impact, if any, of certain market factors, such as lack of liquidity. Simulated or hypothetical trading programs in general are also subject to the fact that they are designed with the benefit of hindsight. No representation is being made that any account will or is likely to achieve profits or losses similar to these being shown.

Trading futures and other leveraged products involves substantial risk of loss and is not suitable for all investors. Past performance is not indicative of future results. This content is for educational purposes only and is not investment advice.

Which rule did your account cross?

Account Autopsy, 49 USD