Skip to content

Free TradingView indicator

Opening Range Breakout

Plots the high and low of a session's first N minutes, signals closes beyond it and projects targets as range multiples.

Breakoutv1.0TradingView (Pine Script v6) Non-repainting signals Alerts

What it does

The opening range is the high and low price reached in the first minutes of a session. Many intraday traders treat a close beyond that range as a sign of the day's early direction. This indicator draws the range, signals the first close above or below it, and projects two targets as multiples of the range height.

How it works

  1. At the first candle of the session, the range starts at that candle's high and low.
  2. For every candle that opens within the first N minutes, the range high and low expand to include it. After N minutes the range is locked.
  3. Long breakout: a closed candle finishes above the range high after previously closing at or below it. Short breakout: a close below the range low after previously closing at or above it. With "only the first breakout per side" on, each side can signal once per session.
  4. Targets: range height = high − low. Long targets = range high + height × multiple. Short targets = range low − height × multiple.

Illustrative example: if the first 15 minutes of an index session make a high of 5,020 and a low of 5,000, the height is 20 points. A long breakout projects targets at 5,040 (1×) and 5,060 (2×).

Lines are plots, so no drawing objects build up on the chart. A warning appears if your chart timeframe is longer than the opening range.

How to use it

  • Use a chart timeframe that divides the range length evenly, such as M1 or M5 for a 15-minute range, so the range is built from several candles.
  • Stock index and US stock sessions are the classic use. For forex, try the London open (for example 0800-1700 Europe/London) or the New York open.
  • Many traders place the stop on the opposite side of the range or at its midpoint. Check that the target distance is worth the risk with the Risk-Reward Calculator.
  • A narrow opening range compared with recent days may lead to a cleaner breakout; a very wide one leaves less room for the targets.

Alerts: breakout up, breakout down. Both fire on candle close.

Settings

InputDefaultWhat it changes
Session hours0930-1600Session used for the range
Session time zoneAmerica/New_YorkClock used for the hours
Opening range length15 minutesRange-building period
Only the first breakout per sideOnOne signal per side per session
Show breakout markersOnTriangles on signals
Show targets after a breakoutOnTarget lines
Target 1 / Target 21.0 / 2.0Target distance in range heights

Limitations

Breakouts from the opening range often fail and return inside, especially on quiet days or before scheduled news. The targets are simple projections, not forecasts. Signals require a candle close, so on M15 the entry can come well after the actual break. Forex has no single opening bell, so results depend heavily on the session you pick. Spreads are often wider in the first minutes of a session.

Pine Script source

In TradingView open Pine Editor, paste the code, click Save and then Add to chart.

FXP_OpeningRangeBreakout.pine

90 lines

// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/opening-range-breakout/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
// Measures the high and low of the first N minutes of a session (the opening range),
// then flags the first close above / below it and projects targets as multiples of the
// range height. Signals are confirmed on bar close.
indicator("FXP Opening Range Breakout", shorttitle = "FXP ORB", overlay = true)

// ── Inputs ─────────────────────────────────────────────────────────────
grpS      = "Session"
sess      = input.session("0930-1600", "Session hours", group = grpS)
tzIn      = input.string("America/New_York", "Session time zone", options = ["America/New_York", "Europe/London", "Europe/Berlin", "Asia/Tokyo", "Asia/Kolkata", "Australia/Sydney", "UTC", "Exchange"], group = grpS)
orMinutes = input.int(15, "Opening range length (minutes)", minval = 1, maxval = 480, group = grpS)

grpSig    = "Signals"
oneSignal = input.bool(true, "Only the first breakout per side each session", group = grpSig)
showSig   = input.bool(true, "Show breakout markers", group = grpSig)

grpT      = "Targets"
showTgt   = input.bool(true, "Show targets after a breakout", group = grpT)
t1Mult    = input.float(1.0, "Target 1 (x range)", minval = 0.1, step = 0.1, group = grpT)
t2Mult    = input.float(2.0, "Target 2 (x range)", minval = 0.1, step = 0.1, group = grpT)

grpC      = "Colors"
colHi     = input.color(#26a69a, "Range high / long", group = grpC)
colLo     = input.color(#ef5350, "Range low / short", group = grpC)
colFill   = input.color(color.new(#2962ff, 90), "Range fill while forming", group = grpC)

// ── Opening range ──────────────────────────────────────────────────────
string tz = tzIn == "Exchange" ? syminfo.timezone : tzIn

bool inSess  = timeframe.isintraday and not na(time(timeframe.period, sess, tz))
bool newSess = inSess and not inSess[1]

var int   orEnd     = na
var float orHigh    = na
var float orLow     = na
var bool  longDone  = false
var bool  shortDone = false

if newSess
    orEnd     := time + orMinutes * 60000
    orHigh    := high
    orLow     := low
    longDone  := false
    shortDone := false
else if inSess and time < orEnd
    orHigh := math.max(orHigh, high)
    orLow  := math.min(orLow, low)

bool  building = inSess and time < orEnd
bool  ready    = inSess and time >= orEnd and not na(orHigh)
float rng      = orHigh - orLow

// ── Breakouts (closed bars) ────────────────────────────────────────────
bool longBreak  = barstate.isconfirmed and ready and close > orHigh and close[1] <= orHigh and (not oneSignal or not longDone)
bool shortBreak = barstate.isconfirmed and ready and close < orLow and close[1] >= orLow and (not oneSignal or not shortDone)

if longBreak
    longDone := true
if shortBreak
    shortDone := true

// ── Plots ──────────────────────────────────────────────────────────────
pHi = plot(building or ready ? orHigh : na, "Opening range high", color = colHi, linewidth = 2, style = plot.style_linebr)
pLo = plot(building or ready ? orLow : na, "Opening range low", color = colLo, linewidth = 2, style = plot.style_linebr)
fill(pHi, pLo, color = building ? colFill : na, title = "Opening range fill")

bool showLongT  = showTgt and longDone and inSess
bool showShortT = showTgt and shortDone and inSess
plot(showLongT ? orHigh + rng * t1Mult : na, "Long target 1", color = color.new(colHi, 30), style = plot.style_linebr)
plot(showLongT ? orHigh + rng * t2Mult : na, "Long target 2", color = color.new(colHi, 55), style = plot.style_linebr)
plot(showShortT ? orLow - rng * t1Mult : na, "Short target 1", color = color.new(colLo, 30), style = plot.style_linebr)
plot(showShortT ? orLow - rng * t2Mult : na, "Short target 2", color = color.new(colLo, 55), style = plot.style_linebr)

plotshape(showSig and longBreak, "Long breakout", shape.triangleup, location.belowbar, colHi, size = size.small)
plotshape(showSig and shortBreak, "Short breakout", shape.triangledown, location.abovebar, colLo, size = size.small)

// ── Timeframe warning ──────────────────────────────────────────────────
var table warn = table.new(position.bottom_right, 1, 1)
if barstate.islast
    if timeframe.isintraday and timeframe.in_seconds() > orMinutes * 60
        table.cell(warn, 0, 0, "Chart timeframe is longer than the opening range. Use a lower timeframe.", text_color = color.white, bgcolor = color.new(color.red, 20), text_size = size.small)
    else if not timeframe.isintraday
        table.cell(warn, 0, 0, "Opening range breakout needs an intraday chart.", text_color = color.white, bgcolor = color.new(color.red, 20), text_size = size.small)

// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(longBreak, "Opening range breakout up", "{{ticker}} {{interval}}: closed above the opening range at {{close}}")
alertcondition(shortBreak, "Opening range breakout down", "{{ticker}} {{interval}}: closed below the opening range at {{close}}")

Key inputs

Key inputs of Opening Range Breakout
InputDefaultDescription
Session hours0930-1600Session whose opening range is measured.
Session time zoneAmerica/New_YorkTime zone the session hours are written in.
Opening range length15 minutesMinutes from the session start used to build the range.
Only the first breakout per sideOnOne long and one short signal per session at most.
Target 1 / Target 21.0 / 2.0 × rangeProjected targets as multiples of the range height.

Educational tools, not advice. Indicators and Expert Advisors describe price; they do not predict it, and past behaviour does not guarantee future results. Test everything on a demo account first and never risk money you cannot afford to lose. See our disclaimer.

Keep exploring

Related tradingview indicators