Repaints AGAIG MTF Opening Range Breakout Trade Indicator For ThinkOrSwim

Repaints

csricksdds

Trader Educator
VIP
AGAIG MTF OPENING RANGE BREAKOUT TRADE INDICATOR

In this indicator I am using 15 minute breakout lines and the indicator will only show one breakout each trading session and I must remind you that all breakouts don’t continue for long runs. Sometimes support and resistance is merely being tested​

Chart Look:
6InslQa.png


Setup

Apply to a 5-minute chart, RTH only doesn't matter for chart display — extended hours can be on or off since the study itself already ignores pre/post-market for triggering new entries.

Key inputs to check per symbol: strikeIncrement (set to match how that name's option chain is spaced — 1 for most, 2.5/5 for higher-priced names), openingRangeMinutes (15 is a reasonable default; tighten to 5 for a more aggressive/faster read, widen to 30 for a more conservative range), holdBars (2 is a solid starting filter against single-bar fakeouts).

Reading the chart

Dashed red/green lines = resistance/support from the opening range. These freeze once the window closes (e.g. 9:45am with the 15-min default) and hold for the rest of the day.

A white OBB-Long or OBB-Short bubble is your entry signal — it only fires once per day, whichever direction triggers first. It shows the ATM strike, T1, T2, and stop.

Once triggered, a dotted stop line and two dashed target lines (light green/red, T1 thinner, T2 thicker) track the trade while it's open.

The corner label always tells you the current state at a glance: which side is active, bars elapsed, and the live stop/target numbers — or "DAILY SIGNAL USED" once the day's shot is spent.

How I'd actually trade it

Wait for the bubble, not just the lines — the lines alone aren't a signal, they're just the levels being watched.

Stop is fixed at entry (prior bar's low/high) and doesn't trail — that's a deliberate simplicity choice, so you decide manually whether to tighten it as price moves toward T1.

T1/T2 are pure price-based math (2x/3x the entry-to-stop distance) — they're a reference for where R-multiples land on the stock, not a guarantee the option will track 1:1 with the underlying's move given theta/IV.

Known limits worth remembering

No live option chain access — always double check the actual weekly contract and its bid/ask before entering, this only tells you where ATM sits.

One signal per day means if you get stopped out early, it won't re-arm even if price re-breaks later that same session.

Backtest holdBars and openingRangeMinutes against your usual watchlist before trusting it live — both were reasonable defaults, not tuned to any specific name.

Indicator Link: http://tos.mx/!f91fu06F
Code:
# AGAIG Opening Bell Breakouts
# ------------------------------------------------------------
# Opening-range breakout indicator for use on an individual
# stock's 5-minute chart.
#
# Logic:
#  - Support/Resistance = high/low of the first N minutes of
#    regular trading hours (RTH), starting at 9:30am ET
#  - Long trigger: close holds above resistance for `holdBars`
#    consecutive RTH bars
#  - Short trigger: close holds below support for `holdBars`
#    consecutive RTH bars
#  - Signals only evaluate during RTH (9:30am-4:00pm ET) -- no
#    triggers on pre-market or after-hours bars
#  - Stop loss = low (long) / high (short) of the bar immediately
#    preceding the trigger bar
#  - Profit targets: T1 = 2x the entry-to-stop distance,
#    T2 = 3x the entry-to-stop distance
#  - One signal per day, either direction
#  - Entry bubble (white background) shows the ATM strike, T1,
#    T2, and stop; a status label in the corner shows trade
#    state, bars elapsed, and current stop/targets
#
# NOTE: ThinkScript chart studies cannot query the live option
# chain. The "strike" shown is a calculated ATM price reference
# based on the underlying's price and your chosen strike
# increment -- you still select the actual weekly contract
# manually.
# ------------------------------------------------------------

declare upper;

input holdBars = 2;                  # consecutive closes required beyond level to confirm breakout
input openingRangeMinutes = 15;      # window from market open used to build support/resistance
input strikeIncrement = 1.0;         # option strike spacing for this underlying (e.g. 1, 2.5, 5)
input showBubbles = yes;
input showLevels = yes;
input showStatusLabel = yes;

# ---------- Regular Trading Hours flag ----------
# Everything that can trigger a NEW signal is gated by this so pre-market
# and after-hours prints against the opening range can't fire an entry.
def isRTH = SecondsFromTime(0930) >= 0 and SecondsFromTime(1600) < 0;

# ---------- Opening Range (first N minutes of RTH) ----------
def orStart = SecondsFromTime(0930) == 0;
def orWindow = SecondsFromTime(0930) >= 0 and SecondsFromTime(0930) < openingRangeMinutes * 60;

rec orHigh = if orStart then high
             else if orWindow then Max(if IsNaN(orHigh[1]) then high else orHigh[1], high)
             else orHigh[1];

rec orLow = if orStart then low
            else if orWindow then Min(if IsNaN(orLow[1]) then low else orLow[1], low)
            else orLow[1];

def resistanceLevel = orHigh;
def supportLevel = orLow;

plot Resistance = if showLevels then resistanceLevel else Double.NaN;
plot Support = if showLevels then supportLevel else Double.NaN;
Resistance.SetDefaultColor(Color.RED);
Support.SetDefaultColor(Color.GREEN);
Resistance.SetLineWeight(2);
Support.SetLineWeight(2);
Resistance.SetStyle(Curve.SHORT_DASH);
Support.SetStyle(Curve.SHORT_DASH);

# ---------- New day reset ----------
def newDay = GetDay() <> GetDay()[1];

# ---------- Breakout hold confirmation (RTH bars only) ----------
# Outside RTH, counts hold steady (frozen) rather than accumulating,
# so a pre-market or after-hours print can never build toward a trigger.
rec aboveCount = if newDay then 0
                 else if !isRTH then aboveCount[1]
                 else if close > resistanceLevel then aboveCount[1] + 1
                 else 0;

rec belowCount = if newDay then 0
                 else if !isRTH then belowCount[1]
                 else if close < supportLevel then belowCount[1] + 1
                 else 0;

def longTriggerRaw = isRTH and aboveCount == holdBars;
def shortTriggerRaw = isRTH and belowCount == holdBars;

# ---------- One-signal-per-day cap ----------
# Once either a long or short signal has fired, no further signals
# (of either direction) are allowed until the next session.
rec dailySignalUsed = if newDay then 0
                      else if longTriggerRaw or shortTriggerRaw then 1
                      else if IsNaN(dailySignalUsed[1]) then 0
                      else dailySignalUsed[1];

def longTrigger = longTriggerRaw and (dailySignalUsed[1] == 0 or IsNaN(dailySignalUsed[1]));
def shortTrigger = shortTriggerRaw and (dailySignalUsed[1] == 0 or IsNaN(dailySignalUsed[1]));

# ---------- Stop loss + entry price (captured once at trigger) ----------
rec entryStopLong = if newDay then Double.NaN
                    else if longTrigger then low[1]
                    else entryStopLong[1];

rec entryStopShort = if newDay then Double.NaN
                     else if shortTrigger then high[1]
                     else entryStopShort[1];

rec entryPriceLong = if newDay then Double.NaN
                     else if longTrigger then close
                     else entryPriceLong[1];

rec entryPriceShort = if newDay then Double.NaN
                      else if shortTrigger then close
                      else entryPriceShort[1];

# ---------- Trade state (one trade tracked at a time, resets each session) ----------
# Once a trade is open, the stop is monitored on every bar (including
# after-hours), since a real open position can still be stopped out
# outside RTH -- only NEW entries are restricted to RTH above.
rec inLong = if newDay then 0
             else if longTrigger then 1
             else if inLong[1] == 1 and low <= entryStopLong then 0
             else inLong[1];

rec inShort = if newDay then 0
              else if shortTrigger then 1
              else if inShort[1] == 1 and high >= entryStopShort then 0
              else inShort[1];

# ---------- Bars elapsed in active move (used for status label) ----------
rec barsInLong = if longTrigger then 1
                 else if inLong == 1 then barsInLong[1] + 1
                 else 0;

rec barsInShort = if shortTrigger then 1
                  else if inShort == 1 then barsInShort[1] + 1
                  else 0;

# ---------- ATM strike suggestion ----------
def atmStrike = Round(close / strikeIncrement, 0) * strikeIncrement;
def suggestedCallStrike = atmStrike;
def suggestedPutStrike = atmStrike;

# ---------- Profit targets (T1 = 2x stop distance, T2 = 3x stop distance) ----------
def longRiskDistance = entryPriceLong - entryStopLong;
def shortRiskDistance = entryStopShort - entryPriceShort;

def longTarget1 = entryPriceLong + (2 * longRiskDistance);
def longTarget2 = entryPriceLong + (3 * longRiskDistance);

def shortTarget1 = entryPriceShort - (2 * shortRiskDistance);
def shortTarget2 = entryPriceShort - (3 * shortRiskDistance);

# ---------- Entry bubbles ----------
AddChartBubble(showBubbles and longTrigger, low,
    "OBB-Long\nCall " + suggestedCallStrike + " - ATM"
    + "\nT1 " + Round(longTarget1, 2) + "  T2 " + Round(longTarget2, 2)
    + "\nStop " + Round(entryStopLong, 2),
    Color.WHITE, no);

AddChartBubble(showBubbles and shortTrigger, high,
    "OBB-Short\nPut " + suggestedPutStrike + " - ATM"
    + "\nT1 " + Round(shortTarget1, 2) + "  T2 " + Round(shortTarget2, 2)
    + "\nStop " + Round(entryStopShort, 2),
    Color.WHITE, yes);

# ---------- Stop loss markers while trade active ----------
plot LongStop = if inLong == 1 then entryStopLong else Double.NaN;
LongStop.SetDefaultColor(Color.DARK_GREEN);
LongStop.SetStyle(Curve.POINTS);
LongStop.SetLineWeight(3);

plot ShortStop = if inShort == 1 then entryStopShort else Double.NaN;
ShortStop.SetDefaultColor(Color.DARK_RED);
ShortStop.SetStyle(Curve.POINTS);
ShortStop.SetLineWeight(3);

# ---------- Target markers while trade active ----------
plot LongT1 = if inLong == 1 then longTarget1 else Double.NaN;
LongT1.SetDefaultColor(Color.LIGHT_GREEN);
LongT1.SetStyle(Curve.SHORT_DASH);
LongT1.SetLineWeight(1);

plot LongT2 = if inLong == 1 then longTarget2 else Double.NaN;
LongT2.SetDefaultColor(Color.LIGHT_GREEN);
LongT2.SetStyle(Curve.SHORT_DASH);
LongT2.SetLineWeight(2);

plot ShortT1 = if inShort == 1 then shortTarget1 else Double.NaN;
ShortT1.SetDefaultColor(Color.LIGHT_RED);
ShortT1.SetStyle(Curve.SHORT_DASH);
ShortT1.SetLineWeight(1);

plot ShortT2 = if inShort == 1 then shortTarget2 else Double.NaN;
ShortT2.SetDefaultColor(Color.LIGHT_RED);
ShortT2.SetStyle(Curve.SHORT_DASH);
ShortT2.SetLineWeight(2);

# ---------- Status label ----------
AddLabel(showStatusLabel,
    if inLong == 1 then "LONG ACTIVE  bars:" + barsInLong + "  stop:" + Round(entryStopLong, 2) + "  T1:" + Round(longTarget1, 2) + "  T2:" + Round(longTarget2, 2)
    else if inShort == 1 then "SHORT ACTIVE  bars:" + barsInShort + "  stop:" + Round(entryStopShort, 2) + "  T1:" + Round(shortTarget1, 2) + "  T2:" + Round(shortTarget2, 2)
    else if dailySignalUsed == 1 then "DAILY SIGNAL USED - no more trades today"
    else "NO ACTIVE SIGNAL",
    if inLong == 1 then Color.GREEN
    else if inShort == 1 then Color.RED
    else if dailySignalUsed == 1 then Color.GRAY
    else Color.LIGHT_GRAY);

AddLabel(showLevels, "OR(" + openingRangeMinutes + "m)  R: " + Round(resistanceLevel, 2) + "   S: " + Round(supportLevel, 2), Color.LIGHT_GRAY);

# ---------- Alerts ----------
Alert(longTrigger, "Opening Bell Breakout LONG", Alert.BAR, Sound.Ring);
Alert(shortTrigger, "Opening Bell Breakout SHORT", Alert.BAR, Sound.Ring);
 
Last edited by a moderator:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
1059 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top