TRENDTROOPER
Signal Service
Features Live Chart Markets Pricing Full Chart Analysis Screener Academy Tools Pine Scripts Live Bot Trading Get Started
Free Indicators

Pine Scripts Library

Thirteen free TradingView indicators, each built around one specific Humbled Trader setup — VWAP reclaims, gap plays, dip buys, support/resistance, and risk sizing. Copy the code or download the file and drop it straight into the Pine Editor.

VWAP
VWAP Compass

VWAP reclaim longs, rejection shorts, and a short-trap warning for stocks faking out below VWAP on low volume.

//@version=6
indicator("VWAP Compass", overlay = true)

// ============================================================================
// VWAP COMPASS
// Based on Humbled Trader — "VWAP Trading Strategy Crash Course"
// Her rules implemented here:
//  • VWAP is the only price indicator she keeps on the chart (plus volume).
//  • Above VWAP = bullish (buyers control), below = bearish (sellers control).
//  • VWAP RECLAIM LONG: stock breaks below VWAP, then reclaims it midday
//    (~10:30–13:00) while printing higher lows with increasing buy volume.
//  • VWAP REJECTION SHORT: stock keeps retesting VWAP from below and failing,
//    with increasing sell volume — likely to fade all day.
//  • SHORT-TRAP WARNING: higher lows forming BELOW VWAP around lunch on LOW
//    volume — algos shaking out longs before a squeeze through VWAP.
//  • Never place stops right at VWAP — give it room (she warns a single wick
//    can take you out).
// ============================================================================

showReclaim = input.bool(true,  "Show VWAP reclaim longs")
showReject  = input.bool(true,  "Show VWAP rejection shorts")
showTrap    = input.bool(true,  "Show short-trap warnings")
volLen      = input.int(13,     "Volume MA length", minval = 2)
minBarsBelow= input.int(4,      "Min bars below VWAP before a reclaim", minval = 1)
tzNY        = "America/New_York"

vwapLine = ta.vwap(hlc3)
volMa    = ta.sma(volume, volLen)

inSession = not na(time(timeframe.period, "0930-1600", tzNY))
inMidday  = not na(time(timeframe.period, "1030-1300", tzNY))

above = close > vwapLine
below = close < vwapLine

var int belowCount = 0
belowCount := above ? 0 : belowCount + 1

// --- VWAP reclaim long: was below for a while, crosses and holds above with volume
higherLow  = low > low[1]
reclaimSig = showReclaim and inSession and above and not above[1] and belowCount[1] >= minBarsBelow and volume > volMa and higherLow

// --- VWAP rejection short: tags VWAP from below, closes red below it, sell volume expanding
rejectSig = showReject and inSession and below and below[1] and high >= vwapLine and close < open and volume > volMa

// --- Short-trap warning: higher pivot lows below VWAP, midday, volume drying up
pl        = ta.pivotlow(low, 2, 2)
var float lastPl  = na
var float prevPl  = na
if not na(pl)
    prevPl := lastPl
    lastPl := pl
trapSig = showTrap and inMidday and below and not na(lastPl) and not na(prevPl) and lastPl > prevPl and volume < volMa

plot(vwapLine, "VWAP", color = color.new(color.blue, 0), linewidth = 2)

plotshape(reclaimSig, "VWAP Reclaim Long", shape.triangleup,   location.belowbar, color.new(color.green,  0), text = "RECLAIM", textcolor = color.green,  size = size.small)
plotshape(rejectSig,  "VWAP Reject Short", shape.triangledown, location.abovebar, color.new(color.red,    0), text = "REJECT",  textcolor = color.red,    size = size.small)
plotshape(trapSig,    "Short Trap Risk",   shape.xcross,       location.belowbar, color.new(color.orange, 0), text = "TRAP?",   textcolor = color.orange, size = size.tiny)

bgcolor(above ? color.new(color.green, 96) : color.new(color.red, 96))

alertcondition(reclaimSig, "VWAP Reclaim Long",  "VWAP Compass: midday VWAP reclaim with higher lows + volume — long setup")
alertcondition(rejectSig,  "VWAP Rejection Short","VWAP Compass: failed VWAP retest with sell volume — short setup")
alertcondition(trapSig,    "Short Trap Warning", "VWAP Compass: higher lows below VWAP on low midday volume — possible short trap / squeeze")
Download
Reversal
Golden Window Reversal

Flags the 10:30–11:00am morning sell-off reversal window on uptrending stocks above their daily 200 SMA.

//@version=6
indicator("Golden Window Reversal", overlay = true)

// ============================================================================
// GOLDEN WINDOW REVERSAL
// Based on Humbled Trader — "Price Action Trading Strategy Extended Crash Course"
// Her rules implemented here:
//  • Zoom out first: the DAILY trend is your best friend. Above the daily
//    200 SMA = bullish big picture; below = bearish.
//  • Her "golden reversal time frame": 10:30–11:00 AM ET is when morning
//    sell-offs on strong stocks tend to reverse (v-shape recovery).
//  • Entry: first red day / morning sell-off on an uptrending large cap with
//    no bearish news → wait for the 5-min downtrend to break with a higher
//    low inside the golden window, then trade the reversal long.
//  • Long wicks at highs = sellers stepping in (resistance); long wicks at
//    lows = dip buyers (support).
//  • Front side vs back side: above the daily key level + VWAP = front side
//    (don't short); below both = back side (don't buy breakouts).
// ============================================================================

tzNY     = "America/New_York"
wickMult = input.float(2.0, "Wick vs body multiple for wick signals", step = 0.25)
useTrend = input.bool(true, "Require daily 200 SMA uptrend for longs")

daily200 = request.security(syminfo.tickerid, "D", ta.sma(close, 200))
vwapLine = ta.vwap(hlc3)

inGolden  = not na(time(timeframe.period, "1030-1100", tzNY))
inSession = not na(time(timeframe.period, "0930-1600", tzNY))

dailyBull = close > daily200

// --- Morning downtrend into the window: lower lows since the open
var float openPx   = na
var bool  soldOff  = false
newDay = ta.change(time("D")) != 0
if newDay
    openPx  := open
    soldOff := false
if inSession and close < openPx * 0.995
    soldOff := true

// --- Golden-window reversal: higher low + close over prior bar high inside window
higherLow   = low > low[1] and low[1] <= low[2]
reversalSig = inGolden and soldOff and higherLow and close > high[1] and close > vwapLine and (not useTrend or dailyBull)

// --- Wick reads
body      = math.abs(close - open)
upWick    = high - math.max(close, open)
dnWick    = math.min(close, open) - low
sellWick  = inSession and upWick > body * wickMult and volume > ta.sma(volume, 13)
buyWick   = inSession and dnWick > body * wickMult and volume > ta.sma(volume, 13)

// --- Front side / back side vs VWAP
frontSide = close > vwapLine and dailyBull
backSide  = close < vwapLine and not dailyBull

plot(vwapLine, "VWAP", color.new(color.blue, 0), 2)
plot(daily200, "Daily 200 SMA", color.new(color.orange, 0), 2)

plotshape(reversalSig, "Golden Window Reversal", shape.labelup, location.belowbar, color.new(color.green, 0), text = "GOLDEN\nREV", textcolor = color.white, size = size.small)
plotshape(sellWick, "Seller Wick", shape.triangledown, location.abovebar, color.new(color.red,   40), size = size.tiny)
plotshape(buyWick,  "Buyer Wick",  shape.triangleup,   location.belowbar, color.new(color.green, 40), size = size.tiny)

bgcolor(inGolden ? color.new(color.yellow, 88) : na, title = "Golden reversal window")
bgcolor(backSide ? color.new(color.red, 95) : frontSide ? color.new(color.green, 97) : na)

alertcondition(reversalSig, "Golden Window Reversal", "Golden Window Reversal: 10:30–11:00 higher-low reversal over VWAP on a daily-uptrend stock")
alertcondition(sellWick, "Seller Wick at Highs", "Golden Window Reversal: heavy upper wick — sellers stepping in")
Download
Dip Buy
Dip Snapper

Marks the first green 5-min candle after a red sell-off into an established support zone on an uptrending stock.

//@version=6
indicator("Dip Snapper", overlay = true)

// ============================================================================
// DIP SNAPPER
// Based on Humbled Trader — "BUY THE DIP — Learn This Profitable Trading
// Strategy in 20Mins"
// Her four criteria implemented here:
//  1. Stock is UPTRENDING on the daily chart with multiple tested support
//     levels (works on anything > $500M market cap).
//  2. Price dips into an established support zone and forms a reversal:
//     the FIRST GREEN 5-MIN CANDLE after multiple red sell-off candles.
//  3. Market is stabilizing/uptrending, not selling off all day (use your
//     own read — this script flags the stock-side setup).
//  4. No heavily negative news (manual check).
//  • Risk: about $1–1.50 below the support / prior day low on a high-beta
//    name. Target: VWAP, then premarket highs — aim for 1:3 or better.
//  • Don't catch the falling knife: the green-candle confirmation IS the entry.
// ============================================================================

minRedBars = input.int(3,  "Min consecutive red candles before the dip buy", minval = 2)
supLookback= input.int(20, "Support lookback (bars)", minval = 5)
supTolPct  = input.float(0.3, "Support touch tolerance (%)", step = 0.1)
riskDollars= input.float(1.0, "Risk below entry ($) for stop line", step = 0.25)

vwapLine  = ta.vwap(hlc3)
daily200  = request.security(syminfo.tickerid, "D", ta.sma(close, 200))
prevLow   = request.security(syminfo.tickerid, "D", low[1])
pmHighSrc = high

// Prior-day low and rolling support: lowest low of the lookback, excluding current bar
support   = ta.lowest(low[1], supLookback)
nearSup   = low <= support * (1 + supTolPct / 100)

dailyBull = close > daily200

var int redRun = 0
redRun := close < open ? redRun + 1 : 0

greenCandle = close > open
firstGreen  = greenCandle and redRun[1] >= minRedBars

dipBuy = firstGreen and nearSup[1] and dailyBull

// --- Stop & target guides drawn at signal
var line stopLn = na
var line tgtLn  = na
if dipBuy
    line.delete(stopLn)
    line.delete(tgtLn)
    stopLn := line.new(bar_index, close - riskDollars, bar_index + 20, close - riskDollars, color = color.red,   style = line.style_dashed)
    tgtLn  := line.new(bar_index, vwapLine,            bar_index + 20, vwapLine,            color = color.green, style = line.style_dashed)

plot(vwapLine, "VWAP", color.new(color.blue, 0), 2)
plot(daily200, "Daily 200 SMA", color.new(color.orange, 30), 1)
plot(support,  "Rolling support", color.new(color.teal, 40), 1, plot.style_linebr)

plotshape(dipBuy, "Dip Buy", shape.labelup, location.belowbar, color.new(color.green, 0), text = "DIP\nBUY", textcolor = color.white, size = size.small)

alertcondition(dipBuy, "Dip Snapper Buy", "Dip Snapper: first green candle after a multi-red sell-off into tested support on a daily uptrend — buy-the-dip setup (check market + news)")
Download
Support/Resistance
Level Keeper

Auto-plots horizontal support/resistance zones from swing highs and lows with 3+ contact points.

//@version=6
indicator("Level Keeper", overlay = true, max_lines_count = 60, max_labels_count = 60)

// ============================================================================
// LEVEL KEEPER
// Based on Humbled Trader — "Support & Resistance Didn't Work Until I
// Learned This Strategy"
// Her rules implemented here:
//  • Find the most OBVIOUS price levels: extreme highs, extreme lows, and
//    V / W shapes on the chart.
//  • A horizontal line needs at least THREE contact points to matter — the
//    more touches, the more significant the level.
//  • Levels are ZONES, never exact to the cent; whole-dollar numbers matter
//    psychologically, so levels are optionally snapped toward round numbers.
//  • Volume is your guide: a break of a key level on above-average volume is
//    a real break; low volume breaks are suspect.
//  • Prior resistance, once broken out of, becomes new support (and vice
//    versa). Wait for 1–2 retests before trading a level.
// ============================================================================

pivLen    = input.int(5,  "Pivot strength (bars each side)", minval = 2)
minTouches= input.int(3,  "Min touches for a valid level", minval = 2)
zonePct   = input.float(0.4, "Zone tolerance (%)", step = 0.1)
maxLevels = input.int(8,  "Max levels drawn", minval = 2, maxval = 20)
volLen    = input.int(14, "Volume MA length")

volMa = ta.sma(volume, volLen)
ph = ta.pivothigh(high, pivLen, pivLen)
pl = ta.pivotlow(low,  pivLen, pivLen)

var array<float> lvls    = array.new_float()
var array<int>   touches = array.new_int()

f_addLevel(float px) =>
    tol = px * zonePct / 100
    int hit = -1
    int n = array.size(lvls)
    if n > 0
        for i = 0 to n - 1
            if math.abs(array.get(lvls, i) - px) <= tol
                hit := i
                break
    if hit >= 0
        array.set(touches, hit, array.get(touches, hit) + 1)
        array.set(lvls, hit, (array.get(lvls, hit) + px) / 2)
    else
        array.push(lvls, px)
        array.push(touches, 1)
        if array.size(lvls) > 40
            array.shift(lvls)
            array.shift(touches)

if not na(ph)
    f_addLevel(ph)
if not na(pl)
    f_addLevel(pl)

// --- Draw the strongest levels
var array<line> drawn = array.new_line()
if barstate.islast and array.size(lvls) > 0
    while array.size(drawn) > 0
        line.delete(array.pop(drawn))
    int shown = 0
    for i = array.size(lvls) - 1 to 0
        if shown < maxLevels and array.get(touches, i) >= minTouches
            px = array.get(lvls, i)
            ln = line.new(math.max(0, bar_index - 100), px, bar_index + 10, px, color = px > close ? color.new(color.red, 30) : color.new(color.green, 30), width = 2)
            array.push(drawn, ln)
            shown += 1

// --- Volume-confirmed break of nearest level
float nearest = na
if array.size(lvls) > 0
    float best = 1e10
    for i = 0 to array.size(lvls) - 1
        if array.get(touches, i) >= minTouches
            d = math.abs(array.get(lvls, i) - close)
            if d < best
                best := d
                nearest := array.get(lvls, i)

breakUp = not na(nearest) and close > nearest and close[1] <= nearest and volume > volMa
breakDn = not na(nearest) and close < nearest and close[1] >= nearest and volume > volMa

plotshape(breakUp, "Volume Breakout",  shape.triangleup,   location.belowbar, color.new(color.green, 0), text = "BRK", textcolor = color.green, size = size.tiny)
plotshape(breakDn, "Volume Breakdown", shape.triangledown, location.abovebar, color.new(color.red,   0), text = "BRK", textcolor = color.red,   size = size.tiny)

alertcondition(breakUp, "Level break UP on volume",   "Level Keeper: key level broken to the upside on above-average volume — prior resistance may become support")
alertcondition(breakDn, "Level break DOWN on volume", "Level Keeper: key level broken to the downside on above-average volume — prior support may become resistance")
Download
Scalping
Scalp Sentinel

Flags failed breakouts/breakdowns at key daily levels for the technical-bounce scalp, gated by above-average volume.

//@version=6
indicator("Scalp Sentinel", overlay = true)

// ============================================================================
// SCALP SENTINEL
// Based on Humbled Trader — "Scalping Trading Strategy — Secrets to
// Increase Daily Profits" (the "technical bounce / failed breakout" scalp)
// Her three golden criteria implemented here:
//  1. Above-average trading volume, intraday AND on the daily.
//  2. A breakout or breakdown at a KEY daily level.
//  3. Intraday price action that CONFIRMS the break or rejection.
//  • Chart setup she uses: VWAP + volume bars with a 13-period volume moving
//    average. 5-min for consolidation, 2-min for fast movers.
//  • Short entry: a FAILED breakout at the key level → short the small
//    bounces back toward the level / VWAP (never short into weakness at
//    support). Risk = key level + slippage; targets = prior intraday supports.
//  • Long side is the mirror image: a failed breakdown.
// ============================================================================

volLen   = input.int(13, "Volume MA length", minval = 2)
keyLook  = input.int(30, "Key-level lookback (bars)", minval = 10)
rvolMin  = input.float(1.5, "Min relative volume on trigger bars", step = 0.1)
tzNY     = "America/New_York"

vwapLine = ta.vwap(hlc3)
volMa    = ta.sma(volume, volLen)
rvol     = volume / volMa

inSession = not na(time(timeframe.period, "0930-1600", tzNY))

// Key intraday levels: highest high / lowest low of the lookback (excluding current bar)
keyHi = ta.highest(high[1], keyLook)
keyLo = ta.lowest(low[1],  keyLook)

// --- Failed breakout: pokes above key high, closes back below it, red, on volume
failedBreakout  = inSession and high > keyHi and close < keyHi and close < open and rvol >= rvolMin

// --- Failed breakdown: pokes below key low, closes back above it, green, on volume
failedBreakdown = inSession and low < keyLo and close > keyLo and close > open and rvol >= rvolMin

// --- Bounce-short entry: after a failed breakout, price bounces back toward VWAP and stalls
var bool shortBias = false
var bool longBias  = false
if failedBreakout
    shortBias := true
    longBias  := false
if failedBreakdown
    longBias  := true
    shortBias := false
if close > keyHi
    shortBias := false
if close < keyLo
    longBias := false

bounceShort = inSession and shortBias and close < vwapLine and high >= vwapLine * 0.999 and close < open
bounceLong  = inSession and longBias  and close > vwapLine and low  <= vwapLine * 1.001 and close > open

plot(vwapLine, "VWAP", color.new(color.blue, 0), 2)
plot(keyHi, "Key high", color.new(color.red,   50), 1, plot.style_linebr)
plot(keyLo, "Key low",  color.new(color.green, 50), 1, plot.style_linebr)

plotshape(failedBreakout,  "Failed Breakout",  shape.xcross, location.abovebar, color.new(color.red,   0), text = "FAIL", textcolor = color.red,   size = size.tiny)
plotshape(failedBreakdown, "Failed Breakdown", shape.xcross, location.belowbar, color.new(color.green, 0), text = "FAIL", textcolor = color.green, size = size.tiny)
plotshape(bounceShort, "Scalp Short (bounce)", shape.triangledown, location.abovebar, color.new(color.red,   0), text = "SCALP", textcolor = color.red,   size = size.small)
plotshape(bounceLong,  "Scalp Long (bounce)",  shape.triangleup,   location.belowbar, color.new(color.green, 0), text = "SCALP", textcolor = color.green, size = size.small)

alertcondition(failedBreakout,  "Failed breakout",  "Scalp Sentinel: failed breakout at key level on volume — watch for bounce shorts toward VWAP")
alertcondition(failedBreakdown, "Failed breakdown", "Scalp Sentinel: failed breakdown at key level on volume — watch for bounce longs toward VWAP")
alertcondition(bounceShort, "Scalp short entry", "Scalp Sentinel: bounce toward VWAP stalling after failed breakout — scalp short setup")
alertcondition(bounceLong,  "Scalp long entry",  "Scalp Sentinel: dip toward VWAP holding after failed breakdown — scalp long setup")
Download
Trendlines
Trendline Weaver

Auto-draws uptrend/downtrend trendlines from extreme swing pivots with at least 3 contact points.

//@version=6
indicator("Trendline Weaver", overlay = true, max_lines_count = 20, max_labels_count = 100)

// ============================================================================
// TRENDLINE WEAVER
// Based on Humbled Trader — "Trendline Trading Strategy — 3 SIMPLE STEPS
// To Improve Profitability"
// Her rules implemented here:
//  • Uptrend = higher highs AND higher lows; downtrend = lower lows AND
//    lower highs. Label them so the trend is never in doubt.
//  • A trendline needs at least THREE contact points — the more, the better.
//  • Draw from EXTREME highs and lows (the V and upside-down-V pivots that
//    stand out), not every wiggle.
//  • Check multiple time frames (she flips daily ↔ weekly) — run this on any
//    chart resolution.
//  • The trend is your best friend: don't be "fundamentally right but
//    technically wrong". Respect your stop when the line breaks.
// ============================================================================

pivLen = input.int(5, "Pivot strength (bars each side)", minval = 2)
showHL = input.bool(true, "Label HH / HL / LH / LL")

ph = ta.pivothigh(high, pivLen, pivLen)
pl = ta.pivotlow(low,  pivLen, pivLen)

var float lastPh = na
var float prevPh = na
var int lastPhBar = na
var int prevPhBar = na
var float lastPl = na
var float prevPl = na
var int lastPlBar = na
var int prevPlBar = na

if not na(ph)
    prevPh    := lastPh
    prevPhBar := lastPhBar
    lastPh    := ph
    lastPhBar := bar_index - pivLen
    if showHL and not na(prevPh)
        label.new(lastPhBar, ph, lastPh > prevPh ? "HH" : "LH", style = label.style_label_down, color = lastPh > prevPh ? color.new(color.green, 20) : color.new(color.red, 20), textcolor = color.white, size = size.tiny)

if not na(pl)
    prevPl    := lastPl
    prevPlBar := lastPlBar
    lastPl    := pl
    lastPlBar := bar_index - pivLen
    if showHL and not na(prevPl)
        label.new(lastPlBar, pl, lastPl > prevPl ? "HL" : "LL", style = label.style_label_up, color = lastPl > prevPl ? color.new(color.green, 20) : color.new(color.red, 20), textcolor = color.white, size = size.tiny)

// --- Auto trendlines from the last two extreme pivots, extended right
var line upTl = na
var line dnTl = na

if not na(lastPl) and not na(prevPl) and lastPl > prevPl
    line.delete(upTl)
    upTl := line.new(prevPlBar, prevPl, lastPlBar, lastPl, extend = extend.right, color = color.new(color.green, 0), width = 2)

if not na(lastPh) and not na(prevPh) and lastPh < prevPh
    line.delete(dnTl)
    dnTl := line.new(prevPhBar, prevPh, lastPhBar, lastPh, extend = extend.right, color = color.new(color.red, 0), width = 2)

// --- Trend state + line-break alerts
upTrend = not na(lastPl) and not na(prevPl) and not na(lastPh) and not na(prevPh) and lastPl > prevPl and lastPh > prevPh
dnTrend = not na(lastPl) and not na(prevPl) and not na(lastPh) and not na(prevPh) and lastPl < prevPl and lastPh < prevPh

f_lineVal(line ln) =>
    na(ln) ? na : line.get_price(ln, bar_index)

upVal = f_lineVal(upTl)
dnVal = f_lineVal(dnTl)

upBreak = not na(upVal) and close < upVal and close[1] >= upVal
dnBreak = not na(dnVal) and close > dnVal and close[1] <= dnVal

plotshape(upBreak, "Uptrend line broken",   shape.triangledown, location.abovebar, color.new(color.red,   0), text = "TL BREAK", textcolor = color.red,   size = size.small)
plotshape(dnBreak, "Downtrend line broken", shape.triangleup,   location.belowbar, color.new(color.green, 0), text = "TL BREAK", textcolor = color.green, size = size.small)

bgcolor(upTrend ? color.new(color.green, 96) : dnTrend ? color.new(color.red, 96) : na)

alertcondition(upBreak, "Uptrend line break",   "Trendline Weaver: price closed below the rising trendline — trend may be ending, respect your stop")
alertcondition(dnBreak, "Downtrend line break", "Trendline Weaver: price closed above the falling trendline — possible trend reversal")
Download
Gap Trading
Gap Navigator

Marks premarket high/low, key daily resistance, and VWAP breakdown levels for catalyst-driven gap-up and gap-down setups.

//@version=6
indicator("Gap Navigator", overlay = true)

// ============================================================================
// GAP NAVIGATOR
// Based on Humbled Trader — "GAP UP TRADING STRATEGY — Golden Setup To
// Become Profitable" (+ "How To Trade Gap Up and Gap Down Strategy")
// Her rules implemented here (large caps, catalyst-driven gaps):
//  GAP-UP LONG:
//   • Overnight gap up OVER a key daily resistance (best: 52-week-high area)
//     with a positive catalyst (earnings beat — manual check).
//   • Entry 1: pullback to the key level (± ~50c risk).
//   • Entry 2: break of the PREMARKET HIGH — then buy dips above it.
//   • Stop: 5-min VWAP breakdown. Sell into each daily resistance above.
//  GAP-DOWN SHORT:
//   • Gap down BELOW key daily support (worst: 52-week-low break) on a
//     bearish catalyst → short the small bounces toward VWAP / broken level.
// Requires an intraday chart with Extended Hours ON for premarket levels.
// ============================================================================

gapMinPct = input.float(2.0, "Min overnight gap (%)", step = 0.5)
tzNY      = "America/New_York"

prevClose = request.security(syminfo.tickerid, "D", close[1])
vwapLine  = ta.vwap(hlc3)

newDay = ta.change(time("D")) != 0

// --- Track premarket high/low and today's open gap
var float pmHigh  = na
var float pmLow   = na
var float dayOpen = na
var bool  gapUp   = false
var bool  gapDown = false

if newDay
    pmHigh := na
    pmLow  := na
    gapUp  := false
    gapDown:= false

if session.ispremarket
    pmHigh := na(pmHigh) ? high : math.max(pmHigh, high)
    pmLow  := na(pmLow)  ? low  : math.min(pmLow, low)

firstRTH = session.ismarket and (session.ispremarket[1] or newDay)
if firstRTH
    dayOpen := open
    gapUp   := open >= prevClose * (1 + gapMinPct / 100)
    gapDown := open <= prevClose * (1 - gapMinPct / 100)

// --- Signals
pmhBreak   = session.ismarket and gapUp and not na(pmHigh) and close > pmHigh and close[1] <= pmHigh and close > vwapLine
gapUpDip   = session.ismarket and gapUp and not na(pmHigh) and close > pmHigh and low <= pmHigh and close > open
gapDnBounce= session.ismarket and gapDown and close < vwapLine and high >= vwapLine * 0.999 and close < open
vwapStop   = session.ismarket and (gapUp and close < vwapLine and close[1] >= vwapLine)

plot(vwapLine,  "VWAP",           color.new(color.blue,   0), 2)
plot(prevClose, "Prior day close",color.new(color.gray,  40), 1, plot.style_linebr)
plot(pmHigh,    "Premarket high", color.new(color.green, 30), 1, plot.style_linebr)
plot(pmLow,     "Premarket low",  color.new(color.red,   30), 1, plot.style_linebr)

plotshape(pmhBreak,    "Gap-Up: PMH break",     shape.triangleup,   location.belowbar, color.new(color.green, 0), text = "PMH\nBRK",  textcolor = color.green,  size = size.small)
plotshape(gapUpDip,    "Gap-Up: dip entry",     shape.circle,       location.belowbar, color.new(color.teal,  0), text = "DIP",       textcolor = color.teal,   size = size.tiny)
plotshape(gapDnBounce, "Gap-Down: bounce short",shape.triangledown, location.abovebar, color.new(color.red,   0), text = "SHORT",     textcolor = color.red,    size = size.small)
plotshape(vwapStop,    "VWAP stop",             shape.xcross,       location.abovebar, color.new(color.orange,0), text = "STOP",      textcolor = color.orange, size = size.tiny)

bgcolor(gapUp ? color.new(color.green, 97) : gapDown ? color.new(color.red, 97) : na)

alertcondition(pmhBreak,    "Gap-up PMH breakout", "Gap Navigator: gap-up stock breaking premarket highs above VWAP — long trigger (verify catalyst)")
alertcondition(gapDnBounce, "Gap-down bounce short","Gap Navigator: gap-down stock stalling at VWAP — short-the-bounce trigger")
alertcondition(vwapStop,    "VWAP breakdown stop", "Gap Navigator: VWAP lost — her stop for the gap-up long")
Download
Short Setup
Bagholder Bear

Flags the small-cap "bag holder" short trigger — the first green-to-red day after a multi-day downtrending run.

//@version=6
indicator("Bagholder Bear", overlay = true)

// ============================================================================
// BAGHOLDER BEAR
// Based on Humbled Trader — "How I Made $2200 in 30 Minutes using this
// Entry Technique" (her "bag holder short" for small caps)
// Her rules implemented here:
//  • Universe (set your scanner, manual): small cap < $800M, low float,
//    gap > 10%, high volume, long-term downtrending "bag holder" daily chart
//    with clear supply/resistance overhead (reverse splits, dilution common).
//  • Don't short day 1 of a strong-catalyst run. The edge is DAY 2 / DAY 3:
//    wait for the FIRST RED DAY.
//  • Trigger: GREEN-TO-RED move — price loses the prior day's close.
//    Confirmation: break of premarket low / key whole-dollar level.
//  • Risk: the daily resistance overhead / premarket high. Add on weak
//    bounces that fail at VWAP with declining bounce volume.
//  • Targets: the prior daily supports the run came from (they usually give
//    most of it back).
// Requires an intraday chart with Extended Hours ON.
// ============================================================================

tzNY = "America/New_York"

prevClose = request.security(syminfo.tickerid, "D", close[1])
prevHigh  = request.security(syminfo.tickerid, "D", high[1])
vwapLine  = ta.vwap(hlc3)
volMa     = ta.sma(volume, 13)

newDay = ta.change(time("D")) != 0

var float pmHigh = na
var float pmLow  = na
if newDay
    pmHigh := na
    pmLow  := na
if session.ispremarket
    pmHigh := na(pmHigh) ? high : math.max(pmHigh, high)
    pmLow  := na(pmLow)  ? low  : math.min(pmLow, low)

// --- Green-to-red: losing the prior day close during regular hours
greenToRed = session.ismarket and close < prevClose and close[1] >= prevClose

// --- Premarket-low break confirmation
pmlBreak = session.ismarket and not na(pmLow) and close < pmLow and close[1] >= pmLow

// --- Weak bounce add: below VWAP, tags it, fails, bounce volume below average
weakBounce = session.ismarket and close < vwapLine and high >= vwapLine * 0.998 and close < open and volume < volMa

// --- Squeeze-risk warning: reclaiming VWAP from below (cover signal)
vwapReclaim = session.ismarket and close > vwapLine and close[1] <= vwapLine

plot(vwapLine,  "VWAP",            color.new(color.blue,  0), 2)
plot(prevClose, "Prior day close", color.new(color.gray, 30), 1, plot.style_linebr)
plot(pmHigh,    "Premarket high (risk)", color.new(color.red,   30), 1, plot.style_linebr)
plot(pmLow,     "Premarket low (trigger)", color.new(color.orange, 30), 1, plot.style_linebr)

plotshape(greenToRed,  "Green-to-Red", shape.triangledown, location.abovebar, color.new(color.red,    0), text = "G→R",   textcolor = color.red,    size = size.small)
plotshape(pmlBreak,    "PM-low break", shape.triangledown, location.abovebar, color.new(color.maroon, 0), text = "PML",   textcolor = color.maroon, size = size.tiny)
plotshape(weakBounce,  "Weak bounce add", shape.circle,    location.abovebar, color.new(color.orange, 0), text = "ADD",   textcolor = color.orange, size = size.tiny)
plotshape(vwapReclaim, "Cover warning",   shape.xcross,    location.belowbar, color.new(color.green,  0), text = "COVER", textcolor = color.green,  size = size.tiny)

alertcondition(greenToRed,  "Green-to-red trigger", "Bagholder Bear: stock went red vs prior close — first-red-day short trigger (day 2/3 runners only)")
alertcondition(pmlBreak,    "Premarket low break",  "Bagholder Bear: premarket low broken — breakdown confirmation")
alertcondition(vwapReclaim, "VWAP reclaim — cover", "Bagholder Bear: VWAP reclaimed from below — squeeze risk, consider covering")
Download
Volume
Volume Prophet

Volume moving average + relative volume (RVOL) panel to confirm breakouts and breakdowns are backed by real volume.

//@version=6
indicator("Volume Prophet", overlay = false, format = format.volume)

// ============================================================================
// VOLUME PROPHET
// Based on Humbled Trader — "Trading won't work if you don't know THIS
// Volume Analysis Indicator"
// Her rules implemented here:
//  • Two tools: a VOLUME MOVING AVERAGE (she uses ~14 periods) over the
//    volume bars, and RELATIVE VOLUME (RVOL) — current vs average.
//  • Momentum traders want RVOL ≥ 2–3; small-cap runners print hundreds of
//    percent. High RVOL = range, momentum, and liquidity.
//  • VOLUME BREAKOUT: volume holding ABOVE its average sustains a move —
//    breakouts on shrinking volume tend to fail.
//  • VOLUME BREAKDOWN: expanding volume on a support break = real selling.
//  • REVERSAL CLUE (swing entries): after a multi-day rout, wait for selling
//    volume to SUBSIDE back under the average (~1/4–1/5 of panic volume),
//    then look for the first green-day breakout.
// ============================================================================

volLen  = input.int(14,  "Volume MA length", minval = 2)
rvolHot = input.float(2.0, "Hot RVOL threshold", step = 0.5)
calmPct = input.float(30.0, "Volume-subsided threshold (% of recent peak)", step = 5)

volMa = ta.sma(volume, volLen)
rvol  = volume / volMa

isUp = close >= open
volColor = volume > volMa ? (isUp ? color.new(color.green, 0) : color.new(color.red, 0)) : (isUp ? color.new(color.green, 60) : color.new(color.red, 60))

plot(volume, "Volume", volColor, style = plot.style_columns)
plot(volMa,  "Volume MA", color.new(color.orange, 0), 2)

// --- Signals
volBreakout  = volume > volMa * rvolHot and isUp
volBreakdown = volume > volMa * rvolHot and not isUp

peakVol   = ta.highest(volume, volLen * 2)
subsided  = volume < peakVol * calmPct / 100 and volume < volMa
reversalWatch = subsided and isUp and not isUp[1]

plotshape(volBreakout,   "Volume breakout",  shape.triangleup,   location.top, color.new(color.green,  0), size = size.tiny)
plotshape(volBreakdown,  "Volume breakdown", shape.triangledown, location.top, color.new(color.red,    0), size = size.tiny)
plotshape(reversalWatch, "Reversal watch",   shape.diamond,      location.top, color.new(color.yellow, 0), size = size.tiny)

// --- RVOL readout
var table t = table.new(position.top_right, 1, 2)
if barstate.islast
    table.cell(t, 0, 0, "RVOL: " + str.tostring(rvol, "#.##") + "x", text_color = color.white, bgcolor = rvol >= rvolHot ? color.new(color.green, 20) : color.new(color.gray, 20))
    table.cell(t, 0, 1, rvol >= rvolHot ? "In play" : "Quiet", text_color = color.white, bgcolor = color.new(color.black, 40))

alertcondition(volBreakout,   "Volume breakout",  "Volume Prophet: buying volume breaking out above average — move has fuel")
alertcondition(volBreakdown,  "Volume breakdown", "Volume Prophet: selling volume breaking out — real distribution")
alertcondition(reversalWatch, "Volume subsided",  "Volume Prophet: panic volume has subsided under the average with a green candle — reversal watch for swing entry")
Download
Index/Large Cap
Index Tide Rider

Daily-support dip-buy and trend-join setups tuned for SPY/QQQ and the large caps that follow them.

//@version=6
indicator("Index Tide Rider", overlay = true)

// ============================================================================
// INDEX TIDE RIDER
// Based on Humbled Trader — "Best Futures Trading Strategy for Beginners"
// (SPY / QQQ / ES / NQ and the large caps that follow them)
// Two setups implemented here:
//  1. DAILY SUPPORT DIP-BUY (panic gap-down reversal):
//     • Market-wide gap down to a key daily support (macro panic, no
//       stock-specific bad news), after MULTIPLE down days.
//     • Do NOT catch the falling knife: wait for price to hold/reclaim the
//       key level, reclaim VWAP with higher lows and a volume surge —
//       reversals cluster in her 10:00–11:00 "golden reversal period".
//  2. TREND-JOIN LONG (continuation):
//     • Market breaking out (not chopping sideways), instrument holding
//       ABOVE PREMARKET HIGHS after 10:00 AM, riding VWAP / 8 EMA, with
//       room to the next daily resistance. Trail rather than top-tick.
// Requires an intraday chart with Extended Hours ON.
// ============================================================================

tzNY   = "America/New_York"
gapPct = input.float(0.75, "Min gap down for dip-buy setup (%)", step = 0.25)

prevClose = request.security(syminfo.tickerid, "D", close[1])
vwapLine  = ta.vwap(hlc3)
ema8      = ta.ema(close, 8)
volMa     = ta.sma(volume, 13)

newDay = ta.change(time("D")) != 0

var float pmHigh = na
var float pmLow  = na
var bool  gapDn  = false
if newDay
    pmHigh := na
    pmLow  := na
    gapDn  := false
if session.ispremarket
    pmHigh := na(pmHigh) ? high : math.max(pmHigh, high)
    pmLow  := na(pmLow)  ? low  : math.min(pmLow, low)

firstRTH = session.ismarket and (session.ispremarket[1] or newDay)
if firstRTH
    gapDn := open <= prevClose * (1 - gapPct / 100)

inGolden = not na(time(timeframe.period, "1000-1100", tzNY))
after10  = not na(time(timeframe.period, "1000-1600", tzNY))

// --- Setup 1: dip-buy reversal — VWAP reclaim with higher low + volume in the window
higherLow = low > low[1]
dipBuy = session.ismarket and gapDn and inGolden and close > vwapLine and close[1] <= vwapLine and higherLow and volume > volMa

// --- Setup 2: trend-join long — holding above premarket high after 10:00, riding VWAP/8EMA
trendJoin = session.ismarket and after10 and not na(pmHigh) and close > pmHigh and close > vwapLine and close > ema8 and low <= ema8 * 1.001 and close > open

// --- Trail warning
trailWarn = session.ismarket and close < vwapLine and close[1] >= vwapLine

plot(vwapLine, "VWAP",  color.new(color.blue,   0), 2)
plot(ema8,     "8 EMA", color.new(color.purple, 0), 1)
plot(pmHigh,   "Premarket high", color.new(color.green, 40), 1, plot.style_linebr)
plot(pmLow,    "Premarket low",  color.new(color.red,   40), 1, plot.style_linebr)

plotshape(dipBuy,    "Dip-Buy Reversal", shape.labelup,    location.belowbar, color.new(color.green, 0), text = "DIP\nBUY",  textcolor = color.white, size = size.small)
plotshape(trendJoin, "Trend-Join Long",  shape.triangleup, location.belowbar, color.new(color.teal,  0), text = "JOIN",      textcolor = color.teal,  size = size.small)
plotshape(trailWarn, "VWAP lost",        shape.xcross,     location.abovebar, color.new(color.orange,0), size = size.tiny)

bgcolor(inGolden ? color.new(color.yellow, 92) : na, title = "Golden reversal period")

alertcondition(dipBuy,    "Dip-buy reversal",  "Index Tide Rider: gap-down day VWAP reclaim with higher low + volume in the golden window — dip-buy setup")
alertcondition(trendJoin, "Trend-join long",   "Index Tide Rider: holding above premarket highs after 10:00, riding VWAP/8EMA — trend-join entry")
alertcondition(trailWarn, "VWAP lost",         "Index Tide Rider: VWAP breakdown — tighten or exit")
Download
Risk Mgmt
Risk Architect

On-chart position size and reward-to-risk calculator so every trade risks a fixed, consistent slice of the account.

//@version=6
indicator("Risk Architect", overlay = true)

// ============================================================================
// RISK ARCHITECT
// Based on Humbled Trader — "Risk Management & Position Sizing Strategy
// for Trading" (+ the risk calculator from her swing-trading video)
// Her rules implemented here:
//  • Risk a FIXED slice of the account per trade: ~1% (conservative) up to
//    3–5% only for experienced aggressive swing trades.
//  • Shares = (account × risk%) ÷ (entry − stop). Keep risk constant on
//    every ticker — never "1,000 shares of everything".
//  • Minimum reward-to-risk of 1:2; aim for 1:3+ to be profitable even at a
//    40% win rate.
//  • Stops go at technical daily key levels (not right at VWAP), targets at
//    the next daily resistance/support.
//  • Her discipline rules: stop trading after ~11:30 AM if that's where you
//    bleed, and stop the day if you give back 30% of your profits.
// Set your entry & stop below; the table sizes the trade and draws 1R/2R/3R.
// ============================================================================

acctSize = input.float(10000, "Account size ($)", minval = 100, step = 500)
riskPct  = input.float(1.0,   "Risk per trade (%)", minval = 0.1, maxval = 10, step = 0.25)
entryPx  = input.price(0.0,   "Entry price (0 = use current close)")
stopPx   = input.price(0.0,   "Stop price (0 = 2% under entry)")
isLong   = input.bool(true,   "Long trade? (off = short)")

eff_entry = entryPx > 0 ? entryPx : close
eff_stop  = stopPx  > 0 ? stopPx  : (isLong ? eff_entry * 0.98 : eff_entry * 1.02)

riskPerShare = math.abs(eff_entry - eff_stop)
maxRiskUsd   = acctSize * riskPct / 100
shares       = riskPerShare > 0 ? math.floor(maxRiskUsd / riskPerShare) : 0

dir = isLong ? 1 : -1
t1  = eff_entry + dir * riskPerShare        // 1R
t2  = eff_entry + dir * riskPerShare * 2    // 2R
t3  = eff_entry + dir * riskPerShare * 3    // 3R

// --- Lines
var line eLn = na
var line sLn = na
var line t2Ln = na
var line t3Ln = na
if barstate.islast
    line.delete(eLn)
    line.delete(sLn)
    line.delete(t2Ln)
    line.delete(t3Ln)
    eLn  := line.new(bar_index - 30, eff_entry, bar_index + 10, eff_entry, color = color.new(color.blue,  0), width = 2)
    sLn  := line.new(bar_index - 30, eff_stop,  bar_index + 10, eff_stop,  color = color.new(color.red,   0), width = 2, style = line.style_dashed)
    t2Ln := line.new(bar_index - 30, t2,        bar_index + 10, t2,        color = color.new(color.green,30), width = 1, style = line.style_dashed)
    t3Ln := line.new(bar_index - 30, t3,        bar_index + 10, t3,        color = color.new(color.green, 0), width = 2, style = line.style_dashed)

// --- Table
var table t = table.new(position.top_right, 2, 7, border_width = 1)

f_row(int r, string k, string v, color bg) =>
    table.cell(t, 0, r, k, text_color = color.white, bgcolor = color.new(color.black, 20), text_halign = text.align_left)
    table.cell(t, 1, r, v, text_color = color.white, bgcolor = bg, text_halign = text.align_right)

if barstate.islast
    f_row(0, "Max risk",      "$" + str.tostring(maxRiskUsd, "#.##") + " (" + str.tostring(riskPct, "#.#") + "%)", color.new(color.red, 30))
    f_row(1, "Risk / share",  "$" + str.tostring(riskPerShare, "#.##"), color.new(color.gray, 30))
    f_row(2, "Position size", str.tostring(shares) + " sh", color.new(color.blue, 20))
    f_row(3, "Entry",         str.tostring(eff_entry, format.mintick), color.new(color.blue, 40))
    f_row(4, "Stop",          str.tostring(eff_stop, format.mintick), color.new(color.red, 40))
    f_row(5, "2R target",     str.tostring(t2, format.mintick) + "  (+$" + str.tostring(maxRiskUsd * 2, "#") + ")", color.new(color.green, 40))
    f_row(6, "3R target",     str.tostring(t3, format.mintick) + "  (+$" + str.tostring(maxRiskUsd * 3, "#") + ")", color.new(color.green, 20))

// --- 11:30 AM discipline reminder
tzNY = "America/New_York"
lateWindow = not na(time(timeframe.period, "1130-1135", tzNY))
plotshape(lateWindow and not lateWindow[1], "11:30 discipline check", shape.flag, location.abovebar, color.new(color.orange, 0), text = "11:30", textcolor = color.orange, size = size.tiny)

alertcondition(lateWindow and not lateWindow[1], "11:30 AM check-in", "Risk Architect: it's 11:30 ET — her rule: if this is where you give profits back, you're done for the day")
Download
Swing Trading
Swing Catalyst

Event-driven swing setup for catalyst gap-ups on stocks holding their daily 200 SMA and 8 EMA.

//@version=6
indicator("Swing Catalyst", overlay = true)

// ============================================================================
// SWING CATALYST
// Based on Humbled Trader — "Simple Part-Time SWING TRADING STRATEGY"
// (her event-driven swing setup, demonstrated on the NVDA earnings gap)
// Her rules implemented here:
//  • Scan: gap up ≥ 3% with heavy premarket dollar volume, market cap
//    > $800M (no small-cap swings), and a FORWARD-LOOKING bullish catalyst:
//    earnings beat + raised guidance, sector hype, or IPO hype (manual).
//  • Daily chart must be in an uptrend: above the 200 SMA AND riding the
//    8 EMA (with a history of reclaiming it). Gapping to new all-time highs
//    = no overhead resistance = extra bullish. Never short all-time highs.
//  • Entry: day-one break of the PREMARKET HIGH (buy the VWAP pullback
//    after the break). Stop: premarket LOW (she prefers it over low-of-day).
//  • Manage: sell 1/10th partials into strength, judge the hold on the
//    15-min / hourly / daily — aim for 3–5R over multiple days.
// Requires an intraday chart with Extended Hours ON (daily signals shown too).
// ============================================================================

gapMin = input.float(3.0, "Min gap up (%)", step = 0.5)

prevClose = request.security(syminfo.tickerid, "D", close[1])
daily200  = request.security(syminfo.tickerid, "D", ta.sma(close, 200))
daily8    = request.security(syminfo.tickerid, "D", ta.ema(close, 8))
vwapLine  = ta.vwap(hlc3)

dailyBull = close > daily200 and close > daily8

newDay = ta.change(time("D")) != 0
var float pmHigh = na
var float pmLow  = na
var bool  bigGap = false
if newDay
    pmHigh := na
    pmLow  := na
    bigGap := false
if session.ispremarket
    pmHigh := na(pmHigh) ? high : math.max(pmHigh, high)
    pmLow  := na(pmLow)  ? low  : math.min(pmLow, low)

firstRTH = session.ismarket and (session.ispremarket[1] or newDay)
if firstRTH
    bigGap := open >= prevClose * (1 + gapMin / 100)

// --- Entry: PMH break on a gap day with a bullish daily chart
pmhBreak = session.ismarket and bigGap and dailyBull and not na(pmHigh) and close > pmHigh and close[1] <= pmHigh

// --- Add: VWAP pullback holding after the break
vwapPull = session.ismarket and bigGap and dailyBull and not na(pmHigh) and close > pmHigh and low <= vwapLine * 1.001 and close > vwapLine and close > open

// --- Stop: premarket low lost
stopHit = session.ismarket and bigGap and not na(pmLow) and close < pmLow and close[1] >= pmLow

// --- Daily trail: 8 EMA lost (swing exit warning)
trailWarn = ta.crossunder(close, daily8)

plot(vwapLine, "VWAP",        color.new(color.blue,   0), 2)
plot(daily8,   "Daily 8 EMA", color.new(color.purple, 0), 2)
plot(daily200, "Daily 200 SMA", color.new(color.orange, 30), 1)
plot(pmHigh,   "Premarket high (entry)", color.new(color.green, 30), 1, plot.style_linebr)
plot(pmLow,    "Premarket low (stop)",   color.new(color.red,   30), 1, plot.style_linebr)

plotshape(pmhBreak,  "Swing entry (PMH break)", shape.labelup,    location.belowbar, color.new(color.green, 0), text = "SWING", textcolor = color.white,  size = size.small)
plotshape(vwapPull,  "Add on VWAP pullback",    shape.circle,     location.belowbar, color.new(color.teal,  0), text = "ADD",   textcolor = color.teal,   size = size.tiny)
plotshape(stopHit,   "Stop (PM low lost)",      shape.xcross,     location.abovebar, color.new(color.red,   0), text = "STOP",  textcolor = color.red,    size = size.small)
plotshape(trailWarn, "8 EMA lost",              shape.triangledown,location.abovebar, color.new(color.orange,0), text = "8EMA",  textcolor = color.orange, size = size.tiny)

alertcondition(pmhBreak,  "Swing entry",  "Swing Catalyst: gap-day premarket-high break on a bullish daily chart — event-driven swing entry (verify the catalyst!)")
alertcondition(stopHit,   "Swing stop",   "Swing Catalyst: premarket low lost — her stop for the event-driven swing")
alertcondition(trailWarn, "Daily 8 EMA lost", "Swing Catalyst: closed under the daily 8 EMA — swing trail warning")
Download
Gap Reversal
Morning Phoenix

The gapper-reversal long: buys premarket-VWAP-holding pullbacks on huge overnight gap-ups with a bullish catalyst.

//@version=6
indicator("Morning Phoenix", overlay = true)

// ============================================================================
// MORNING PHOENIX
// Based on Humbled Trader — "The Most Consistently Profitable Trading
// Strategy" (her A+ setup: the GAPPER REVERSAL LONG, e.g. DDOG & SNOW)
// Her three golden criteria implemented here:
//  1. HUGE overnight gap up (5%+) on a large/mid cap.
//  2. Strong positive catalyst — ideally an earnings beat on all metrics
//     (manual check).
//  3. Very bullish daily chart — gapping OVER the daily resistance levels.
//  • The stock should already be trending up premarket and holding its
//    premarket VWAP after any early pullback.
//  • You are NOT buying the high-of-day breakout. You buy the PULLBACKS:
//    dips to premarket VWAP / the key premarket support that hold, then you
//    SELL INTO the breakouts at the next daily resistance.
//  • Risk ≥ $1 on high-beta names; upside is the reclaimed trend (1:3+).
// Requires an intraday chart with Extended Hours ON.
// ============================================================================

gapMin = input.float(5.0, "Min overnight gap (%)", step = 0.5)

prevClose = request.security(syminfo.tickerid, "D", close[1])
vwapLine  = ta.vwap(hlc3)
volMa     = ta.sma(volume, 13)

newDay = ta.change(time("D")) != 0
var float pmHigh = na
var float pmLow  = na
var bool  bigGap = false
if newDay
    pmHigh := na
    pmLow  := na
    bigGap := false
if session.ispremarket
    pmHigh := na(pmHigh) ? high : math.max(pmHigh, high)
    pmLow  := na(pmLow)  ? low  : math.min(pmLow, low)

firstRTH = session.ismarket and (session.ispremarket[1] or newDay)
if firstRTH
    bigGap := open >= prevClose * (1 + gapMin / 100)

// --- Pullback buy: gap day, dip tags VWAP, holds, closes green above it
pullbackBuy = session.ismarket and bigGap and low <= vwapLine * 1.002 and close > vwapLine and close > open and volume > volMa

// --- Wick-bought confirmation: lower wick bought back up near VWAP (her bullish tell)
body   = math.abs(close - open)
dnWick = math.min(close, open) - low
wickBuy = session.ismarket and bigGap and dnWick > body and close > vwapLine and low <= vwapLine * 1.005

// --- Sell-into-strength: breaking the premarket high (scale out, don't chase)
pmhTest = session.ismarket and bigGap and not na(pmHigh) and close > pmHigh and close[1] <= pmHigh

// --- Invalidation: losing VWAP after the open
vwapLost = session.ismarket and bigGap and close < vwapLine and close[1] >= vwapLine

plot(vwapLine, "VWAP", color.new(color.blue, 0), 2)
plot(pmHigh, "Premarket high (sell zone)", color.new(color.green, 30), 1, plot.style_linebr)
plot(pmLow,  "Premarket low",              color.new(color.red,   40), 1, plot.style_linebr)
plot(prevClose, "Prior day close", color.new(color.gray, 50), 1, plot.style_linebr)

plotshape(pullbackBuy, "Pullback buy",   shape.labelup,     location.belowbar, color.new(color.green, 0), text = "BUY\nDIP", textcolor = color.white,  size = size.small)
plotshape(wickBuy,     "Wick bought up", shape.triangleup,  location.belowbar, color.new(color.teal, 20), size = size.tiny)
plotshape(pmhTest,     "Scale out",      shape.labeldown,   location.abovebar, color.new(color.orange, 0), text = "SELL\nSTR", textcolor = color.white, size = size.tiny)
plotshape(vwapLost,    "VWAP lost",      shape.xcross,      location.abovebar, color.new(color.red,    0), size = size.tiny)

bgcolor(bigGap ? color.new(color.green, 97) : na)

alertcondition(pullbackBuy, "Gapper pullback buy", "Morning Phoenix: big-gap stock holding VWAP on a pullback with volume — her A+ gapper reversal entry (verify catalyst)")
alertcondition(pmhTest,     "Scale into strength", "Morning Phoenix: premarket high breaking — scale out into strength at resistance")
alertcondition(vwapLost,    "VWAP lost",           "Morning Phoenix: VWAP lost on the gap day — setup invalidated")
Download

How to use these

  1. Click Copy Code on any script above (or download the .pine file).
  2. Open any chart on TradingView and go to Pine Editor at the bottom of the screen.
  3. Click OpenNew blank indicator, select all the placeholder code, and paste.
  4. Click Save, then Add to chart. All scripts are indicators (not strategies) — they plot signals, they don't place trades on their own.