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 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")
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")
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)")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
.pine file).