Five-Minute Opening-Range Retests With Prior-Day Bias

Video: Once You Master This Strategy, Trading Becomes Incredibly Simple
Creator: Scarface Trades
Original Video: Watch the original video
Difficulty: Intermediate

The Big Idea

Scarface Trades combines two references: the prior day’s regular-session high and low, and the first five minutes of today’s cash open. He then waits for a breakout and a retest with supportive candle behavior. The aim is to enter after price returns to a known boundary rather than chasing the initial move.

The “one candle” framing refers to the first five-minute opening range, analyzed with one-minute execution candles. It is not literally a strategy requiring only one observation. The creator’s reported dollar profits, high-probability claims, and winning examples are not a verified performance record or a guarantee of results.

Step One: Mark the Correct Prior-Day Range

The source explicitly uses the previous regular session from 9:30 a.m. to 4:00 p.m. Eastern. Its high and low exclude premarket and overnight movement. A platform’s default daily candle may use a different session, especially for futures, so do not substitute it without checking.

The source interprets price above the prior high as strength and price below the prior low as weakness. Those are conditional directional filters, not predictions that continuation must occur. Price between the two remains inside the previous range and does not satisfy either outside-range condition.

The cash-equity open at 9:30 New York time can be a useful reference for related futures and options, but it is not the universal opening time of every instrument. Futures can already be trading, and an option’s execution depends on its own quote, spread, and contract behavior. An underlying-chart backtest is not an option-premium backtest.

Step Two: Wait for the First Five Minutes to Finish

On a one-minute chart, collect the bars opening at 9:30, 9:31, 9:32, 9:33, and 9:34. Their combined high and low become the opening range at 9:35. The 9:34 bar includes trading until 9:35; the range is not final when that candle starts.

Freeze those boundaries once the five bars close. The bearish example breaks the prior low early. In the bullish example, the first five-minute range begins inside the prior day’s range and price later moves above the prior high. Both references must be evaluated using information available at the time of the actual setup.

An opening-range break alone is not the requested entry. Separate the breakout event from the later retest so a single wide candle does not retrospectively provide both a completed signal and an impossible earlier fill.

Step Three: Retest, Confirm, and Define Risk

DecisionBullish versionBearish version
Directional contextPrice above the prior regular-session high.Price below the prior regular-session low.
Opening boundaryBreak above the five-minute high.Break below the five-minute low.
ReturnPrice revisits the opening high and shows bullish response.Price revisits the opening low and shows bearish response.
RiskThe example invalidates below the entry candle.The short-stop wording is unclear; define a price above the short entry before trading.
ObjectiveThe source uses the high of day in its example and asks for at least 2R.The source describes a 2R objective.

The creator calls the short confirmation a bearish hammer-style candle and the long confirmation a strong green candle. Exact body, wick, and tolerance thresholds are not supplied. A research script therefore needs explicit substitute definitions.

The short example says the stop would be a “break back below” the prior low, although the proposed entry is already short below that low. Taken literally, that is not a conventional protective buy-stop above entry. It may be a verbal or transcript error, but the chart’s intended stop cannot be established from that sentence alone. Do not copy it as a complete risk rule.

Check the Reward-to-Risk Arithmetic

The short illustration quotes approximately $990 of risk and $1,670 of potential profit. That is about 1.69R, not at least 2R. The long illustration quotes $600 of risk and $1,230 of potential profit, which is 2.05R, rather than the stated 2.25R. Rounding or the displayed chart may explain differences, but the quoted numbers do not support the stated multiples.

For an original long example, suppose the opening high is $101, the prior-day high is $100.80, and a later retest candle closes at $101.10 with a low of $100.95. An illustrative stop at $100.94 creates $0.16 of signal-price risk. A fixed 2R target would be $101.42. A $50 planned price-risk budget permits 312 whole shares before costs, margin constraints, and execution uncertainty.

If the actual next-open fill is $101.18 while those absolute stop and target prices stay fixed, risk becomes $0.24 and reward becomes $0.24: only 1R. This is why close-price arithmetic and executable entry timing must be kept separate. A narrower retest stop can improve nominal reward/risk while making the result more sensitive to spread and slippage.

A high-of-day target must be the high already observed when the decision is made, not the eventual day’s high. If that known high does not offer sufficient room, the setup fails that target model. A fixed-R target and a high-of-day target are different experiments.

Pine Script: Opening-Range Retest Research Strategy

Show Pine Script — five-minute opening-range retest strategy

//@version=6
// Guide: https://candlechasers.com/five-minute-opening-range-retest-prior-day-bias/
// Research approximation for US equity/ETF one-minute standard candles.
strategy("CandleChasers - Five-minute range retest", overlay=true,
     initial_capital=25000, pyramiding=0,
     commission_type=strategy.commission.percent, commission_value=0.01,
     slippage=2, margin_long=100, margin_short=100,
     calc_on_order_fills=false, calc_on_every_tick=false, process_orders_on_close=false)
units = input.int(1, "Fixed shares", minval=1)
reward = input.float(2.0, "Signal-price reward/risk", minval=2)
toleranceATR = input.float(0.1, "Retest tolerance / prior ATR", minval=0)
expiry = input.int(15, "Breakout expires after bars", minval=1)
atr = ta.atr(14)
nyMinute = hour(time, "America/New_York") * 60 + minute(time, "America/New_York")
rth = nyMinute >= 570 and nyMinute < 960
start = nyMinute == 570
valid = chart.is_standard and timeframe.isminutes and timeframe.multiplier == 1
var float dayHigh = na
var float dayLow = na
var int dayBars = 0
var bool beganAtOpen = false
var float previousHigh = na
var float previousLow = na
var float openingHigh = na
var float openingLow = na
var int openingBars = 0
var int longBreak = na
var int shortBreak = na
var bool submittedToday = false
var float tradeStop = na
var float tradeTarget = na
if valid and barstate.isconfirmed
    if start
        previousHigh := beganAtOpen and dayBars == 390 ? dayHigh : na
        previousLow := beganAtOpen and dayBars == 390 ? dayLow : na
        dayHigh := na
        dayLow := na
        dayBars := 0
        beganAtOpen := true
        openingHigh := na
        openingLow := na
        openingBars := 0
        longBreak := na
        shortBreak := na
        submittedToday := false
    if rth
        dayHigh := na(dayHigh) ? high : math.max(dayHigh, high)
        dayLow := na(dayLow) ? low : math.min(dayLow, low)
        dayBars += 1
        if nyMinute < 575 and beganAtOpen
            openingHigh := na(openingHigh) ? high : math.max(openingHigh, high)
            openingLow := na(openingLow) ? low : math.min(openingLow, low)
            openingBars += 1
        ready = openingBars == 5 and not na(previousHigh) and nyMinute >= 575 and nyMinute < 660
        tolerance = atr[1] * toleranceATR
        if ready and not submittedToday and strategy.position_size == 0
            if not na(longBreak) and (bar_index - longBreak > expiry or close <= openingHigh or close <= previousHigh)
                longBreak := na
            if not na(shortBreak) and (bar_index - shortBreak > expiry or close >= openingLow or close >= previousLow)
                shortBreak := na
            // Retest must be on a later completed candle than the breakout.
            longSignal = not na(longBreak) and bar_index > longBreak and low <= openingHigh + tolerance and high >= openingHigh - tolerance and close > openingHigh and close > previousHigh and close > open
            shortSignal = not na(shortBreak) and bar_index > shortBreak and high >= openingLow - tolerance and low <= openingLow + tolerance and close < openingLow and close < previousLow and close < open
            if longSignal
                tradeStop := low - syminfo.mintick
                tradeTarget := close + reward * (close - tradeStop)
                strategy.entry("L", strategy.long, qty=units)
                strategy.exit("LX", "L", stop=tradeStop, limit=tradeTarget)
                submittedToday := true
            else if shortSignal
                tradeStop := high + syminfo.mintick
                tradeTarget := close - reward * (tradeStop - close)
                strategy.entry("S", strategy.short, qty=units)
                strategy.exit("SX", "S", stop=tradeStop, limit=tradeTarget)
                submittedToday := true
            if not submittedToday
                if na(longBreak) and close > openingHigh and close > previousHigh and close[1] <= math.max(openingHigh, previousHigh)
                    longBreak := bar_index
                if na(shortBreak) and close < openingLow and close < previousLow and close[1] >= math.min(openingLow, previousLow)
                    shortBreak := bar_index
    if nyMinute == 959
        strategy.close_all(comment="Regular session end", immediately=true)
if strategy.position_size > 0
    strategy.exit("LX", "L", stop=tradeStop, limit=tradeTarget)
if strategy.position_size < 0
    strategy.exit("SX", "S", stop=tradeStop, limit=tradeTarget)
plot(rth ? previousHigh : na, "Prior RTH high", color.green, style=plot.style_linebr)
plot(rth ? previousLow : na, "Prior RTH low", color.red, style=plot.style_linebr)
plot(rth and openingBars == 5 ? openingHigh : na, "Opening high", color.aqua, style=plot.style_linebr)
plot(rth and openingBars == 5 ? openingLow : na, "Opening low", color.orange, style=plot.style_linebr)
plot(strategy.position_size != 0 ? tradeStop : na, "Frozen stop", color.red, style=plot.style_linebr)
plot(strategy.position_size != 0 ? tradeTarget : na, "Frozen target", color.green, style=plot.style_linebr)
var table status = table.new(position.top_right, 1, 1)
if barstate.islast
    table.cell(status, 0, 0, not valid ? "Use standard 1-minute candles" : na(previousHigh) ? "Need a complete prior 390-bar RTH session" : "Prior session ready; entries 09:35-10:59 NY", text_color=chart.fg_color)

The Pine Script v6 strategy below uses standard one-minute US equity or ETF charts. It builds prior-session levels directly from 9:30–16:00 New York bars, waits for the five-minute range to complete, requires a completed breakout beyond both relevant levels, and accepts a retest only on a later candle. Bullish confirmation means a green close above both levels; bearish confirmation means a red close below both. Retest proximity is adjustable using prior-bar ATR.

Research choices added here are one submitted entry per day, a 15-bar breakout expiry, entries from 9:35 through 10:59, stops one tick beyond the retest candle, and fixed signal-price R targets for both directions. These are transparent approximations, not a reproduction of the creator’s discretionary results. A close back inside either required level cancels an armed setup.

The script deliberately requires a complete prior 390-bar regular session and all five opening bars. The first loaded session, a missing-bar session, or a half-day prior session will not qualify. It skips the next day after an abbreviated prior session instead of treating the reduced range as a normal full session. Load enough one-minute history. The status panel explains basic chart and prior-session eligibility.

Stops and targets are frozen and submitted with the market entry. Entries normally fill on the following bar, so gaps and slippage change realized reward/risk. No order-fill or tick recalculation is enabled, no higher-timeframe requests are used, and no future pivots or final high-of-day values are consulted. Keep those recalculation settings disabled in Strategy Properties.

The script closes any remaining position on the completed 15:59 bar using an immediate simulated market close. That same-close assumption can be optimistic; it is not a guaranteed live closing fill. It does not implement holiday early closes, so exclude those dates when positions could remain open or implement a proper calendar before using the model for operational trading.

Fixed shares are not fixed percentage-risk sizing. Example costs and capital may need adjustment; unsupported contract size or inadequate capital can reject orders. The strategy is not designed to model futures session rules or option contracts. The code has been reviewed for chronological signal construction and future-data leakage but has not been compiled or backtested in TradingView here. Consult the official strategy documentation (paid link) for fill assumptions and simulation limits.

What to Test Before Trusting the Model

  1. Prior-day filter: compare retests with and without the outside-prior-range requirement while retaining the same opening range and exits.
  2. Breakout versus retest: compare actual next-available fills, rejected or missing retests, costs, and adverse excursions rather than just attractive hindsight entries.
  3. Target choice: compare fixed R with a pre-entry high-of-day or low-of-day target, keeping the minimum reward/risk gate explicit.
  4. Confirmation: compare a simple directional close with a separately specified wick/body rejection pattern on later evaluation data.

Record independent setup count, fill price, signal-price and realized risk, average net outcome, drawdown, slippage, and the number of breakout days that never offered a qualifying retest. Include failed and skipped setups. Two successful chart examples cannot establish a stable edge.

Common Execution Errors

  • Using overnight highs and lows when the method requires the previous cash session.
  • Trading before the fifth opening bar closes.
  • Assuming a candle’s intrabar touch was tradable after judging its completed confirmation.
  • Calling a wick touch a retest without defining the allowed tolerance and closing behavior.
  • Using the eventual high of day as a target known before entry.
  • Sizing from an attractive nominal R multiple without allowing for execution costs.

Final Takeaway

The useful structure is prior regular-session bias, a completed five-minute opening range, and a later retest with a defined response. The trade still needs an unambiguous stop, a target known at the decision time, and executable sizing. Simplicity makes the rules easier to review; it does not establish profitability.

Risk Disclosure

This article and code are educational and are not financial advice or a recommendation to trade. Trading may cause substantial losses, and leverage can amplify them. Stops cannot guarantee prices, and opening volatility can worsen spreads and slippage. Backtests depend on data, session definitions, order timing, and fill assumptions and cannot reproduce all live conditions. Historical or reported results do not guarantee future performance. Costs, liquidity, gaps, holidays, market regimes, and discretionary execution may materially alter outcomes. Validate the code, instrument specifications, and risk controls before considering live use.

CandleChasers independently interprets this source and is not affiliated with or endorsed by Scarface Trades. Reported earnings and probability claims belong to the creator; the examples, research definitions, and code here are CandleChasers’ own educational work.

As an Amazon Associate I earn from qualifying purchases.