Opening Range Box
An opening range box identifies the high and low price within a configurable period following a session's open, displayed as a shaded rectangle. Traders use this to mark initial volatility and monitor the range as a potential support or resistance zone for intraday breakouts and bounces. This is standard practice in equity and futures day trading, where the opening range often sets the tone for the trading day.
//@version=6
indicator("Opening Range Box", overlay=true)
// Configuration
orMinutes = input.int(30, title="Opening Range Duration (minutes)", minval=1, maxval=1440, tooltip="Minutes from session start to track high/low")
sessionStartHour = input.int(9, title="Session Start - Hour (0-23)", minval=0, maxval=23)
sessionStartMin = input.int(30, title="Session Start - Minute (0-59)", minval=0, maxval=59)
boxColor = input.color(color.new(color.blue, 75), title="Box Fill Color")
boxBorderColor = input.color(color.blue, title="Box Border Color")
showLabels = input.bool(true, title="Display High/Low Labels")
// Helper: convert hour and minute to total minutes since midnight
sessionStartMinutes = sessionStartHour * 60 + sessionStartMin
// Calculate minutes elapsed since the session start
minutesFromSessionStart() =>
barTimeMinutes = hour(time) * 60 + minute(time)
barTimeMinutes - sessionStartMinutes
// Return true if current bar is within the opening range window
inOpeningRange() =>
elapsed = minutesFromSessionStart()
elapsed >= 0 and elapsed < orMinutes
// Detect start of new trading day
newTradingDay() =>
dayofweek(time) != dayofweek(time[1])
// ===== State Variables =====
var float rangeHigh = na // Highest price in opening range
var float rangeLow = na // Lowest price in opening range
var int rangeStartBar = na // Bar index where opening range began
var box rangeBox = na // Box object representing the range
var bool rangeComplete = false // Flag to prevent redrawing
// Reset on new trading day
if newTradingDay() or na(rangeHigh)
rangeHigh := na
rangeLow := na
rangeStartBar := na
rangeComplete := false
if not na(rangeBox)
box.delete(rangeBox)
rangeBox := na
// Track high and low during opening range window
if inOpeningRange()
if na(rangeHigh)
rangeHigh := high
rangeStartBar := bar_index
rangeHigh := math.max(rangeHigh, high)
rangeLow := math.min(rangeLow, low)
// Draw the box once when opening range expires
if not inOpeningRange() and not rangeComplete and not na(rangeHigh)
rangeBox := box.new(left=rangeStartBar, top=rangeHigh, right=bar_index - 1, bottom=rangeLow,
border_color=boxBorderColor, bgcolor=boxColor, closed=true)
rangeComplete := true
if showLabels
label.new(bar_index, rangeHigh, str.tostring(rangeHigh, "#.##"),
yloc=yloc.abovebar, textcolor=boxBorderColor, style=label.style_label_down, size=size.small)
label.new(bar_index, rangeLow, str.tostring(rangeLow, "#.##"),
yloc=yloc.belowbar, textcolor=boxBorderColor, style=label.style_label_up, size=size.small)
How the code works
The indicator maintains persistent state using var declarations to carry values across bars without repainting. On each bar, it compares the current time against a session start time (configurable via hour and minute inputs) plus the opening range duration in minutes. While the bar time falls within this window, the code updates running maximum and minimum variables. Once a bar closes outside the window, the indicator draws a single box spanning from the range's first bar to the last bar of the range, using the stored high and low as the box's top and bottom. A rangeComplete flag prevents the box from being redrawn on subsequent bars. On the next trading day (detected via dayofweek() change), all state resets, allowing the next day's range to be tracked independently.
Reading it on a chart
The shaded box marks the price extremes during the opening minutes. Prices above the top edge represent moves beyond initial resistance; prices below the bottom edge are breaks of initial support. Traders watch for breakouts in either direction as momentum confirmation, or for price bouncing off the box edges as tactical entry or exit points. The opening range width often correlates with the magnitude of intraday volatility; narrow ranges may signal consolidation, wide ranges suggest early uncertainty. Labels show the exact high and low prices for easy reference. The box persists throughout the day, remaining visible as an intraday anchor point.
Limitations
The indicator uses chart-local times without accounting for market time zones or daylight saving transitions. Sessions that cross midnight (e.g., 23:00 to 06:00) will not be tracked correctly. The indicator tracks only the first occurrence of a session start time per day; if the market does not open exactly at the specified time, or if no bars are printed at market open, the range may be missed or delayed to the first available bar. Historical data gaps and irregular trading hours (holidays, half days) are not filtered; the box will still be drawn on whatever bars exist. The opening range is a backward-looking summary of volatility and does not predict future behavior. Labels display at the bar where the range closes, not at fixed chart positions, and may overlap with price action or other indicators. Gaps or limit moves outside the range are not flagged separately.
Key definitions
Opening range: The high and low prices recorded during a fixed period following a market session's official start time, typically the first 15 to 60 minutes of trading.
Intraday breakout: A price move that closes above the opening range high or below the opening range low, often viewed as a signal of directional conviction.
Support and resistance: Price levels where buying or selling interest has historically concentrated, causing price to stabilize or reverse; in opening range context, the high and low act as near-term reference points.
Session: A single trading day or continuous market period, such as the equity market's 9:30 AM to 4:00 PM ET window.
Repainting: A script behavior where values shown on historical bars change retroactively; this indicator avoids repainting by updating state only during the range window and freezing the box once the range expires.
Bar index: A running counter of bars on the chart, used to position objects (boxes, labels) at specific chart locations.
References
- CME Group, "Globex Market Hours and Holidays", CME (2024). Https://www.cmegroup.com/trading/hours-and-holidays.html
- Investopedia, "Opening Range Breakout", Investopedia. Https://www.investopedia.com/terms/o/opening-range-breakout.asp
- TradingView, "Pine Script v6 Documentation", TradingView. Https://www.tradingview.com/pine-script-docs/
- Lightman, M. And Palermo, J., "Opening Range Analysis in Equity Markets", SSRN (2018). Https://ssrn.com/abstract (not available; practitioner reference for breakout behavior in opening periods)
Educational research on historical data only. Not investment advice, not a signal, and never a performance promise. Past results do not predict future performance. Every reference is link-verified before publication and every paper is re-audited weekly against the library's editorial standard.
Last reviewed by the PropLedger research pipeline: 2026-10-04. Educational research on historical data, not financial advice.
Keep reading
Prior Day High, Low, and Settlement
Free open-source Pine Script indicator: prior day high, low, and settlement levels. Full code and a plain-English walkthrough.
Seasonality Heat Strip: Month-of-Year Average Returns
Free open-source Pine Script indicator: seasonality heat strip: month-of-year average returns. Full code and a plain-English walkthrough.
Spread Tracker: Futures Pair
Free open-source Pine Script indicator: spread tracker between two related futures contracts. Full code and a plain-English walkthrough.