Idea in brief
Toby Crabel wrote a book on short-term price patterns and the opening range breakout (ORB). The core idea: the market alternates between rest and movement, and one phase gives rise to the other. So an opening breakout is worth trading after a compression day, when the day's range is narrower than several previous ones, not after a wide day.
Crabel measures compression with simple filters: NR4 (the day's range is narrower than each of the three previous days), NR7 (narrower than the six previous days), inside day (the range is inside yesterday's) and their combination ID/NR4. On the next day Crabel places stop orders above and below the opening range at a stretch distance, the 10-day average of the distance from the open to the nearer extreme. The order that fills becomes the position, and the other serves as the protective stop.
The card has two more variants of the same compression idea. Jack Corsellis trades narrow daily bars in leading stocks through their high. Trader X, analyzed by the prop firm IQ Capital from trade logs, looks on the hourly chart of ES and NQ for four candles in a row, each no wider than the previous one.
Why it might work
A narrow day means that neither buyers nor sellers could move the price. The market is in balance and waiting for new information. Crabel writes that participants act on the first sign of direction after such a lull, so the first confident move out of the range after compression more often grows into a trend day. Stretch filters out noise near the open: price has to move away from the range by an amount typical for that market.
The second layer of the explanation is about time. Crabel's ideal trade goes into profit right away, and the best entry is in the first 10 minutes. The more time passes from the open to the entry, the lower the chance. If price stands still after entry, the trade is suspect.
The figures come from Crabel's book. The markets and test period are not named in the video. The explanation of Trader X's approach through volatility regime changes was given by the host based on the logs, and the trader did not disclose the exit rules.
Rules
Compression filters (author)
// daily bars; day 0 = the last closed day
R(k) = High[k] - Low[k]
NR4 = R(0) < R(1) AND R(0) < R(2) AND R(0) < R(3) // narrower than each of the three previous days
NR7 = R(0) < R(k) for all k = 1..6
Inside = High[0] <= High[1] AND Low[0] >= Low[1] // Finetiq: we allow equal extremes
ID_NR4 = Inside AND NR4 // the best filter according to Crabel's data
R2(k) = Highest(High, 2)[k] - Lowest(Low, 2)[k]
NR2bar = R2(0) < Lowest(R2, 20)[1] // the narrowest 2-day range in 20 days
R3(k) = Highest(High, 3)[k] - Lowest(Low, 3)[k]
NR3bar = R3(0) < Lowest(R3, 28)[1] // 28 days in video #14 (27:23);
// in video #41 (02:25) Jack says 20 days. Test both
// Finetiq: we compare with windows ending on days 1..N, and allow a one-day overlap
Contraction = NR7 OR ID_NR4 OR (Inside AND R(0) < R(k) for k = 1..4)
// author: ORB is effective after an inside day narrower than the 4-5 previous days and after any NR7
ORB entry (author)
// stretch over the 10 previous days
Stretch = Average( MIN(High - Open, Open - Low), 10 )[1]
// the day after Contraction
OR_High, OR_Low = high and low of the opening range
// Finetiq: the length of the range is not named in the video. Starting version: the first 5-minute bar,
// variant for testing: the opening price (OR_High = OR_Low = Open)
BuyLevel = OR_High + Stretch
SellLevel = OR_Low - Stretch
BUY STOP at BuyLevel
SELL SHORT STOP at SellLevel
// the first filled order = the position, the second stays as the protective stop
Long: StopLoss = SellLevel
Short: StopLoss = BuyLevel
CANCEL both orders if neither is filled within 60 minutes after the open
// Finetiq: the author only says that a late entry is worse, and the worst entry is before the close
ORBp: one order with the trend (author)
// in a market with a clear direction and on any inside day (author)
TrendUp = Close > EMA(Close, 21) AND EMA(Close, 21) > EMA(Close, 21)[5]
TrendDown = Close < EMA(Close, 21) AND EMA(Close, 21) < EMA(Close, 21)[5]
// author: the main trend matters more than anything else. EMA 21 is taken from Jack's example, the 5-day slope is Finetiq
IF TrendUp THEN only BUY STOP at BuyLevel
IF TrendDown THEN only SELL SHORT STOP at SellLevel
// the protective stop is placed after entry: Long StopLoss = SellLevel
IF price first reached the opposite level THEN CANCEL the order // author
Trade management
// author: stop to breakeven within an hour after entry
IF 60 minutes have passed since entry
IF the position is in profit THEN StopLoss = EntryPrice
ELSE EXIT AT NEXT BAR OPEN // Finetiq: we read "the trade does not behave like the ideal" as an exit
// author: the target is a 2-3 day move, but hold overnight only with a substantial profit by the end of the session
IF 5 minutes left until the end of the session
IF profit in points >= Stretch THEN hold, StopLoss = EntryPrice // Finetiq: "substantial" = one stretch
ELSE EXIT
IF the position has been open for 3 days THEN EXIT at the close // Finetiq
Variant B. Daily narrow bar in a leader (Jack)
// daily bars; which stocks count as leaders is decided by screening outside the signal
Trigger = (NR7 OR NR2bar OR NR3bar OR Inside)
AND bar near EMA(Close, 10) or EMA(Close, 21) // author: most often near the 10 and 21 EMAs
// Finetiq: "near the average" = Low <= EMA <= High
ADRpct = 100 * (Average(High / Low, 20) - 1) // author: 20-day ADR% without gaps; Finetiq: formula
IF Trigger
BUY STOP at High[0] // author: through the high of the narrow bar
StopLoss = Low[0] // author
IF (High[0] - Low[0]) / High[0] * 100 > 2/3 * ADRpct THEN CANCEL // author: risk 1/2-2/3 of ADR%
CANCEL after 3 days without a fill // Finetiq
SELL 1/2 (or 1/3) LIMIT at EntryPrice + 1R (or + 2R) // author
remainder: EXIT AT NEXT BAR OPEN on Close < EMA(Close, 10) or EMA(Close, 21) // author
Variant C. Trader X's monotonic compression
// hourly bars of ES and NQ, positions are held overnight (author)
Compression = R(0) <= R(1) AND R(1) <= R(2) AND R(2) <= R(3)
// author: four candles in a row, each no wider than the previous one, the last one the narrowest
// Finetiq: the phrase can also be read as four comparisons (five candles). Test both
BUY STOP at High[0] + 1 tick
SELL SHORT STOP at Low[0] - 1 tick // OCO (author)
after a fill both levels are removed, no re-entry on the setup // author
no more than one trade a day per instrument // author
some major news events are skipped // author, which ones exactly is unknown
// exit: the author uses a volatility trailing stop, we could not reconstruct the formula
InitialStop = the opposite level // Finetiq
Trail (long) = Highest(High since entry) - 3 * ATR(14) // Finetiq: starting value
SELL 1/2 LIMIT at EntryPrice + 2R, remainder on Trail // Finetiq: the author exits in parts
Parameters
| Parameter | Value | Source |
|---|---|---|
| NR4 and NR7 | narrower than 3 and 6 previous days | author |
| Inside day | range inside yesterday's | author |
| Best filter | ID/NR4 | author |
| 2-bar NR window | 20 days | author |
| 3-bar NR window | 28 days (#14) or 20 days (#41) | author, two values |
| Stretch | 10-day average of MIN(High − Open, Open − Low) | author |
| Opening range | first 5-minute bar | Finetiq |
| Entry window | 60 minutes from the open | Finetiq |
| ORBp trend filter | EMA 21, 5-day slope | author (Jack's example), slope Finetiq |
| Breakeven | within an hour after entry | author |
| Holding overnight | end-of-day profit of at least one stretch, up to 3 days | Finetiq |
| Variant B: risk | no more than 1/2-2/3 of the 20-day ADR% | author |
| Variant B: partial exit | 1/2 or 1/3 at 1R or 2R | author |
| Variant B: trailing stop | close below the 10 or 21 EMA | author |
| Variant C: compression | 4 candles, each no wider than the previous one | author |
| Variant C: timeframe and markets | H1, ES and NQ | author |
| Variant C: trailing stop | 3 × ATR(14) from the high | Finetiq |
| Variant C: partial exit | 1/2 at 2R | Finetiq |
What to test
- Crabel's main claim. ORB on days after Contraction versus ORB on days after a wide day (range larger than the three or six previous days) and versus ORB every day. If the result after compression is not better, the filter does not work on your market.
- ID/NR4 versus the individual filters. Compare inside day, NR4 and their combination on the same entry. Crabel claims the combination is better in 15 tests out of 16.
- Stretch neighborhood. Multiplier 0, 0.5, 1 and 1.5, window of 5, 10 and 20 days. Separately, the opening range length: the opening price, 5, 15 and 30 minutes. If the result holds only for one combination, it is overfitting.
- The 3-bar NR window. 20 days versus 28. The difference between Jack's two videos gives a ready-made sensitivity test.
- Exit. Breakeven after an hour versus no breakeven, versus an exit at the end of the day and versus holding for 2-3 days. The one-hour rule changes the win rate the most.
- Trader X and costs. Three comparisons versus four, monotonic compression versus classic NR4 on H1. On ES a tick is worth $12.50. Add a tick of slippage on each stop order plus commission and see how much of the average trade remains.
- Variant B. A risk threshold of 1/2 ADR versus 2/3 and versus no threshold. If the result without a threshold is no worse, the filter only reduces the number of trades.
Platform notes
TradingView (Pine Script)
- Compression filters and stretch are calculated on daily bars, while the entry is on 5-minute bars. Take yesterday's values without looking ahead:
request.security(syminfo.tickerid, "D", expr[1], lookahead = barmerge.lookahead_on). - The daily bar of CME futures starts at 18:00 ET the previous day. The Open, High and Low of such a bar are not the day session on which ORB is built. For futures, calculate the range, NR and stretch for the main session from intraday bars.
- The pair of orders:
strategy.entrywithstopandoca_type = strategy.oca.cancel, and after entry a protective stop viastrategy.exit(..., stop = sellLevel). - One hour in a trade on 5-minute bars:
bar_index - strategy.opentrades.entry_bar_index(0) >= 12. If the entry and the stop are both hit by one candle, you needuse_bar_magnifier = trueor a lower timeframe.
MultiCharts and TradeStation (EasyLanguage)
Timeis the bar's close time: the first 5-minute bar after the 09:30 open hasTime = 935. Daily values are convenient to take from a second data stream (High of Data2).Buy next bar at BuyLevel stoplives for one bar, and orders are sent again on every bar. Once a position is open, stop sendingSell Shortand placeSell next bar at SellLevel stop. Otherwise the opposite order will reverse the position, while in Crabel's rules the second order only closes it.- NR and stretch depend on the day's Open, High and Low, and those depend on the session template (day session or 24 hours). Keep one template for the daily and the intraday stream.
- The one-hour rule on 5-minute bars:
If BarsSinceEntry >= 12 then .... For the order of fills within a candle, enable Bar Magnifier or Look-Inside-Bar.
MetaTrader 5 (MQL5)
- The daily bar is built on the broker's server time, and its Open is server midnight, not the exchange open. Stretch on such a bar is different. Calculate daily values yourself from M5 over the exchange session.
- At some brokers, a short Sunday bar almost always qualifies as NR4 and NR7. These are false signals for Monday and need to be excluded.
- Convert the 09:30 ET open to server time, accounting for daylight saving time. In the tester,
TimeGMT()equals server time. - Trader X's "one tick" is the ES price increment (0.25). CFDs on the S&P 500 have a different increment, so use
SYMBOL_TRADE_TICK_SIZE, not_Point. OCO and removing levels after entry have to be coded yourself.
Where the idea can break
- Crabel's statistics are old and come from the book. The markets, period and costs of the test are not named in the video. Compression patterns have become widely known since then.
- Crabel requires taking the whole market context into account: trend, support and resistance, the character of the specific instrument. The mechanical version does not contain this and may work worse than Crabel's own practice.
- Trader X's results cover 25 calendar days and 20 trading days. They were shown by a prop firm in a promotional video with a challenge discount. The host says that, according to the code, the strategy also found mediocre breakouts that Trader X did not take, so signal selection is manual. The stop formula is unknown.
- Stop orders on a breakout near the open fill with slippage, and spreads are wider in the first minutes. With frequent intraday trades, this is a noticeable share of the expectancy.
- Variant B relies on choosing leading stocks. Jack decides which stocks count as leaders, and without that screening the signal on a random stock may behave differently.