The opening range is the high and the low of the first minutes after a market opens, 30 minutes after 09:30 New York by default. Once the range is complete, the strategy rests a buy stop at its high and a sell stop at its low, one cancelling the other, so there is at most one trade a day. The stop sits the width of the range away from the fill (the other side), the target a multiple of that distance (2R by default), and on the session's second to last bar every open order is cancelled and the position closed, so the exit fills at the open of the last bar.
The session is three run parameters on the market's own clock: the time zone as a number (0 New York, 1 Chicago, 2 London, 3 Berlin, 4 Zurich, 5 Tokyo, 6 Hong Kong, 7 Sydney, 8 UTC) and the open and the close written HHMM (930 is 09:30). New York is zone 0 from 930 to 1600, Frankfurt (Xetra) zone 3 from 900 to 1730, London zone 2 from 800 to 1630. The backtest form and the optimiser set them, and they go along into an export for MetaTrader 5, cTrader, TradingView or Rust. The template turns the wall clock time into UTC for every day, so the range starts at the right bar in summer and in winter, including the weeks when America and Europe have changed their clocks and the other has not. Times that are not clock times, or a close at or before the open, place nothing.
An optional filter skips days whose range is unusually small or large compared with the daily ATR, computed over whole days from the bars of the run.
Parameters
Name
Type
Default
Range or options
Description
rangeMinutes
int
30
min 1, max 240
Minutes after the open that make the range. A whole number of bars.
stopRange
float
1
min 0.1, max 3
The stop's distance from the fill as a share of the range (with the buffer on both sides). 1.0 is the other side.
targetR
float
2
min 0, max 10
The target as a multiple of the stop distance. 0 sets no target; the position is closed before the close.
bufferPips
float
0
min 0, max 100
Pips beyond the range high and low the stop orders rest at.
minRangeAtr
float
0
min 0, max 5
Skip a day whose range is smaller than this many daily ATRs. 0 is off.
maxRangeAtr
float
0
min 0, max 5
Skip a day whose range is larger than this many daily ATRs. 0 is off.
atrDays
int
14
min 2, max 100
Whole days in the daily ATR the two filters compare with. Used only when a filter is on.
riskPercent
float
1
min 0, max 10
Per cent of the balance lost if the stop is hit. 0 trades the run's lot size.
allowShort
int
1
min 0, max 1
1 trades breaks in both directions, 0 long only.
zone
int
0
min 0, max 8
The market's time zone: 0 New York, 1 Chicago, 2 London, 3 Berlin, 4 Zurich, 5 Tokyo, 6 Hong Kong, 7 Sydney, 8 UTC. The open and the close are read on this clock, and a day is a calendar day on it.
sessionOpen
int
930
min 0, max 2359
When the session opens, HHMM on the market's clock. The opening range starts here: 930 for New York, 900 for Frankfurt.
sessionClose
int
1600
min 0, max 2359
When the session closes, HHMM on the market's clock, later the same day. The position is closed at the open of the last bar before it.
Use it in a strategy
python# The entry rule in your own strategy, on the close of the bar that completes the range
# (six M5 bars for a 30 minute range):
bars = ctx.bars(6)
high = max(b.high for b in bars)
low = min(b.low for b in bars)
dist = (high - low) / ctx.pip()
ctx.order("LONG", stop=high, sl_pips=dist, tp_pips=2 * dist, oco="orb", risk_percent=1.0)
ctx.order("SHORT", stop=low, sl_pips=dist, tp_pips=2 * dist, oco="orb", risk_percent=1.0)
To run the whole template, install it, switch it on, pick Opening range breakout under Plugins in the strategy list and set the session in its parameters. Run it on M1, M5, M15 or M30 bars that start on the open. In a strategy of your own, finding the bar that completes the range on the market's clock is the part to write yourself; the template writes each zone's daylight saving rules out as arithmetic, which is what lets it export.
What it provides
opening_range_breakout/orbStrategy
The strategy, with its parameters: range minutes, stop as a share of the range, target in R, entry buffer, the daily ATR filter, the risk per trade, the short side, and the session (time zone, open, close).
When values are known
The range is known on the close of its last bar, and the two orders rest from the next bar on. The daily ATR for the filter covers the days before the current one only.
Limits
Session times are the ones you set. Holidays and early closes are not known to the template: on a short day the exit comes at the usual time, after the market has closed.
The daylight saving rules are written out from the first year each zone has kept them: New York and Chicago 1976, London 1972, Berlin 1980, Zurich 1981, Tokyo 1952, Hong Kong 1980, Sydney 1996. The backtest reads the time zone database on earlier days. An export for MetaTrader 5, cTrader, TradingView or Rust has the rules only, so it places nothing on a day before the zone's first year, and its daily ATR counts from there.
The bars have to start on the open and divide the range. On H1 bars and a 09:30 open there is no bar at 09:30, so nothing trades.
An export reads the bar's time to the minute. On bars shorter than a minute (S5) it places nothing; the backtest trades them.
On CFD and FX data the market trades before the open, so the open is a time of day rather than a first print. The range is built from the run's bars, which may differ from the exchange's own opening range.
A narrow range with risk sizing means a large position. The engine refuses an entry the margin cannot carry, and a fast open can fill a stop order well past its price.
Breakouts of the opening range often fail and reverse; a day can take the stop and then run in the original direction. No result is promised.