Opening Range Breakout

Captures initial session volatility by trading breakouts from the first N minutes' high/low range.

The opening range concentrates the session's first burst of volatility into a defined high and low. When price breaks out of that range with conviction, the move can extend significantly. When it fakes out, it reverses quickly. This strategy defines the range over the first N minutes, enters on a confirmed breakout in either direction, and exits with defined risk and reward. The settings — range duration, targets, session filters — are where the real work happens.

The Opening Range Breakout (ORB) is one of the most well-known intraday trading strategies, popularized by traders like Toby Crabel in his 1990 book Day Trading with Short Term Price Patterns and Opening Range Breakout. The concept is elegantly simple: the first portion of a trading session often sets the tone for the rest of the day.

The "opening range" is defined as the high and low established during the first N minutes of the session — typically 15, 30, or 60 minutes. Once this range is established, the strategy watches for price to break above the high (bullish) or below the low (bearish) and enters a trade in that direction.

The logic behind ORB is rooted in market microstructure. The opening of a trading session is when overnight orders, institutional flows, and news reactions converge. This creates a burst of activity that often establishes key support and resistance levels for the day. A breakout from this range suggests that one side (buyers or sellers) has gained control.

The strategy includes take-profit and stop-loss levels based on the opening range size, expressed as multipliers. For example, a TP multiplier of 1.5x means the profit target is 1.5 times the height of the opening range. This provides a systematic risk/reward framework.

//@version=6
strategy("Opening Range Breakout", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

// Inputs
orbMinutes = input.int(30, "ORB Window (minutes)", options=[15, 30, 60])
tpMult = input.float(1.5, "Take Profit Multiplier")
slMult = input.float(1.0, "Stop Loss Multiplier")

// Session timing
isNewDay = ta.change(time("D")) != 0
var float orbHigh = na
var float orbLow = na
var bool orbDefined = false
var int barCount = 0

if isNewDay
    orbHigh := high
    orbLow := low
    orbDefined := false
    barCount := 0

barCount += 1
orbBars = orbMinutes / timeframe.multiplier

if barCount <= orbBars
    orbHigh := math.max(orbHigh, high)
    orbLow := math.min(orbLow, low)
    if barCount == orbBars
        orbDefined := true

Once the opening range is defined, the breakout logic is straightforward. The strategy uses ta.crossover() and ta.crossunder() to detect the moment price breaks through the range boundaries. Each trade is paired with calculated exit levels based on the range size, ensuring consistent risk management across different market conditions.

// Breakout logic
orbRange = orbHigh - orbLow
longBreakout = orbDefined and ta.crossover(close, orbHigh)
shortBreakout = orbDefined and ta.crossunder(close, orbLow)

if (longBreakout)
    strategy.entry("ORB Long", strategy.long)
    strategy.exit("ORB Long Exit", "ORB Long", profit=orbRange * tpMult / syminfo.mintick, loss=orbRange * slMult / syminfo.mintick)

if (shortBreakout)
    strategy.entry("ORB Short", strategy.short)
    strategy.exit("ORB Short Exit", "ORB Short", profit=orbRange * tpMult / syminfo.mintick, loss=orbRange * slMult / syminfo.mintick)

// Plot ORB levels
plot(orbDefined ? orbHigh : na, "ORB High", color=color.green, style=plot.style_stepline)
plot(orbDefined ? orbLow : na, "ORB Low", color=color.red, style=plot.style_stepline)