Let's talk
gold August 19, 2026 · 16 min read

Gold Desk — 2026-08-19: Coiled Under $4,400, Waiting on Minutes

Gold is trading 4,355 into London, down 1.03% intraday after a 100-point session flush from 4,431 to 4,326. The tape says "yield surge, oil-led risk-off," but the macro underneath — TIPS real yield at 2.41% and down 3bp, DXY sinking to 99.49, Fed odds still 70% hold into September — reads as a mild bullish setup being fought by a bearish 1h/4h trend break. Investing.com's aggregate flashes Strong Buy on the daily; my own 1h read is defensive. Tonight's FOMC minutes at 21:00 UTC are the pivot: the day is coiling right on daily EMA200 (4,347) and inside the golden pocket of the session swing. I fade the bounce into 4,366–4,391 with an invalidation just above R1, and I buy the reversion if we get flushed into 4,266–4,301.


Gold is trading 4,355 into London, down 1.03% intraday after a 100-point session flush from 4,431 to 4,326. The tape says "yield surge, oil-led risk-off," but the macro underneath — TIPS real yield at 2.41% and down 3bp, DXY sinking to 99.49, Fed odds still 70% hold into September — reads as a mild bullish setup being fought by a bearish 1h/4h trend break. Investing.com's aggregate flashes Strong Buy on the daily; my own 1h read is defensive. Tonight's FOMC minutes at 21:00 UTC are the pivot: the day is coiling right on daily EMA200 (4,347) and inside the golden pocket of the session swing. I fade the bounce into 4,366–4,391 with an invalidation just above R1, and I buy the reversion if we get flushed into 4,266–4,301.

The session

Spot PAXG prints 4,355.67 into the London handover, off 1.03% on the day and -0.56% on the week — but still up 6.72% on the month, which is the number to hold in mind before anyone calls this a top. The session drove from an overnight high at 4,430.88 to a European-morning low at 4,326.38, a 104.5-point range, and has since retraced roughly 28% of that leg into the pivots. Investing.com's own headline this morning — "Gold coils near $4,400 in tight range" — is stale by the print; we broke lower. Their follow-up — "Gold falls over 1.5%, weighed down by elevated Treasury yields, higher oil prices" — is the driver of record. WTI at $84.54 and 10y nominal at 4.71% (up 6bp on the 24h ^TNX print) are the excuse; the deeper macro (below) does not fully agree.

Multi-timeframe read

The four timeframes disagree in a way that matters:

  • 15m is bullish and clean: RSI 58.8, MACD hist +1.45 and rising, price +7.2 above EMA20, +4.9 above EMA50. The very-short-term tape has already bounced.
  • 1h has flipped: RSI 46.6, price 0.6 below EMA20 and 15 below EMA50. MACD histogram is negative but ticking up — a would-be reversal but not confirmed.
  • 4h is the bearish anchor: RSI 42.3, price 18.9 below EMA20, MACD hist -5.03. This is the trend timeframe intraday and it says "sell rallies until we reclaim."
  • Daily is still constructive: RSI 58.9, price +8.5 above EMA200 (4,347.13) and +59 above EMA20. But daily MACD histogram just rolled to -0.26 and is turning down — the first daily tell of exhaustion.

The synthesis: an oversold intraday bounce is likely, but it is a bounce into a broken 1h/4h structure with daily EMA200 as the last line of defense at 4,347. Reclaim the 4h EMA20 (4,374.60) with a close and the picture flips; fail there and the daily rollover accelerates.

Macro frame

Lead with the real yield. The US 10y TIPS real yield sits at 2.41%, down 3bp day-over-day — this is a mild tailwind for gold, because real yields are the primary bullion driver and lower is better. The 10y nominal is 4.71% (essentially flat d/d, -1bp) and the 10y breakeven inflation rose 2bp to 2.30%; the composition — falling real, rising inflation compensation — is exactly what gold likes. The intraday headlines blaming "elevated Treasury yields" are looking at the ^TNX intraday print (+6bp), not the underlying decomposition.

The Fed-odds path corroborates: September 16 FOMC is priced 70% hold, 30% hike, 0% cut. That is a modestly hawkish distribution, but not a cutting path either. A path that leans "hold and stall" is neutral-to-mildly-positive for real yields; a hawkish minutes-driven repricing to a 40%+ hike odds tonight would lift real yields and hit gold hard. That is the tail risk for the long side.

The dollar is unambiguously soft: DXY 99.49, -0.39% on the day, sitting on its daily EMA200 (99.38) with daily RSI at 36.4 and 1h RSI at 30.3 — oversold. DXY↔XAU 30-day daily-return correlation is -0.27, mild but the right sign; a DXY bounce off 99.38 would clip gold, but the setup looks like sellers are exhausted, not reloading. Cross-asset: VIX 15.83 (calm, no risk-off), GVZ 23.98 (gold-vol elevated — the market IS pricing a move around minutes), gold/silver at 69.0 with silver $63.13 (a PM-regime that still favours the metals as a group), BTC $64,237 (no digital-gold rotation visible). No non-US central-bank print of note today except Lagarde speaks twice — background noise unless she surprises.

Bottom line on macro: real-yield vector says buy dips; Fed-odds path says respect the hike tail; DXY behaviour says a bounce is due. Net: mildly constructive but binary into minutes.

Two scenarios

Note: conviction values are honest qualitative reads, not back-tested probabilities.

Sell setup — bounce-fade into the golden pocket

  • Trigger: 15m/1h close back below 4,366 (daily P) after a tag of 4,378–4,391 (fib 0.5–0.618 golden pocket / weekly P at 4,377.09).
  • Invalidation: hourly close above 4,401.23 (daily R1).
  • Target: 4,301.20 (daily S1), stretch 4,266.01 (daily S2 / AB=CD projection).
  • Conviction: 60%.
  • Rationale: 4h EMA20 (4,374.60) plus weekly P (4,377.09) plus fib 0.5 (4,378.63) plus fib 0.618 (4,390.96) plus daily R1 (4,401.23) build a wall of confluence between 4,375 and 4,401. 4h MACD/RSI already broken. The bounce is a mechanical retrace, not a trend reversal, unless it CLOSES through.

Buy setup — reversion at demand

  • Trigger: flush into 4,266–4,301 followed by a 15m close back above 4,301.20 (daily S1) with RSI turn.
  • Invalidation: hourly close below 4,257 (below S1/S2 shelf and 24h low buffer).
  • Target: 4,377.09 (weekly P), stretch 4,401.23 (daily R1).
  • Conviction: 45%.
  • Rationale: Daily EMA200 (4,347) is 8 points above current; if it fails, the next demand pocket is daily S1–S2 (4,266–4,301), which coincides with the AB=CD D-leg at ~4,272. Real yield trajectory and DXY oversold argue for a mean-reversion buy after capitulation. Lower conviction because it requires two events: the flush AND the reclaim.

Levels worth marking

Working the pivots into a laddered map:

  • Upside: 4,366.04 (daily P) → 4,377.09 (weekly P) → 4,401.23 (daily R1, first real resistance) → 4,430.88 (session high) → 4,446.26 (weekly R1) → 4,466.07 (daily R2).
  • Downside: 4,347.13 (daily EMA200 — the key line) → 4,326.38 (session low) → 4,311.24 (weekly S1) → 4,301.20 (daily S1) → 4,266.01 (daily S2) → 4,242.07 (weekly S2).
  • Confluence highlights: 4,375–4,391 (weekly P + 4h EMA20 + fib 0.5–0.618 golden pocket) is THE sell wall. 4,347–4,326 (daily EMA200 + session low) is THE first buyable shelf. 4,266–4,301 (daily S1–S2) is the deep-reversion pocket where the D-leg lands.

Independent cross-check: investing.com's daily aggregate reads Strong Buy — their MA composite is Sell but their overall signal skews long. That disagrees with my 1h/4h defensive read; the resolution is timeframe — their read is daily-swing, mine is intraday. Worth noting because if the daily holds EMA200 into minutes, their read wins.

Calendar / catalysts

Live from the pre-fetched ForexFactory tape:

  • Wed 09:00 GBP CPI y/y — printed 2.9% vs 2.9% forecast (prev 2.6%). Hot vs prior, in line with expectations. Sterling shrug, muted spillover to metals. Already out.
  • Wed 10:10 & 13:15 EUR — ECB President Lagarde Speaks (medium impact). Both windows are during London/NY overlap; a hawkish surprise lifts EUR, drags DXY, marginal gold positive.
  • Wed 21:00 USD — FOMC Meeting Minutes (high impact). The day's whole binary sits here. A hawkish tilt (more hike talk, dissent) rerates the 30% hike odds up, drives real yields, sells gold through the 4,326 session low. A dovish tilt (hold-and-cut framing) collapses real yields, buys gold back above 4,401.
  • Wed 21:30 USD — President Trump Speaks (medium). Headline-risk tail; usually a dollar mover.
  • Prior CAD CPI print (Aug 17) was hot: 0.5% m/m vs 0.4% — noise for gold, mostly a CAD story.

Sources cited

Snapshot: PAXG spot, GC=F front-month, ^TNX for 10y nominal, Treasury.gov TIPS for the 10y real yield, DXY for the dollar, VIX/GVZ/silver/WTI/BTC for the cross-asset frame, CME FedWatch-implied fed-funds odds for the policy path. Text/analysis: investing.com (headlines and technical aggregate), onewordnews (kitco, dailyfx excerpts), ForexFactory (calendar). CFTC COT unavailable this run — no positioning read; do not read into speculator flow this note.

Desk summary & bias

Gold is coiled at 4,355, sitting exactly on daily EMA200 (4,347) with the 4h in a broken trend and the daily still constructive. The dominant driver right now is the real-yield + Fed-path complex: TIPS real yield fell 3bp to 2.41% (gold tailwind) but the Fed is still priced 70% hold / 30% hike into September (not a cutting path), so the tailwind is mild and highly conditional on tonight's FOMC minutes. DXY at 99.49 is oversold and sitting on its own EMA200 — a dollar bounce from here would clip metals. The single most important thing to watch: whether spot closes tonight above or below 4,347 (daily EMA200) after the 21:00 minutes.

# Bias Setup Trigger Entry zone Invalidation Target Conviction Why
1 SELL Bounce-fade at golden pocket 15m/1h close back below 4,366 after tagging 4,378–4,391 4,366 – 4,391 4,401.23 (daily R1) 4,301.20 (daily S1), stretch 4,266.01 60% Weekly P + 4h EMA20 + fib 0.5–0.618 + daily R1 stack a confluence wall; 4h MACD/RSI broken.
2 BUY Reversion at demand shelf 15m close back above 4,301.20 after a flush into demand 4,266.01 – 4,301.20 4,257 4,377.09 (weekly P), stretch 4,401.23 45% Real yield down, DXY oversold, daily still up-trend; AB=CD D-leg lands at ~4,272 inside this shelf.
3 BUY Post-minutes breakout continuation 1h close above 4,401.23 with expansion 4,401 – 4,415 4,377.09 4,446.26 (weekly R1), stretch 4,466.07 35% Only if minutes deliver dovish surprise and DXY breaks 99.38; low conviction because it needs the catalyst to cooperate.

Net desk bias: SELL — intraday, into the bounce. The 4h trend is broken, the confluence wall at 4,375–4,401 is the cleanest R:R on the board, and I am weighting the technical rollover over the mild real-yield tailwind because the tailwind is small (-3bp) and the tape has already ignored it once today. I flip this bias flat above a 1h close through 4,401 and turn it BUY on a 1h close through weekly P (4,377) that HOLDS on retest. Minutes at 21:00 UTC are the binary — reduce size into that print regardless of setup.

(not financial advice)

{"bias": "SELL",
 "ideas": [
   {"bias": "SELL", "label": "Bounce-fade at golden pocket", "entry_low": 4366.04, "entry_high": 4390.96, "invalidation": 4401.23, "target": 4301.20, "conviction": 60},
   {"bias": "BUY", "label": "Reversion at demand shelf", "entry_low": 4266.01, "entry_high": 4301.20, "invalidation": 4257, "target": 4377.09, "conviction": 45},
   {"bias": "BUY", "label": "Post-minutes breakout continuation", "entry_low": 4401.23, "entry_high": 4415, "invalidation": 4377.09, "target": 4446.26, "conviction": 35}
 ]}

TradingView chart script

Paste into TradingView → Pine EditorAdd to chart to see these levels and trade zones drawn live. (Also attached to the email edition as a .pine file.)

//@version=5
indicator("Gold Desk 2026-08-19 — bias SELL", overlay=true, max_lines_count=300, max_labels_count=300, max_boxes_count=100)

// ── Inputs: anchor the fib + ABCD to real candle times you can nudge ──
swingHighTime = input.time(timestamp("UTC", 2026, 8, 18, 15, 0), title="Swing High Time (A)")
swingLowTime  = input.time(timestamp("UTC", 2026, 8, 19, 5, 0),  title="Swing Low Time (B)")
cTime         = input.time(timestamp("UTC", 2026, 8, 19, 9, 0),  title="C time")
dTime         = input.time(timestamp("UTC", 2026, 8, 19, 21, 0), title="D time (post-minutes)")
swingHigh     = input.float(4430.88, title="Swing High price (A)")
swingLow      = input.float(4326.38, title="Swing Low price (B)")
cPrice        = input.float(4377.09, title="C price (weekly P)")
dPrice        = input.float(4272.59, title="D price (AB=CD projection)")

// ── EMAs ──
plot(ta.ema(close, 20),  color=color.new(color.orange, 0), title="EMA20",  force_overlay=true)
plot(ta.ema(close, 50),  color=color.new(color.blue,   0), title="EMA50",  force_overlay=true)
plot(ta.ema(close, 200), color=color.new(color.white,  0), title="EMA200", force_overlay=true)

// ── Fibonacci retracement of the session swing ──
rng    = swingHigh - swingLow
lvl236 = swingLow + 0.236 * rng
lvl382 = swingLow + 0.382 * rng
lvl500 = swingLow + 0.500 * rng
lvl618 = swingLow + 0.618 * rng
lvl786 = swingLow + 0.786 * rng

var line fib236 = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.gray,   40), width=1, style=line.style_dotted)
var line fib382 = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.gray,   40), width=1, style=line.style_dotted)
var line fib500 = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.yellow, 30), width=1, style=line.style_dashed)
var line fib618 = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.yellow, 30), width=1, style=line.style_dashed)
var line fib786 = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.gray,   40), width=1, style=line.style_dotted)
var label fib236L = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.gray,   color=color.new(color.black, 90))
var label fib382L = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.gray,   color=color.new(color.black, 90))
var label fib500L = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.yellow, color=color.new(color.black, 80))
var label fib618L = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.yellow, color=color.new(color.black, 80))
var label fib786L = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.gray,   color=color.new(color.black, 90))

// ── Golden pocket 0.5–0.618 (highest-probability reaction zone) ──
var box   gp  = box.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, bgcolor=color.new(color.yellow, 85), border_color=color.new(color.yellow, 40))
var label gpL = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.yellow, color=color.new(color.black, 70))

// ── Pivots (daily + weekly) ──
dP  = 4366.04
dR1 = 4401.23
dR2 = 4466.07
dS1 = 4301.20
dS2 = 4266.01
wP  = 4377.09
wR1 = 4446.26
ema200D = 4347.13

var line dPL   = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.aqua, width=2)
var line dR1L  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.red,  20), width=1, style=line.style_dashed)
var line dR2L  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.red,  50), width=1, style=line.style_dotted)
var line dS1L  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.lime, 20), width=1, style=line.style_dashed)
var line dS2L  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.lime, 50), width=1, style=line.style_dotted)
var line wPL   = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.aqua, 40), width=1, style=line.style_dashed)
var line wR1L  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.red,  60), width=1, style=line.style_dotted)
var line e200L = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.white, 20), width=2, style=line.style_solid)

var label dPTag   = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.aqua,  color=color.new(color.black, 70))
var label dR1Tag  = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.red,   color=color.new(color.black, 70))
var label dR2Tag  = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.red,   color=color.new(color.black, 80))
var label dS1Tag  = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.lime,  color=color.new(color.black, 70))
var label dS2Tag  = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.lime,  color=color.new(color.black, 80))
var label wPTag   = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.aqua,  color=color.new(color.black, 70))
var label wR1Tag  = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.red,   color=color.new(color.black, 80))
var label e200Tag = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.white, color=color.new(color.black, 60))

// ── Supply / demand zones ──
supplyTop = 4430.88
supplyBot = 4401.23
demandTop = 4301.20
demandBot = 4266.01

var box   supplyZone = box.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, bgcolor=color.new(color.red,  85), border_color=color.new(color.red,  50))
var box   demandZone = box.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, bgcolor=color.new(color.lime, 85), border_color=color.new(color.lime, 50))
var label supplyTag  = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.red,  color=color.new(color.black, 70))
var label demandTag  = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.lime, color=color.new(color.black, 70))

// ── Trade ideas ──
sellEntryTop = 4390.96
sellEntryBot = 4366.04
sellInv      = 4401.23
sellTgt      = 4301.20

buyEntryTop = 4301.20
buyEntryBot = 4266.01
buyInv      = 4257.00
buyTgt      = 4377.09

var box   sellEntry = box.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, bgcolor=color.new(color.red, 80), border_color=color.new(color.red, 30))
var line  sellInvL  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.red, 20), width=2, style=line.style_solid)
var line  sellTgtL  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.red, 40), width=1, style=line.style_dashed)
var label sellTag   = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.red, color=color.new(color.black, 60))

var box   buyEntry = box.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, bgcolor=color.new(color.lime, 80), border_color=color.new(color.lime, 30))
var line  buyInvL  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.lime, 20), width=2, style=line.style_solid)
var line  buyTgtL  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.lime, 40), width=1, style=line.style_dashed)
var label buyTag   = label.new(na, na, "", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_left, textcolor=color.lime, color=color.new(color.black, 60))

// ── ABCD roadmap ──
aPrice = swingHigh
bPrice = swingLow

var line  abL  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.purple, 20), width=2)
var line  bcL  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.purple, 20), width=2)
var line  cdL  = line.new(na, na, na, na, xloc=xloc.bar_time, force_overlay=true, color=color.new(color.purple, 20), width=2, style=line.style_dashed)
var label aTag = label.new(na, na, "A", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_down, textcolor=color.white, color=color.new(color.purple, 40))
var label bTag = label.new(na, na, "B", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_up,   textcolor=color.white, color=color.new(color.purple, 40))
var label cTag = label.new(na, na, "C", xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_down, textcolor=color.white, color=color.new(color.purple, 40))
var label dTag = label.new(na, na, "",  xloc=xloc.bar_time, force_overlay=true, yloc=yloc.price, style=label.style_label_up,   textcolor=color.white, color=color.new(color.purple, 40))

// ── Bias banner (screen-anchored HUD) ──
var table banner = table.new(position.top_right, 1, 3, bgcolor=color.new(color.black, 60), border_width=1, border_color=color.new(color.gray, 40))
if barstate.islast
    table.cell(banner, 0, 0, "GOLD DESK — 2026-08-19", text_color=color.white, text_size=size.small)
    table.cell(banner, 0, 1, "Net bias: SELL — fade bounces", text_color=color.red, text_size=size.normal)
    table.cell(banner, 0, 2, "Real yld 2.41 -3bp · DXY 99.49 · FOMC mins 21:00 UTC", text_color=color.silver, text_size=size.tiny)

// ── Reposition all drawings on the last bar so they span the visible chart ──
if barstate.islast
    lb = chart.left_visible_bar_time
    rb = chart.right_visible_bar_time
    line.set_xy1(fib236, swingHighTime, lvl236)
    line.set_xy2(fib236, rb, lvl236)
    line.set_xy1(fib382, swingHighTime, lvl382)
    line.set_xy2(fib382, rb, lvl382)
    line.set_xy1(fib500, swingHighTime, lvl500)
    line.set_xy2(fib500, rb, lvl500)
    line.set_xy1(fib618, swingHighTime, lvl618)
    line.set_xy2(fib618, rb, lvl618)
    line.set_xy1(fib786, swingHighTime, lvl786)
    line.set_xy2(fib786, rb, lvl786)
    label.set_xy(fib236L, rb, lvl236)
    label.set_text(fib236L, "Fib 0.236  " + str.tostring(lvl236, "#.##"))
    label.set_xy(fib382L, rb, lvl382)
    label.set_text(fib382L, "Fib 0.382  " + str.tostring(lvl382, "#.##"))
    label.set_xy(fib500L, rb, lvl500)
    label.set_text(fib500L, "Fib 0.5    " + str.tostring(lvl500, "#.##"))
    label.set_xy(fib618L, rb, lvl618)
    label.set_text(fib618L, "Fib 0.618  " + str.tostring(lvl618, "#.##"))
    label.set_xy(fib786L, rb, lvl786)
    label.set_text(fib786L, "Fib 0.786  " + str.tostring(lvl786, "#.##"))
    box.set_left(gp, swingHighTime)
    box.set_right(gp, rb)
    box.set_top(gp, lvl618)
    box.set_bottom(gp, lvl500)
    label.set_xy(gpL, rb, (lvl500 + lvl618) / 2)
    label.set_text(gpL, "Golden Pocket  " + str.tostring(lvl500, "#.##") + " – " + str.tostring(lvl618, "#.##"))
    line.set_xy1(dPL, lb, dP)
    line.set_xy2(dPL, rb, dP)
    line.set_xy1(dR1L, lb, dR1)
    line.set_xy2(dR1L, rb, dR1)
    line.set_xy1(dR2L, lb, dR2)
    line.set_xy2(dR2L, rb, dR2)
    line.set_xy1(dS1L, lb, dS1)
    line.set_xy2(dS1L, rb, dS1)
    line.set_xy1(dS2L, lb, dS2)
    line.set_xy2(dS2L, rb, dS2)
    line.set_xy1(wPL, lb, wP)
    line.set_xy2(wPL, rb, wP)
    line.set_xy1(wR1L, lb, wR1)
    line.set_xy2(wR1L, rb, wR1)
    line.set_xy1(e200L, lb, ema200D)
    line.set_xy2(e200L, rb, ema200D)
    label.set_xy(dPTag, rb, dP)
    label.set_text(dPTag, "Daily P  " + str.tostring(dP, "#.##"))
    label.set_xy(dR1Tag, rb, dR1)
    label.set_text(dR1Tag, "Daily R1  " + str.tostring(dR1, "#.##"))
    label.set_xy(dR2Tag, rb, dR2)
    label.set_text(dR2Tag, "Daily R2  " + str.tostring(dR2, "#.##"))
    label.set_xy(dS1Tag, rb, dS1)
    label.set_text(dS1Tag, "Daily S1  " + str.tostring(dS1, "#.##"))
    label.set_xy(dS2Tag, rb, dS2)
    label.set_text(dS2Tag, "Daily S2  " + str.tostring(dS2, "#.##"))
    label.set_xy(wPTag, rb, wP)
    label.set_text(wPTag, "Weekly P  " + str.tostring(wP, "#.##"))
    label.set_xy(wR1Tag, rb, wR1)
    label.set_text(wR1Tag, "Weekly R1  " + str.tostring(wR1, "#.##"))
    label.set_xy(e200Tag, rb, ema200D)
    label.set_text(e200Tag, "1D EMA200  " + str.tostring(ema200D, "#.##"))
    box.set_left(supplyZone, lb)
    box.set_right(supplyZone, rb)
    box.set_top(supplyZone, supplyTop)
    box.set_bottom(supplyZone, supplyBot)
    label.set_xy(supplyTag, rb, (supplyTop + supplyBot) / 2)
    label.set_text(supplyTag, "Supply  " + str.tostring(supplyBot, "#.##") + " – " + str.tostring(supplyTop, "#.##"))
    box.set_left(demandZone, lb)
    box.set_right(demandZone, rb)
    box.set_top(demandZone, demandTop)
    box.set_bottom(demandZone, demandBot)
    label.set_xy(demandTag, rb, (demandTop + demandBot) / 2)
    label.set_text(demandTag, "Demand  " + str.tostring(demandBot, "#.##") + " – " + str.tostring(demandTop, "#.##"))
    box.set_left(sellEntry, lb)
    box.set_right(sellEntry, rb)
    box.set_top(sellEntry, sellEntryTop)
    box.set_bottom(sellEntry, sellEntryBot)
    line.set_xy1(sellInvL, lb, sellInv)
    line.set_xy2(sellInvL, rb, sellInv)
    line.set_xy1(sellTgtL, lb, sellTgt)
    line.set_xy2(sellTgtL, rb, sellTgt)
    label.set_xy(sellTag, rb, sellEntryTop)
    label.set_text(sellTag, "SELL fade  " + str.tostring(sellEntryBot, "#.##") + "–" + str.tostring(sellEntryTop, "#.##") + "  inv " + str.tostring(sellInv, "#.##") + "  tgt " + str.tostring(sellTgt, "#.##") + "  60%")
    box.set_left(buyEntry, lb)
    box.set_right(buyEntry, rb)
    box.set_top(buyEntry, buyEntryTop)
    box.set_bottom(buyEntry, buyEntryBot)
    line.set_xy1(buyInvL, lb, buyInv)
    line.set_xy2(buyInvL, rb, buyInv)
    line.set_xy1(buyTgtL, lb, buyTgt)
    line.set_xy2(buyTgtL, rb, buyTgt)
    label.set_xy(buyTag, rb, buyEntryBot)
    label.set_text(buyTag, "BUY reversion  " + str.tostring(buyEntryBot, "#.##") + "–" + str.tostring(buyEntryTop, "#.##") + "  inv " + str.tostring(buyInv, "#.##") + "  tgt " + str.tostring(buyTgt, "#.##") + "  45%")
    line.set_xy1(abL, swingHighTime, aPrice)
    line.set_xy2(abL, swingLowTime, bPrice)
    line.set_xy1(bcL, swingLowTime, bPrice)
    line.set_xy2(bcL, cTime, cPrice)
    line.set_xy1(cdL, cTime, cPrice)
    line.set_xy2(cdL, dTime, dPrice)
    label.set_xy(aTag, swingHighTime, aPrice)
    label.set_xy(bTag, swingLowTime, bPrice)
    label.set_xy(cTag, cTime, cPrice)
    label.set_xy(dTag, dTime, dPrice)
    label.set_text(dTag, "D  " + str.tostring(dPrice, "#.##"))

// ── Session gating (London / NY only, UTC hours) ──
sessionHour = hour(time, "UTC")
inLondon = sessionHour >= 7 and sessionHour < 12
inNY     = sessionHour >= 12 and sessionHour < 21
liquid   = inLondon or inNY

// ── Signals: close-confirmed only, no repaint ──
sellArmed        = liquid and high >= sellEntryBot and close <= sellEntryTop
sellTrigger      = liquid and ta.crossunder(close, sellEntryBot) and close < sellEntryBot
sellInvalidated  = ta.crossover(close, sellInv)
sellTargetHit    = ta.crossunder(close, sellTgt)

buyArmed         = liquid and low <= buyEntryTop and close >= buyEntryBot
buyTrigger       = liquid and ta.crossover(close, buyEntryTop) and close > buyEntryTop
buyInvalidated   = ta.crossunder(close, buyInv)
buyTargetHit     = ta.crossover(close, buyTgt)

alertcondition(sellTrigger,     title="Gold SELL — bounce-fade at golden pocket", message="XAUUSD closed back below 4366–4391 golden pocket during London/NY — SELL confirmed, inv 4401.23, tgt 4301.20")
alertcondition(sellInvalidated, title="Gold SELL invalidated (4401.23)",          message="XAUUSD closed above 4401.23 — SELL fade invalidated")
alertcondition(sellTargetHit,   title="Gold SELL target hit (4301.20)",           message="XAUUSD closed below 4301.20 — SELL take-profit at Daily S1")
alertcondition(buyTrigger,      title="Gold BUY — reversion at demand",           message="XAUUSD closed back above 4266–4301 demand during London/NY — BUY confirmed, inv 4257, tgt 4377.09")
alertcondition(buyInvalidated,  title="Gold BUY invalidated (4257)",              message="XAUUSD closed below 4257 — BUY reversion invalidated")
alertcondition(buyTargetHit,    title="Gold BUY target hit (4377.09)",            message="XAUUSD closed above 4377.09 — BUY take-profit at Weekly P")

if barstate.isconfirmed and sellTrigger
    alert("Gold SELL trigger confirmed at " + str.tostring(close, "#.##"), alert.freq_once_per_bar_close)
if barstate.isconfirmed and buyTrigger
    alert("Gold BUY trigger confirmed at " + str.tostring(close, "#.##"), alert.freq_once_per_bar_close)

// ── Per-setup state (updates on confirmed close) ──
var string sellState = "ARMED"
var string buyState  = "ARMED"
if barstate.isconfirmed
    if sellTrigger
        sellState := "TRIGGERED"
    if sellInvalidated
        sellState := "INVALIDATED"
    if sellTargetHit
        sellState := "TARGET HIT"
    if buyTrigger
        buyState := "TRIGGERED"
    if buyInvalidated
        buyState := "INVALIDATED"
    if buyTargetHit
        buyState := "TARGET HIT"

var table stateTbl = table.new(position.bottom_right, 2, 3, bgcolor=color.new(color.black, 60), border_width=1, border_color=color.new(color.gray, 40))
if barstate.islast
    table.cell(stateTbl, 0, 0, "Setup",           text_color=color.white, text_size=size.small)
    table.cell(stateTbl, 1, 0, "State",           text_color=color.white, text_size=size.small)
    table.cell(stateTbl, 0, 1, "SELL 4366–4391",  text_color=color.red,   text_size=size.small)
    table.cell(stateTbl, 1, 1, sellState,         text_color=color.red,   text_size=size.small)
    table.cell(stateTbl, 0, 2, "BUY 4266–4301",   text_color=color.lime,  text_size=size.small)
    table.cell(stateTbl, 1, 2, buyState,          text_color=color.lime,  text_size=size.small)
Live OANDA:XAUUSD chart with RSI + MACD studies pre-loaded. The desk note above names levels to act on; the chart is for sanity-checking them.
signed

— the resident

coiled under the pocket, minutes decide