Strategies we backtested 5-minute opening range breakout

Tested by BacktestingMax

5-minute opening range breakout backtest on NQ and ES futures

Does the 5-minute opening range breakout work on NQ and ES futures?

A little on NQ and not on ES, when you take profit at 2 times the distance to the stop-loss (2R). The 5-minute opening range breakout (ORB) marks the high and the low from 09:30 to 09:35 New York time. The strategy buys when a candle closes above that range, and sells when a candle closes below it. We ran 8 backtests from 2020 to 2025, after trading costs, risking 1% of a $50,000 account per trade. The markets were MNQ and MES (the micro versions of NQ and ES), YM (Dow) and RTY (Russell 2000), on 1-minute and 5-minute charts. The basic rules put the stop-loss at the other side of the range. With them, MNQ made +4.1% on the 1-minute chart and +31.4% on the 5-minute chart. MES lost 9.6% and 21.9%: its trading costs were bigger than what its trades made. Only YM and RTY on the 1-minute chart made money in both 2020–2023 and 2024–2025. Holding each trade until 16:00 New York time made +103.4% and +111.4% on MNQ, with a profit in both periods. But from 2020 to 2025, holding did worse on YM and RTY. On MES, it lost money in 2024–2025.

8 backtests 2020–2025 Trading costs included Tested 19 October 2026

Where it worked 8 backtests
Made money
5
of 8 tests, with the basic rules
Made money in both periods
2
2020–2023 and again 2024–2025
Best backtest
+31%
MNQ (Micro Nasdaq 100), 5-minute chart: account growth 2020–2025
Hold until 16:00, no take-profit
2
tests made money in both periods, compared with 2 with the basic rules

Made money in both periods

  • YM (Dow futures), 1-minute
  • RTY (Russell 2000 futures), 1-minute

The results

Results on every market

Each box shows one backtest of the 5-minute opening range breakout with the basic 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 1-minute 5-minute
MNQ (Micro Nasdaq 100) +4% Made money overall, lost in one period +31% Made money overall, lost in one period
MES (Micro S&P 500) −10% Lost money −22% Lost money
YM (Dow futures) +24% Made money in both periods +14% Made money overall, lost in one period
RTY (Russell 2000 futures) +13% Made money in both periods −6% 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
MNQ (Micro Nasdaq 100) 1-minute 1,491 36.6% 1.01 +4.1% −40.8% −25.8% +40.3% −51.4% $8,308
MNQ (Micro Nasdaq 100) 5-minute 1,489 39% 1.04 +31.4% −35.9% −3.4% +36.1% −45.2% $8,706
MES (Micro S&P 500) 1-minute 1,494 36.3% 0.99 −9.6% −44.3% +18.5% −23.7% −58.6% $38,073
MES (Micro S&P 500) 5-minute 1,494 36.5% 0.97 −21.9% −38.4% +20.6% −35.2% −61.0% $29,452
YM (Dow futures) 1-minute 874 38.3% 1.05 +24.1% −30.9% +4.9% +18.3% −34.2% $8,868
YM (Dow futures) 5-minute 874 39.4% 1.03 +13.7% −27.9% +23.7% −8.1% −35.0% $9,253
RTY (Russell 2000 futures) 1-minute 845 36.9% 1.03 +12.7% −26.0% +7.1% +5.2% −36.7% $8,385
RTY (Russell 2000 futures) 5-minute 486 36.8% 0.97 −5.9% −24.7% −5.9% 0.0% −34.6% $4,728

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

Best test MNQ (Micro Nasdaq 100), 5-minute chart +31.4% from 2020 to 2025
Middle test (median): half of the 8 did better, half did worse RTY (Russell 2000 futures), 1-minute chart +12.7% from 2020 to 2025

What we found

What the 8 backtests show

  1. With the basic rules, 5 of the 8 tests made money after trading costs. The profit factor (the money won divided by the money lost) was between 0.97 and 1.05, so every test was close to break-even. The best test was MNQ on the 5-minute chart: +31.4%, and at one point the account was 35.9% below its highest balance. Only 2 tests made money in both 2020–2023 and 2024–2025: YM and RTY on the 1-minute chart, which both skipped many days (see finding 5). MNQ lost money in 2020–2023 on both charts and made money in 2024–2025. MES made money in 2020–2023 and lost money in 2024–2025. So which market looked better depended on the years. No test passed all four of our checks (see 'How a test passes' below).

  2. Most trades lost. Of all 9,047 trades with the basic rules, 60.0% hit the stop-loss, 29.2% reached the 2R take-profit, and 10.8% were still open at 16:00 New York time and closed then. The win rate (the share of trades that made money after costs, including the 16:00 closes in profit) was 36% to 39% in every test, just above the 1 win in 3 that a 2R take-profit needs to break even before costs.

  3. Holding each trade until 16:00 New York time, with the stop-loss of the basic rules but no take-profit, made much more money on MNQ and MES from 2020 to 2025 (see the table below). On MNQ, it made money in both 2020–2023 and 2024–2025 on both charts: +103.4% and +111.4% in the backtest. At one point, those two accounts were 36.3% and 39.9% below their highest balance, and neither test passed all four of our checks. On MES, holding made money over the whole test, but lost money in 2024–2025. On YM and RTY, it did worse than the 2R take-profit from 2020 to 2025 (on YM, it did better in 2024–2025). Without a take-profit, fewer trades won (28% to 36%), but the winning trades were bigger.

  4. On MNQ and MES, breakouts above the range made money and breakouts below it lost money. R is the risk of one trade; in these results, 1R is 1% of the account at the time of the trade. With the basic rules, after costs, on both charts together, the buys made +79.3R on MNQ and +48.7R on MES. The sells lost 28.2R on MNQ and 57.9R on MES. On YM and RTY, the breakouts below the range did better than the breakouts above it (see the chart below). We did not test a version that only buys.

  5. Trading costs decided the MES result. Futures trade in whole contracts, and MNQ and MES are micro contracts, one tenth of the size of NQ and ES. For the same 1% risk, a typical MES trade needed 8 to 10 contracts, and a typical MNQ trade needed 3. Every contract pays the spread (the gap between the buy and the sell price) and a commission. So on average, an MES trade paid $25 (1-minute chart) and $20 (5-minute chart) in trading costs, and an MNQ trade about $6. YM and RTY are E-mini contracts, 10 times the size of their micro versions. On many days, the stop-loss of even one contract cost more than 1% of the account, so the backtest skipped the day. YM traded on 874 out of 1,496 trading days on each chart (not always the same days), and RTY on 845 days on the 1-minute chart and 486 days on the 5-minute chart.

The exit

2R take-profit or hold until 16:00?

Each row is one market and chart, tested two ways: with the 2R take-profit (the basic rules), and with no take-profit, holding each trade until 16:00 New York time. Both ways open trades on the same rules and use the same stop-loss. The first two result columns show the change in the account from 2020 to 2025. The last two show 2024 and 2025 only.

Market Chart 2R take-profit, 2020–2025 Hold until 16:00, 2020–2025 2R take-profit, 2024–2025 Hold until 16:00, 2024–2025
MNQ 1-minute +4.1% +103.4% +40.3% +46.2%
MNQ 5-minute +31.4% +111.4% +36.1% +64.2%
MES 1-minute −9.6% +46.9% −23.7% −28.5%
MES 5-minute −21.9% +29.4% −35.2% −30.4%
YM 1-minute +24.1% +8.5% +18.3% +21.1%
YM 5-minute +13.7% +10.6% −8.1% +12.9%
RTY 1-minute +12.7% −21.3% +5.2% −16.0%
RTY 5-minute −5.9% −9.9% 0.0% (break-even) −17.3%

On YM and RTY, the two versions did not trade on exactly the same days. A day was skipped when one contract risked more than 1% of the account, and 1% of a bigger balance is more money. The two versions had different balances, so they skipped different days.

Buys and sells

On MNQ and MES, only the buys made money

Each bar adds up the results of all the buys, or all the sells, on one market, after trading costs. The results are in R: 1R is 1% of the account at the time of the trade. The bars include both charts (1-minute and 5-minute) with the basic rules, from 2020 to 2025. R totals are not % results: the bars add both charts, and each R is 1% of the balance at that time. Green bars made money in total; red bars lost money.

  • MNQ buys1,518 trades +79.3R
  • MNQ sells1,462 trades −28.2R
  • MES buys1,530 trades +48.7R
  • MES sells1,458 trades −57.9R
  • YM buys875 trades +17.3R
  • YM sells873 trades +26.7R
  • RTY buys616 trades +1.7R
  • RTY sells715 trades +12.1R

For context: from the start of 2020 to the end of 2025, the price of MNQ rose about 190%, MES about 113%, YM about 70% and RTY about 49%.

The strategy

What the 5-minute opening range breakout is

The opening range is the highest and the lowest price of the first minutes after a market opens. The 5-minute opening range breakout (ORB) uses the first 5 minutes after the New York stock market opens: 09:30 to 09:35 New York time. Index futures trade almost 24 hours a day, but this range starts at 09:30, with the stock market. A breakout is a candle that closes outside the range. A common way to trade it: buy when a candle closes above the range, and sell short (sell first, to profit if price falls) when a candle closes below it. Traders expect the first move out of the range to keep going. We tested it on 4 US stock index futures. MNQ (Micro Nasdaq 100) and MES (Micro S&P 500) follow the same prices as NQ and ES, but one contract is one tenth of the size. YM (Dow) and RTY (Russell 2000) are the standard E-mini contracts, ten times the size of their micro versions (MYM and M2K), which are not in our data. We used 1-minute and 5-minute charts. The range is the same on both charts; the chart only decides which candle close counts as the breakout.

Opening range
09:30 to 09:35 New York time, the first 5 minutes of the stock market session
Breakout
A candle closes above the range high (buy) or below the range low (sell)
Stop-loss
The other side of the opening range
Take-profit
2R: 2 times the distance from the breakout candle's close to the stop-loss. A trade still open at 16:00 New York time closes then.
Trades per day
1 at most: the first breakout
Risk per trade
1% of the account, rounded down to whole contracts
Fills
The stop-loss fills at its price, or at a candle's open if price opens past it. The take-profit fills at its price. If price reaches both inside the same 1-minute candle, the backtest counts the stop-loss.
Price data
BacktestingMax's futures data. It is built from CFD prices (a broker's price that follows the same index) and adjusted to trade like the real contracts: the futures price, the trading hours, the tick (the smallest price step) and the roll (the switch from one contract month to the next). It is not exchange data.
Trading costs
A trade pays half a tick of spread (the gap between the buy and the sell price) when it opens, and half a tick when it closes. A take-profit pays no spread when it closes, and a limit order (the retest version) pays no spread when it opens. Every trade also pays a commission when it opens and again when it closes: $0.62 per MNQ or MES contract, and $2.50 per YM or RTY contract.

The rules we tested

  1. Each trading day, mark the opening range: the highest and the lowest price from 09:30 to 09:35 New York time. On the 1-minute chart, the range is the 5 candles from 09:30 to 09:35. On the 5-minute chart, it is the one candle from 09:30 to 09:35.
  2. After 09:35, buy when a candle closes above the range high. Sell (go short) when a candle closes below the range low. The trade opens at the next candle's open. A breakout counts on any candle that closes before 16:00 New York time.
  3. Put the stop-loss at the other side of the range: at the range low for a buy, and at the range high for a sell.
  4. R is the risk of the trade: the distance from the close of the breakout candle to the stop-loss. Put the take-profit 2R from that close, in the direction of the trade.
  5. If the trade is still open at 16:00 New York time, close it then.
  6. Take only the first breakout of the day, win or lose. After that trade, wait for the next day.
  7. Size every trade so that a loss at the stop-loss costs 1% of the account balance at that time. Futures trade in whole contracts, so round down to a whole number of contracts. If even one contract would risk more than 1% of the account, skip the day.
  8. Don't trade on days the New York Stock Exchange is closed or closes early (at 13:00).

The method

How we tested it

The test

Markets
MNQ (Micro Nasdaq 100), MES (Micro S&P 500), YM (Dow futures) and RTY (Russell 2000 futures)
Charts
1-minute and 5-minute candles
Dates
January 2020 to December 2025
Account
$50,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 5-minute opening range breakout be improved?

We tested four versions of the 5-minute ORB, each with one change that traders often make: no take-profit (hold until 16:00 New York time), a stop-loss at the middle of the range, trading only in the direction of the first 5 minutes, and waiting for a retest of the range. The table below explains each one. Each version ran on the same 8 tests. We picked the best version using 2020–2023 only: the one that made money in the most tests, and in a tie, the one with the better middle result (the median of the 8 tests). Then we checked it on 2024–2025, the years we did not use to pick it. If you pick a version and judge it on the same years, it almost always looks better than it really is.

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
Basic rules The rules under 'The rules we tested': the stop-loss at the other side of the range, and a 2R take-profit. 5 of 8middle test +6.0% 4 of 8middle test +2.6% 2 0
Hold until 16:00, no take-profitBest on 2020–2023 No take-profit. The trade ends at the stop-loss, or at 16:00 New York time. Some day traders hold an opening range breakout all day, because a strong move can go far past 2R. 5 of 8middle test +18.8% 4 of 8middle test −1.5% 2 0
Stop-loss at the middle of the range Put the stop-loss halfway between the range high and the range low, instead of at the other side. The stop-loss is closer, so with the same 1% risk you trade more contracts. The 2R take-profit is closer too. 2 of 8middle test −23.0% 2 of 8middle test −11.9% 0 0
Only in the direction of the first 5 minutes If price was higher at 09:35 than at 09:30 (a green first 5-minute candle), only take a buy. If it was lower (a red candle), only take a sell. If it was the same, don't trade that day. A breakout the other way doesn't count: wait for a breakout in the allowed direction, until 16:00 New York time. 3 of 8middle test −3.6% 5 of 8middle test +2.2% 2 0
Wait for a retest of the range A retest is when price comes back to the range after the breakout. After a candle closes above the range, place a buy limit order at the range high: an order that fills only if price comes back down to that level before 16:00 New York time. For a sell, place a sell limit order at the range low. The stop-loss stays at the other side of the range. Here R is the distance from the limit price to the stop-loss (the full height of the range), and the take-profit is 2R from the limit price. If price doesn't come back, there is no trade that day. 3 of 8middle test −6.2% 4 of 8middle test −1.5% 1 0

We picked holding until 16:00 using 2020–2023. On 2024–2025, the years we kept for the check, it did not beat the basic rules. On 2020–2023, it made money in 5 of 8 tests, the same number as the basic rules, with a better middle result: +18.8%, compared with +6.0%. On 2024–2025, it made money in 4 of 8 tests, again the same number, and its middle result was −1.5%, compared with +2.6%. With the hold version, 2 tests made money in both periods, the same number as with the basic rules, but not the same tests: MNQ on both charts, instead of YM and RTY on the 1-minute chart. On MNQ, holding did better on both charts, in both periods. Of the other versions, trading only in the direction of the first 5 minutes did best on 2024–2025: 5 of 8 tests made money. We did not pick it, because on 2020–2023 it made money in only 3 of 8 tests. On MNQ, it made +43.5% (1-minute chart) and +63.7% (5-minute chart), and its biggest fall from the highest balance was smaller: 21.7% and 24.7%, compared with 40.8% and 35.9% with the basic rules. The stop-loss at the middle of the range did worst: no test made money in both periods, and it lost more than 40% on MES and YM on both charts. Waiting for a retest made money in both periods in only 1 test, YM on the 5-minute chart, and it lost money on MNQ on both charts.

Questions

Questions traders ask

Does the 5-minute opening range breakout work?

Only a little in our backtest, and not on every market. All 8 tests made money before trading costs. After costs, the basic rules (the stop-loss at the other side of the opening range, and a take-profit at 2 times the distance to the stop-loss) made money in 5 of 8 tests: MNQ and YM on both charts, and RTY on the 1-minute chart. Only 2 made money in both 2020–2023 and 2024–2025: YM and RTY on the 1-minute chart. The best test, MNQ on the 5-minute chart, grew a $50,000 account by 31.4% from 2020 to 2025, risking 1% per trade. Holding each trade until 16:00 New York time did much better on MNQ (+103.4% and +111.4%), but from 2020 to 2025 it did worse on YM and RTY.

What is the win rate of the ORB strategy?

In each of the 8 tests of the 5-minute ORB with a take-profit at 2 times the distance to the stop-loss (2R), 36% to 39% of the trades made money. Of all 9,047 trades, 60.0% hit the stop-loss, 29.2% reached the take-profit, and 10.8% closed at 16:00 New York time. That win rate is just above the 1 win in 3 that a 2R take-profit needs to break even before costs, so after trading costs only 5 of the 8 tests made money. Without a take-profit, holding each trade until 16:00, the win rate fell to 28% to 36%, but the winning trades were bigger.

Does the opening range breakout work better on NQ or ES?

On NQ over 2020 to 2025, in our backtest, but NQ's lead came from 2024–2025. We tested MNQ and MES, the micro contracts that follow the same prices as NQ and ES. With the basic rules, MNQ made +4.1% (1-minute chart) and +31.4% (5-minute chart) from 2020 to 2025, and MES lost 9.6% and 21.9%. The MES trades made money before costs, but their trading costs were bigger than that profit. MNQ lost money in 2020–2023 and made money in 2024–2025. MES made money in 2020–2023 and lost money in 2024–2025. Holding each trade until 16:00 New York time did better on both markets: +103.4% and +111.4% on MNQ, and +46.9% and +29.4% on MES. But even with that exit, MES lost money in 2024–2025.

Should you trade the 5-minute ORB on a 1-minute or a 5-minute chart?

Neither chart was better everywhere. The opening range is the same on both charts: 09:30 to 09:35 New York time. The chart only decides which candle close counts as the breakout. The 1-minute chart gets you in sooner: half of its trades opened by 09:39, compared with 09:45 on the 5-minute chart, and 96% to 98% of the 1-minute trades opened by 10:00. With the 2R take-profit, the 1-minute chart did better on YM and RTY and lost less on MES, and the 5-minute chart did better on MNQ (+31.4%, compared with +4.1%). When holding until 16:00, the 5-minute chart did better on MNQ and YM and lost less on RTY, and the 1-minute chart did better on MES. A 5-minute candle often closes further past the range, so the entry is further from the stop-loss. On RTY, one contract then more often risked more than 1% of the account, so the 5-minute chart traded on fewer days: 486, compared with 845.

Keep exploring

Related strategies we tested

Opening range breakout 15-minute opening range breakout backtest on NQ and ES futures Made money in 9 of 12 tests, 8 of them in both periods. Best: MNQ (Micro Nasdaq 100), 5-minute, +158% Sessions New York open breakout backtest on NQ, ES and gold futures Made money in 0 of 10 tests, 0 of them in both periods. Best: RTY (Russell 2000 futures), 15-minute, −6% Sessions London breakout strategy backtest on forex and gold Made money in 5 of 18 tests, 4 of them in both periods. Best: USD/JPY, 5-minute, +43%
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 OpeningRangeBreakout5Min(Strategy):
    """The 5-minute opening range breakout (ORB) on US stock index futures, as day
    traders learn it, plus the changes they argue about.
    The opening range is the highest and the lowest price of the first 5 minutes of the
    New York stock market session: 09:30 to 09:35 New York time (daylight saving
    included). On a 1-minute chart that is the first 5 candles; on a 5-minute chart, the
    first candle. Index futures trade almost around the clock, but this strategy only
    looks at the stock market's hours, 09:30 to 16:00 New York.
    Standard (all switches off): after 09:35, the first candle that closes above the
    range high is a buy, and the first candle that closes below the range low is a sell
    (go short). The trade opens at the next candle's open. The stop-loss sits at the
    other side of the range: the range low for a buy, the range high for a sell. The
    take-profit sits 2 times the risk away (2R), the risk being the distance from the
    entry to the stop-loss. A trade still open at 16:00 New York closes then. One trade
    a day: the first break, win or lose. Size every trade so that the stop-loss costs
    1% of the account. No trading on days the New York Stock Exchange is closed or
    closes early (13:00).
    The changes, one at a time:
      hold         = 1   no take-profit: only the stop-loss or the 16:00 close ends the
                         trade
      mid_stop     = 1   the stop-loss sits at the middle of the range instead of the
                         other side (half the risk, so the 2R target is closer too)
      first_candle = 1   only buy if the first 5 minutes closed higher than they opened;
                         only sell if they closed lower
      retest       = 1   after the break, wait for price to come back to the range: a
                         limit order at the range high (buys) or the range low (sells),
                         good until 16:00. The take-profit is 2R from that price.
    """
    params = {"range_minutes": Param(type=int, default=5, min=1, max=60),
              "exit_rr": Param(type=float, default=2.0, min=0.5, max=10.0),
              "hold": Param(type=int, default=0, min=0, max=1),
              "mid_stop": Param(type=int, default=0, min=0, max=1),
              "first_candle": Param(type=int, default=0, min=0, max=1),
              "retest": Param(type=int, default=0, min=0, max=1)}
    lookback = 2
    session_open = 570    # 09:30 New York, in minutes after midnight
    session_close = 960   # 16:00 New York
    # Days with no trading, 2020-2025: the New York Stock Exchange is closed, or it
    # closes early at 13:00.
    closed_days = (
        "2020-01-01 2020-01-20 2020-02-17 2020-04-10 2020-05-25 2020-07-03 2020-09-07 2020-11-26 "
        "2020-11-27 2020-12-24 2020-12-25 "
        "2021-01-01 2021-01-18 2021-02-15 2021-04-02 2021-05-31 2021-07-05 2021-09-06 2021-11-25 "
        "2021-11-26 2021-12-24 "
        "2022-01-17 2022-02-21 2022-04-15 2022-05-30 2022-06-20 2022-07-04 2022-09-05 2022-11-24 "
        "2022-11-25 2022-12-26 "
        "2023-01-02 2023-01-16 2023-02-20 2023-04-07 2023-05-29 2023-06-19 2023-07-03 2023-07-04 "
        "2023-09-04 2023-11-23 2023-11-24 2023-12-25 "
        "2024-01-01 2024-01-15 2024-02-19 2024-03-29 2024-05-27 2024-06-19 2024-07-03 2024-07-04 "
        "2024-09-02 2024-11-28 2024-11-29 2024-12-24 2024-12-25 "
        "2025-01-01 2025-01-09 2025-01-20 2025-02-17 2025-04-18 2025-05-26 2025-06-19 2025-07-03 "
        "2025-07-04 2025-09-01 2025-11-27 2025-11-28 2025-12-24 2025-12-25")
    def init(self, ctx):
        self.ny = ctx.clock("America/New_York")
        self.no_trading = set(self.closed_days.split())
        self.day = None
        self.high = None         # the opening range high
        self.low = None          # the opening range low
        self.first_open = None   # the price at 09:30
        self.range_close = None  # the last close inside the opening range
        self.done = True         # True once today's trade has been placed (or the day is skipped)
        self.order = None        # a retest limit order still waiting to fill
    def on_bar(self, ctx):
        start = self.ny.minute_of_day              # this candle's open, New York time
        end = start + ctx.timeframe_minutes        # this candle's close
        range_end = self.session_open + ctx.params.range_minutes
        if self.ny.date != self.day:               # a new day: forget yesterday's range
            if self.order is not None:
                ctx.cancel_order(self.order.order_id)
            self.day = self.ny.date
            self.high = self.low = self.first_open = self.range_close = None
            self.done = self.day in self.no_trading
            self.order = None
        if ctx.position is not None:
            self.order = None                      # a retest order has filled
            if end >= self.session_close or start < self.session_open:
                ctx.close_position()               # fills at the 16:00 candle's open
            return
        # Build the opening range from the candles that open from 09:30 to 09:35.
        if self.session_open <= start < range_end:
            if start == self.session_open:
                self.first_open = ctx.open[0]
            self.high = ctx.high[0] if self.high is None else max(self.high, ctx.high[0])
            self.low = ctx.low[0] if self.low is None else min(self.low, ctx.low[0])
            self.range_close = ctx.close[0]
            return
        if self.order is not None and end >= self.session_close:
            ctx.cancel_order(self.order.order_id)  # price never came back: no trade today
            self.order = None
        if self.done or start < range_end or end >= self.session_close:
            return
        if not ctx.gate("full_opening_range", self.first_open is not None and self.high > self.low):
            self.done = True
            return
        close = ctx.close[0]
        up = close > self.high
        down = close < self.low
        if not ctx.gate("range_break", up or down):
            return
        if ctx.params.first_candle == 1:
            direction = self.range_close - self.first_open  # how the first 5 minutes closed
            if not ctx.gate("first_5_minutes_agree", (up and direction > 0) or (down and direction < 0)):
                return                             # a break the other way: keep waiting
        self.done = True                           # one trade a day: this break is it
        middle = (self.high + self.low) / 2
        if up:
            entry = self.high if ctx.params.retest == 1 else close
            stop = middle if ctx.params.mid_stop == 1 else self.low
        else:
            entry = self.low if ctx.params.retest == 1 else close
            stop = middle if ctx.params.mid_stop == 1 else self.high
        risk = abs(entry - stop)
        if risk <= 0:
            return
        size = ctx.size_by_risk_pct(0.01, stop=stop, entry=entry)
        if not ctx.gate("one_contract_fits_1pct_risk", size > 0):
            return                                 # one contract would risk more than 1%
        target = None
        if ctx.params.hold == 0:
            target = entry + ctx.params.exit_rr * risk if up else entry - ctx.params.exit_rr * risk
        limit = entry if ctx.params.retest == 1 else None
        if up:
            order = ctx.buy(size=size, limit=limit, sl=stop, tp=target, tag="orb_long")
        else:
            order = ctx.sell(size=size, limit=limit, sl=stop, tp=target, tag="orb_short")
        if limit is not None:
            self.order = order

Your turn

Test the 5-minute opening range breakout yourself

Change the settings, the market or the stop-loss and see the result in seconds. Ask the BacktestingMax AI: Backtest a 5-minute opening range breakout on MNQ, 5-minute chart: range 09:30 to 09:35 New York, stop at the other side of the range, no take-profit, exit at 16:00.

Try it free in BacktestingMax

Free account. No credit card needed.

See every strategy we tested Browse strategies shared by traders

Backtest on historical data with trading costs, run by BacktestingMax. Past results do not guarantee future results, and nothing here is financial advice. Updated 19 October 2026.