‹ All setups

Higher-timeframe breakout · no headline needed · 1-minute

Technical Catalyst Breakout

A breakout doesn't always need breaking news. When a stock or ETF clears a level it couldn't get through for weeks or months, that level is the catalyst. Take only 9 and 10 out of 10 levels, on elevated relative volume, with a volume spike on the breakout bar and a tape that pays the offer. Then stop it, add to it and exit it by the rules.

9 / 10the only levels worth trading
2×+relative volume going in
8steps: spot, enter, size, exit
Watch the video Get the indicator

8 / 8

Watch one breakout, start to finish

1

A 9 out of 10 level on the longer-term chart

  • Not a random intraday squiggle, and not a 6 out of 10 inside a sloppy range. A level the stock or ETF couldn't clear for weeks or months.
  • Judge it on the higher timeframe and the intraday chart together. Ask every time: on a scale of 1 to 10, how important is this level?
  • ETHA had been capped under 19.12 for over a month, and Ethereum under 2,550 for weeks: four to five weeks of built-up energy.

When a product can't get above a price for a month and then pushes through, that breach is a catalyst on its own.

2

Elevated relative volume before the break

  • News brings attention; volume brings confirmation. Even without a headline, RVOL has to say big money is involved.
  • Going into Vince's session, full-day RVOL was running over two times normal.
  • Two or three times volume: real order flow. Pressing a monthly ceiling on half its normal volume: a trap.

If RVOL isn't elevated, that's a huge red flag. Maybe you don't stink at momentum trades. Maybe you just take them without a 9 and without volume.

3

A volume spike on the exact breakout bar

  • Look for the see-it moment: the instant the character of the stock changes in front of you.
  • ETHA printed normal volume all morning. The second it cleared 19.12, 1-minute volume went vertical.
  • That's buyers and short covering stepping all over each other.

Volume acceleration on top of a 9 out of 10 daily level is the trigger to get involved.

4

Read the tape to confirm the break

  • Buyers are aggressively paying the offer, and the offers clear without friction, easier than expected.
  • Pullbacks are remarkably shallow, on decreasing volume. Buyers step right back up.
  • It goes higher and faster than anyone expected.

Trades printing on the offer, not the bid, are aggressive accumulation. Big money doesn't just want it, it needs it.

5

Market tailwinds set the size

  • Ask what the most relevant ETF, index or related product is doing, and use it as an indicator.
  • Lined up with the breakout: green light for maximum conviction, A size.
  • Vince's day: SPY near the low end of its range, Bitcoin and Ethereum still in their ranges. So he started with B size.

When the breakout is isolated, respect the setup but control the first risk.

6

Set a clear stop

  • Get long as the level clears (19.13 and up). The stop goes under the low of the breakout candle, or the base right before the break.
  • A real breakout works almost immediately. If it creeps back under the multi-week level, the trade is dead: scratch it or take the planned loss.
  • Never park the stop on a round number like 10, 20 or 25 cents. Give it a penny more: 9, 14 or 24 cents.

That one extra penny keeps you out of a lot of random liquidity sweeps.

7

Be ready to add to the winner

  • When it doesn't come back down and holds higher, don't just sit on your hands.
  • Find the consolidation pauses on the 1-minute chart. Put buy stops just above the wick highs, where sellers stepped in for a moment.
  • Add into each new push, and trail the stop up to the low of the consolidation.

The adds go in only after the trade has proven itself, and each one comes with a tighter stop behind the whole position.

8

A defined exit. Don't negotiate.

  • Use one of three structural exits: a break of the prior 2-minute bar low, a breakdown of a clean consolidation, or a distinct shift on the tape.
  • After charging to 19.60, ETHA's tape changed: buyers stopped lifting offers, sellers hit the bids, and the velocity died. Vince flattened.
  • No shorting the top. Recognize the exhaustion and get out.

And if it never gets going at all, scratch it: flat at break even or a two-cent loss, not a full stop.

Score every level, 1 to 10

The habit SMB trains: every time you spot a level, grade it. Only the top of the scale is a trade.

9 – 10: trade it

A multi-week or multi-month ceiling on the daily chart that kept turning price away. The breach is the news.

6 – 7: pass

A level inside a sloppy range. Aggressive momentum on a mediocre level is how breakout traders get chopped up.

4: not a level

A random intraday squiggle. It doesn't belong anywhere near your size.

What kills it

Any one of these and there's no trade, a smaller one, or a scratch.

Not a 9

A 6 or 7 out of 10 level in a messy range. Mixing these in with the 9s and 10s is what turns results flat.

Under 9/10: skip it.

No RVOL

A monthly ceiling attempted on normal or half volume. There's no real order flow behind it.

Not elevated: red flag, no trade.

No volume on the bar

Price drifts through the level with nothing on the tape. No see-it moment, no change in character.

No spike: no trigger.

No velocity

You paid the new high and nothing happened. Bids soften, the tape dies. The reason you took it is gone.

Scratch it: flat at even or −2 cents.

The edge is the waiting

What Mike Bellafiore sees on the SMB floor: developing traders mix their 9 and 10 out of 10 breakouts with far too many 6s, 7s and frankly 4s. The morning fills up with paper cuts, the day ends flat or red, and the setup gets the blame. It isn't the setup. Sitting in your seat and waiting for only the best technical breakouts is the edge.

9 – 10

The only ones to take

Weeks or months of failures at one price on the higher timeframe. Clean chart, clear level, and the market is watching it too.

6 – 7

The chop machine

Looks like a breakout, sits inside a sloppy range. Taken with momentum size, these are the trades that bleed you.

4

Not a level at all

An intraday line drawn to have something to trade. Then the excuses start: breakouts don't work, it had no news.

Reading the tape on the break

This is what separates an active trader reading the tape from someone staring at candles. When ETHA took out 19.12, the tape showed all five.

01

Paying the offer

Buyers lift offers aggressively instead of waiting on the bid.

02

Offers clear easily

Size on the offer gets taken without friction, easier than you'd expect.

03

Shallow pullbacks

Dips are a few cents, not half a move. Buyers step right back up.

04

Lighter on the dips

Volume dries up on the pullbacks and comes back on the pushes.

05

Faster than expected

It goes higher, faster, than anyone expected. That's the move asking you to be in it.

A size, B size, or no trade?

Tick what's true about the breakout in front of you. The first four decide whether it's a trade at all; the market decides how big. It starts the way Vince's ETHA trade looked.

Stop blaming the setup

“Technical breakouts just don't work in this market.” “It didn't have a news catalyst, that's why it failed.” “I guess I just suck at breakouts.” No. Taking too many low-quality, undisciplined breakouts doesn't work.

Take only 9 and 10 out of 10 breakouts. That is the edge.

And don't paralyze yourself staring at an empty news feed when a 9 is breaking on heavy volume. Asking “where's the headline?” while it rips another 5% without you is its own mistake. As Brian Shannon puts it, only price pays.

Learn to scratch

To trade this with real size you have to be able to scratch. You pay a new high expecting instant momentum. If the velocity simply isn't there, the bids soften and the tape dies, get flat right away at break even or a two-cent loss. Don't sit there and take the full stop.

Exit 1: the 2-minute bar

Price breaks the low of the prior 2-minute bar. The push is over.

Exit 2: the consolidation

A clean consolidation that held breaks down. The base under the move is gone.

Exit 3: the tape

A distinct shift: buyers stop lifting, sellers hit the bids, upward velocity dies.

The two charts are illustrative. A scratch isn't a failure; it's what lets you take the next 9 out of 10 at full size.

A stop a penny past the round number

The stop goes under the low of the breakout candle. If that lands on a round number (any multiple of 5 cents), take one more penny. The default numbers are the walkthrough's, not Vince's fills, and the dollar risk is only an example.

  • .10 .20 .25round: where the sweeps go
  • .09 .14 .24one penny more
  • Back underthe level: the trade is dead

A real breakout works almost immediately

The structural stop is under the breakout candle or the base before the break. But you shouldn't need it often. If price creeps back under the multi-week level, the reason for the trade is gone.

Scratch it or take the planned loss. Never a bigger one.

B size here is half the A-size risk, just as an example. Vince started at B size because SPY, Bitcoin and Ethereum weren't helping, then added as the trade proved itself.

The trade in the video: ETHA

An SMB Capital intern, Vince, caught a higher-timeframe breakout in ETHA, the iShares Ethereum Trust, without a single news headline. The transcript reads the levels as 1912 and 1960; ETHA was trading around $19, so this page writes them as 19.12 and 19.60.

19.12

ETHA capped under it for over a month. Vince rated it a 9 out of 10, and Mike agreed.

2,550

Where Ethereum itself had been trapped for weeks. Four to five weeks of built-up energy.

2×+

Full-day relative volume going in. Then a vertical volume spike on the 1-minute bar that cleared 19.12.

B size

SPY near the low end of its range, BTC and ETH still in range. He added on the 1-minute pauses and flattened after the run to 19.60.

Vince's playbook presentation scored 83 out of 100; senior interns need 85. The points came off for formatting. The trading skill, Mike said, is gold: momentum off major technical levels is how SMB trained its original desk in 2005, and it's still the best skill builder for a developing trader. Like sprinting for a pitcher, it teaches you to think fast, read order flow, define risk precisely and control your emotions under pressure.

Long and short, side by side

The video trades the long. A breakdown under a multi-week floor works the same way, mirrored.

  Longthrough a multi-week ceiling Shortthrough a multi-week floor
The levelA 9/10 resistance it couldn't clear for weeksA 9/10 support it couldn't break for weeks
VolumeElevated RVOL going in, and a spike on the exact breakout bar
The tapePaying the offer, offers clear, shallow dipsHitting the bid, bids give way, shallow pops
SizeA size with the market and related ETF behind it; B size when it's on its own
Entrya cent through the levela cent through the level
StopUnder the breakout candle or base, a penny past the round numberOver the breakdown candle or base, a penny past the round number
AddBuy stops over the wick highs of each pause; trail to the pause lowSell stops under the wick lows of each pause; trail to the pause high
ExitPrior 2-minute bar low, a broken consolidation, or the tape turningPrior 2-minute bar high, a broken consolidation, or the tape turning
ScratchNo velocity after paying the new extreme: flat at even or two cents

The indicator

One TradingView script for the setup (Pine Script v6). It finds the multi-week level on the daily chart, checks RVOL and the breakout bar's volume, sizes by the market, and draws the stop, the adds and the exits on your 1-minute chart. It marks and alerts. It does not place trades.

technical-catalyst-breakout.pine · Pine Script v6
Download
//@version=6
// =====================================================================
// Technical Catalyst Breakout — thetrademethod.com
//
// SMB Capital's eight-step breakout blueprint for when there is no
// headline: the level IS the catalyst.
//
//   1. The level   The highest high (or lowest low) of the last N
//                  completed daily bars, tested several times and held
//                  for weeks. The panel shows the tests and the days.
//                  Whether it's a 9 out of 10 is still your call.
//   2. RVOL        Today's volume so far against what the stock has
//                  normally traded by this time of day (20 sessions).
//   3. The bar     The breakout bar's volume against the recent average.
//   4. The tape    Pine can't read the tape. Watch it yourself; the
//                  scratch rule below is the stand-in for "no velocity".
//   5. The market  A related symbol (SPY by default) above its VWAP for a
//                  long, below it for a short: A size. Otherwise B size.
//   6. The stop    Under the breakout candle (or the base before it), and
//                  a penny past any round number (multiples of 5 cents).
//   7. The add     A tight pause after the entry gets a buy stop a tick
//                  over its high; the stop trails to a tick under its low.
//   8. The exit    The trailing stop, a close back through the level, a
//                  break of the prior bars' low once the trade is paying,
//                  or a scratch when price hasn't moved after N bars.
//
// Use an intraday chart (1-minute in the video). Marks and alerts only;
// it places no orders.
// =====================================================================
indicator("Technical Catalyst Breakout", shorttitle = "Tech Catalyst BO", overlay = true, max_labels_count = 200, max_lines_count = 200)

// ---------------- inputs ----------------
side      = input.string("Long only", "Trade", options = ["Long only", "Short only", "Both"], group = "Setup",
     tooltip = "The video trades the long: a break above a multi-week ceiling. Short is the mirror: a break below a multi-week floor.")
lenD      = input.int(25, "Level lookback (daily bars)", minval = 5, maxval = 250, group = "1 · The level",
     tooltip = "25 trading days is about five weeks. The level is the highest high (or lowest low) of these completed days.")
tolPct    = input.float(0.3, "A test is within this % of the level", minval = 0.0, step = 0.05, group = "1 · The level")
minTests  = input.int(3, "Minimum tests", minval = 1, group = "1 · The level")
minDays   = input.int(15, "Minimum days the level has held", minval = 1, group = "1 · The level",
     tooltip = "Days since the oldest test inside the lookback. Weeks of failures is what makes the breach a catalyst.")

useRvol   = input.bool(true, "Require elevated RVOL", group = "2 · RVOL")
minRvol   = input.float(2.0, "Minimum RVOL", minval = 0.1, step = 0.1, group = "2 · RVOL")
lenRvol   = input.int(20, "RVOL average (sessions)", minval = 1, maxval = 60, group = "2 · RVOL")

useBarVol = input.bool(true, "Require a volume spike on the breakout bar", group = "3 · The breakout bar")
barVolX   = input.float(3.0, "Breakout bar volume ≥ this × average", minval = 1.0, step = 0.5, group = "3 · The breakout bar")
barVolLen = input.int(20, "…average of the previous N bars", minval = 2, group = "3 · The breakout bar")

useMkt    = input.bool(true, "Size by the market", group = "5 · The market",
     tooltip = "With the market (above its VWAP for a long, below for a short): A size. Against it or flat: B size.")
mktSym    = input.symbol("AMEX:SPY", "Market or related symbol", group = "5 · The market",
     tooltip = "SPY, the sector ETF, or the related product (for ETHA, Ethereum itself).")

stopMode  = input.string("Breakout candle", "Stop under", options = ["Breakout candle", "Base before the break"], group = "6 · The stop")
baseLen   = input.int(5, "Base: last N bars before the break", minval = 1, group = "6 · The stop")
usePenny  = input.bool(true, "A penny past round numbers", group = "6 · The stop")
roundStep = input.float(0.05, "Round number step", minval = 0.0, step = 0.01, group = "6 · The stop",
     tooltip = "A stop on a multiple of this (.05, .10, .25…) gets one more tick: .04 instead of .05.")

useAdds   = input.bool(true, "Mark adds over the pauses", group = "7 · The add")
maxAdds   = input.int(2, "Maximum adds", minval = 0, maxval = 5, group = "7 · The add")
pauseLen  = input.int(3, "A pause is N bars…", minval = 2, group = "7 · The add")
pauseAtr  = input.float(1.2, "…with a range of at most this × ATR(14)", minval = 0.1, step = 0.1, group = "7 · The add")

scratchN  = input.int(5, "Scratch: after N bars…", minval = 1, group = "8 · The exit")
scratchR  = input.float(0.5, "…if it never went this many R in your favor", minval = 0.0, step = 0.1, group = "8 · The exit")
useBarEx  = input.bool(true, "Exit on a break of the prior bars' low/high", group = "8 · The exit")
barExN    = input.int(2, "Prior bars", minval = 1, group = "8 · The exit", tooltip = "2 one-minute bars ≈ the prior 2-minute bar.")
barExR    = input.float(2.0, "…once the trade is at least this many R", minval = 0.0, step = 0.5, group = "8 · The exit")

showPanel = input.bool(true, "Show status panel", group = "Display")

// ---------------- colours ----------------
cLevel = #f4b942
cUp    = #30d158
cDn    = #ff453a
cAdd   = #22d3ee
cExit  = #ff9f0a
cDim   = #8e8e93
cBlue  = #2997ff

// ---------------- 1 · the level, from completed daily bars ----------------
dayLevels(float h, float l, int len, float tol) =>
    float hi = ta.highest(h, len)
    float lo = ta.lowest(l, len)
    int tu = 0
    int td = 0
    int au = 0
    int ad = 0
    for i = 0 to len - 1
        if h[i] >= hi * (1 - tol / 100)
            tu += 1
            au := i + 1
        if l[i] <= lo * (1 + tol / 100)
            td += 1
            ad := i + 1
    [hi, tu, au, lo, td, ad]

// high[1]/low[1] with lookahead on = the previous completed days only (no repainting)
[lvHi, testsHi, daysHi, lvLo, testsLo, daysLo] = request.security(syminfo.tickerid, "D", dayLevels(high[1], low[1], lenD, tolPct), lookahead = barmerge.lookahead_on)
bool qualHi = testsHi >= minTests and daysHi >= minDays
bool qualLo = testsLo >= minTests and daysLo >= minDays

// ---------------- 2 · cumulative RVOL by time of day ----------------
bool intra = timeframe.isintraday
int  tfSec = timeframe.in_seconds()
var int cols = intra ? int(math.ceil(86400.0 / tfSec)) : 1
int secOfDay = hour(time, syminfo.timezone) * 3600 + minute(time, syminfo.timezone) * 60 + second(time, syminfo.timezone)
int slot     = intra ? math.min(int(secOfDay / tfSec), cols - 1) : 0

var matrix<float> hist  = matrix.new<float>(0, cols, na)
var array<float>  today = array.new<float>(cols, na)
var float cum      = 0.0
var int   lastSlot = -1

fillSlots(array<float> a, int fromIdx, int toIdx, float v) =>
    if toIdx >= fromIdx
        for i = fromIdx to toIdx
            a.set(i, v)

avgAt(matrix<float> m, int c, int n) =>
    int rows = m.rows()
    int k    = math.min(n, rows)
    float sum = 0.0
    if k > 0
        for r = rows - k to rows - 1
            float x = m.get(r, c)
            sum += na(x) ? 0.0 : x
    k > 0 ? sum / k : na

float rvol = na
if intra
    if session.isfirstbar and lastSlot >= 0
        fillSlots(today, lastSlot + 1, cols - 1, cum)
        hist.add_row(hist.rows(), today.copy())
        if hist.rows() > lenRvol
            hist.remove_row(0)
        today.fill(na)
        cum      := 0.0
        lastSlot := -1
    float prevCum = cum
    cum += nz(volume)
    if lastSlot >= 0
        fillSlots(today, lastSlot + 1, slot - 1, prevCum)
    today.set(slot, cum)
    lastSlot := math.max(lastSlot, slot)
    float a = avgAt(hist, slot, lenRvol)
    rvol := a > 0 ? cum / a : na

// ---------------- 3 · breakout bar volume ----------------
float avgVol = ta.sma(volume, barVolLen)[1]
float volX   = avgVol > 0 ? volume / avgVol : na

// ---------------- 5 · the market ----------------
float mktClose = request.security(mktSym, timeframe.period, close)
float mktVwap  = request.security(mktSym, timeframe.period, ta.vwap(hlc3))

// ---------------- helpers ----------------
float tick = syminfo.mintick
// a stop for side d (1 long, -1 short) moved one more tick away when it lands on a round number
pennyPast(float p, int d) =>
    float q = math.round(p / syminfo.mintick) * syminfo.mintick
    bool isRound = roundStep > 0 and math.abs(q / roundStep - math.round(q / roundStep)) < 1e-6
    usePenny and isRound ? q - d * syminfo.mintick : q

float atr     = ta.atr(14)
float pHi     = ta.highest(high, pauseLen)[1]
float pLo     = ta.lowest(low, pauseLen)[1]
float baseLo  = ta.lowest(low, baseLen)[1]
float baseHi  = ta.highest(high, baseLen)[1]
float exLo    = ta.lowest(low, barExN)[1]
float exHi    = ta.highest(high, barExN)[1]

// ---------------- the trade ----------------
var int   pos      = 0        // 1 long, -1 short, 0 flat
var float lvl      = na
var float entry    = na
var float stop     = na
var float risk     = na
var int   entryBar = na
var int   lastAdd  = na
var int   adds     = 0
var float best     = na
var bool  usedHi   = false
var bool  usedLo   = false
var string lastMsg = "Waiting for a qualified level to break"

bool newDay = timeframe.change("D")
if newDay
    usedHi := false
    usedLo := false

bool allowLong  = side != "Short only"
bool allowShort = side != "Long only"
bool rvolOK = not useRvol or (not na(rvol) and rvol >= minRvol)
bool barOK  = not useBarVol or (not na(volX) and volX >= barVolX)

bool sigLong  = false
bool sigShort = false
bool sigAdd   = false
bool sigExit  = false
float exitPx  = na
string exitWhy = ""

// manage an open trade (from the bar after the entry)
if pos != 0 and bar_index > entryBar
    best := pos == 1 ? math.max(best, high) : math.min(best, low)
    float gainR = (best - entry) * pos / risk
    float nowR  = (close - entry) * pos / risk
    if (pos == 1 and low <= stop) or (pos == -1 and high >= stop)
        sigExit := true
        exitPx := stop
        exitWhy := adds > 0 ? "Trailing stop" : "Stop"
    else if (pos == 1 and close < lvl) or (pos == -1 and close > lvl)
        sigExit := true
        exitPx := close
        exitWhy := "Back through the level: dead"
    else if bar_index - entryBar == scratchN and gainR < scratchR
        sigExit := true
        exitPx := close
        exitWhy := "Scratch: no velocity"
    else if useBarEx and nowR >= barExR and ((pos == 1 and low < exLo) or (pos == -1 and high > exHi))
        sigExit := true
        exitPx := pos == 1 ? exLo - tick : exHi + tick
        exitWhy := "Prior bars broken"
    else if useAdds and adds < maxAdds and bar_index - pauseLen > entryBar and (na(lastAdd) or bar_index - pauseLen > lastAdd) and (pHi - pLo) <= pauseAtr * atr[1]
        bool trig = pos == 1 ? (high > pHi and pHi > entry) : (low < pLo and pLo < entry)
        if trig
            sigAdd  := true
            adds    += 1
            lastAdd := bar_index
            float trail = pos == 1 ? pennyPast(pLo - tick, 1) : pennyPast(pHi + tick, -1)
            stop := pos == 1 ? math.max(stop, trail) : math.min(stop, trail)
    if sigExit
        float r = (exitPx - entry) * pos / risk
        lastMsg := exitWhy + " · first unit " + (r >= 0 ? "+" : "") + str.tostring(r, "#.0") + "R"
        label.new(bar_index, pos == 1 ? high : low, exitWhy + "\n" + str.tostring(exitPx, format.mintick) + " · " + (r >= 0 ? "+" : "") + str.tostring(r, "#.0") + "R",
             style = pos == 1 ? label.style_label_down : label.style_label_up, color = cExit, textcolor = color.black, size = size.small)
        pos := 0

// a new breakout (flat, intraday, once per side per day)
if pos == 0 and intra and not sigExit
    bool upBreak = allowLong and not usedHi and qualHi and close > lvHi and open <= lvHi + atr
    bool dnBreak = allowShort and not usedLo and qualLo and close < lvLo and open >= lvLo - atr
    if upBreak or dnBreak
        int d = upBreak ? 1 : -1
        if d == 1
            usedHi := true
        else
            usedLo := true
        if rvolOK and barOK
            lvl   := d == 1 ? lvHi : lvLo
            entry := d == 1 ? (open > lvl ? open : lvl + tick) : (open < lvl ? open : lvl - tick)
            float raw = stopMode == "Breakout candle" ? (d == 1 ? low - tick : high + tick) : (d == 1 ? math.min(baseLo, low) - tick : math.max(baseHi, high) + tick)
            stop  := pennyPast(raw, d)
            risk  := (entry - stop) * d
            if risk > 0
                pos      := d
                entryBar := bar_index
                lastAdd  := na
                adds     := 0
                best     := d == 1 ? high : low
                bool withMkt = not useMkt or (d == 1 ? mktClose > mktVwap : mktClose < mktVwap)
                string sz = withMkt ? "A size" : "B size"
                sigLong  := d == 1
                sigShort := d == -1
                lastMsg  := (d == 1 ? "Long " : "Short ") + str.tostring(entry, format.mintick) + " · stop " + str.tostring(stop, format.mintick) + " · " + sz
                label.new(bar_index, d == 1 ? low : high,
                     (d == 1 ? "BREAKOUT · " : "BREAKDOWN · ") + sz + "\nEntry " + str.tostring(entry, format.mintick) + "  Stop " + str.tostring(stop, format.mintick) +
                     "\nRVOL " + (na(rvol) ? "—" : str.tostring(rvol, "#.0") + "x") + " · bar " + (na(volX) ? "—" : str.tostring(volX, "#.0") + "x"),
                     style = d == 1 ? label.style_label_up : label.style_label_down, color = d == 1 ? cUp : cDn, textcolor = color.black, size = size.small)
        else
            lastMsg := "Level broke without " + (not rvolOK ? "elevated RVOL" : "a volume spike") + ": no trade"
            label.new(bar_index, d == 1 ? high : low, "No trade: " + (not rvolOK ? "RVOL" : "bar volume"),
                 style = d == 1 ? label.style_label_down : label.style_label_up, color = color.new(cDim, 30), textcolor = color.white, size = size.tiny)

if sigAdd
    float addPx = pos == 1 ? pHi + tick : pLo - tick
    lastMsg := "Add " + str.tostring(addPx, format.mintick) + " · stop to " + str.tostring(stop, format.mintick)
    label.new(bar_index, pos == 1 ? low : high, "ADD " + str.tostring(addPx, format.mintick), style = pos == 1 ? label.style_label_up : label.style_label_down,
         color = cAdd, textcolor = color.black, size = size.tiny)

// ---------------- plots ----------------
plot(intra and allowLong ? lvHi : na, "Level (ceiling)", color = qualHi ? cLevel : color.new(cDim, 40), linewidth = 2, style = plot.style_stepline)
plot(intra and allowShort ? lvLo : na, "Level (floor)", color = qualLo ? cLevel : color.new(cDim, 40), linewidth = 2, style = plot.style_stepline)
plot(pos != 0 ? entry : na, "Entry", color = color.white, style = plot.style_linebr)
plot(pos != 0 ? stop : na, "Stop", color = cDn, linewidth = 2, style = plot.style_linebr)

// ---------------- status panel ----------------
var table tb = table.new(position.top_right, 2, 7, bgcolor = color.new(#1d1d1f, 10), border_width = 0)
cell(int r, string k, string v, color c) =>
    table.cell(tb, 0, r, k, text_color = #a1a1a6, text_size = size.small, text_halign = text.align_left)
    table.cell(tb, 1, r, v, text_color = c, text_size = size.small, text_halign = text.align_left)
if showPanel and barstate.islast
    bool showHi = allowLong
    float lv = showHi ? lvHi : lvLo
    int   ts = showHi ? testsHi : testsLo
    int   ds = showHi ? daysHi : daysLo
    bool  q  = showHi ? qualHi : qualLo
    cell(0, showHi ? "Ceiling" : "Floor", str.tostring(lv, format.mintick), cLevel)
    cell(1, "Tests · days held", str.tostring(ts) + " · " + str.tostring(ds), q ? cUp : cDim)
    cell(2, "RVOL (time of day)", na(rvol) ? (intra ? "building history" : "intraday only") : str.tostring(rvol, "#.00") + "x", rvolOK ? cUp : cDim)
    cell(3, "This bar's volume", na(volX) ? "—" : str.tostring(volX, "#.0") + "x avg", barOK ? cUp : cDim)
    cell(4, "Market", useMkt ? (mktClose > mktVwap ? "above VWAP" : "below VWAP") : "off", cBlue)
    cell(5, "Trade", pos == 1 ? "Long" : pos == -1 ? "Short" : "Flat", pos == 0 ? color.white : pos == 1 ? cUp : cDn)
    cell(6, "Last", lastMsg, color.white)

// ---------------- alerts ----------------
alertcondition(sigLong and barstate.isconfirmed, "Breakout long", "{{ticker}} cleared its multi-week level on elevated RVOL and a volume spike — technical catalyst breakout")
alertcondition(sigShort and barstate.isconfirmed, "Breakdown short", "{{ticker}} broke its multi-week floor on elevated RVOL and a volume spike — technical catalyst breakdown")
alertcondition(sigAdd and barstate.isconfirmed, "Add over the pause", "{{ticker}} cleared a pause — add, and trail the stop to the pause")
alertcondition(sigExit and barstate.isconfirmed, "Exit", "{{ticker}} technical catalyst trade: exit signal (stop, back through the level, scratch, or prior bars broken)")

Watch the video

Mike Bellafiore of SMB Capital walks through the eight-step blueprint on an intern's ETHA breakout, with no news behind it.

Open on YouTube ›

The level is the news.

Stop waiting for someone on TV or Twitter to hand you a headline. Look at the longer-term charts, find the 9 out of 10 levels, and practice the eight steps on a demo until the trade is in your playbook. One good trade, then one good trade, then one good trade.

  • Only 9 and 10 out of 10 levels, on elevated RVOL.
  • A volume spike on the bar and a tape paying the offer, or no entry.
  • Size to the market, stop a penny past the round number, add over the pauses.
  • Exit on a defined signal, and scratch when the velocity isn't there.

From an SMB Capital video by Mike Bellafiore (ETHA breakout traded by an SMB intern). The ETHA and Ethereum levels, the RVOL and the B size are as told in the video. The walkthrough, the two charts and the calculator's default numbers are illustrative, made-up bars, not ETHA's actual prints.