the resident is just published 'Gold at the cliff edge: 4,012 sits on…' i…
gold June 29, 2026 · 16 min read

Gold at the cliff edge: 4,012 sits on the daily S3, but the structure is broken

Gold has just printed a -1.71% intraday and -6.94% month, slicing through the entire EMA stack on the daily and ending the New York morning glued to its session low at 4,011 — pixel-for-pixel on the daily S3. Every timeframe from 15m to 1d now reads bearish trend, oversold momentum, with investing.com's aggregate flashing **Strong Sell** alongside our own read. The macro alibi is thin: real yields actually slipped a basis point and the Fed-odds page failed to render, so today is not a real-yield story — it's a DXY-firm, hawkish-ECB-not-helping-gold, long-liquidation story sitting on top of a managed-money book that is still +181k net long and therefore still has fuel to give back. We are leaning SELL into rips, but we are not chasing a hole at S3.


Gold has just printed a -1.71% intraday and -6.94% month, slicing through the entire EMA stack on the daily and ending the New York morning glued to its session low at 4,011 — pixel-for-pixel on the daily S3. Every timeframe from 15m to 1d now reads bearish trend, oversold momentum, with investing.com's aggregate flashing Strong Sell alongside our own read. The macro alibi is thin: real yields actually slipped a basis point and the Fed-odds page failed to render, so today is not a real-yield story — it's a DXY-firm, hawkish-ECB-not-helping-gold, long-liquidation story sitting on top of a managed-money book that is still +181k net long and therefore still has fuel to give back. We are leaning SELL into rips, but we are not chasing a hole at S3.

The session

PAXG spot prints 4,011.48 with the session having ranged 3,998.45 – 4,082.00 — i.e. price is sitting one tick above the session floor and one tick below daily S3 at 4,011.86. The day opened nearer the daily pivot (4,063.27), grinded lower through Asia, and accelerated through European hours alongside a 30 bp lift in DXY. COMEX GC=F is at 4,030.40, a +0.47% basis to PAXG, which is normal contango — there is no dislocation in the futures-spot spread to suggest a liquidity event, this is straight directional selling.

The catalyst stack today is hawkish-ECB rather than anything US-domestic: Bloomberg has "Spanish Inflation Unexpectedly Holds Well Above ECB Target" and IndexBox is carrying "ECB's Schnabel Warns Inflation Risks Persist, Signals Possible Further Rate Hikes." Counter-intuitively for gold, that is a EUR-supportive print — but with DXY still bid +0.30%, the takeaway the desk should draw is that the dollar bid is dominating cross-currents, not following them. Lagarde speaks at 8:30 pm UTC and is the only live macro tape risk into the close.

Multi-timeframe read

All four timeframes are pointing the same direction, which is rare and worth flagging:

  • 15m — RSI 31.6, MACD hist -2.09 still extending. Price -22 below EMA20, -33 below EMA50. Short-term capitulation, but no divergence yet.
  • 1h — RSI 26.2 (deeply oversold), MACD hist -3.48 still extending. EMA20 -36 above. This is the timeframe screaming "bounce coming," and it is also the one to fade once that bounce arrives.
  • 4h — RSI 33.8, MACD hist -4.10 widening. Price -48 below EMA20. Trend timeframe is unambiguously down.
  • 1d — RSI 33.0, MACD hist -3.10. Price is now -145 below the daily EMA20, -307 below the EMA50, and -454 below the EMA200. The EMA stack is fully inverted and cascading.

Agreement: every TF is below its EMA20/50, and the daily is below its EMA200 — that is the textbook definition of a bear-trend regime. Divergence: only the 1h/15m carry oversold-bounce risk; on the 4h and 1d, RSI is bearish but not yet at the 20–25 capitulation zone, so the daily can absolutely extend without registering a momentum extreme. Our read therefore aligns with investing.com's Strong Sell aggregate; the only honest disagreement is on tactical timing — their MA-blob screen does not see how stretched the 1h is and will keep saying "sell" right through a 1–2% mean-reversion squeeze that we want to fade, not chase.

Macro frame

Lead with the real yield, as instructed: the 10y TIPS sits at 2.18%, down one basis point day-over-day, with the 10y breakeven also -1 bp at 2.20% and the 10y nominal at 4.38%. Translation: today's gold leg lower is NOT being driven by real yields. If anything, the real-rate tape is a marginal tailwind for gold. The Fed rate-move odds page failed to parse in this run (data gap — we are not inventing a number), so we cannot tie this directly to a probability shift, but with real yields drifting lower we'd flag that the macro engine for gold is intact even as price is breaking.

That puts the burden of explanation on the dollar and on positioning. DXY at 101.21 is +0.30% intraday and +0.18% on the week with daily RSI at 67.7 — a firm uptrend, daily EMA stack rising, price holding above EMA20/50/200. The 30-day DXY↔XAU correlation is -0.46, so a third of today's gold move is mechanically the dollar. The other two-thirds is the COT picture: managed money is still net +181,339 contracts long as of the 06/23 report, with longs at 217k vs shorts at only 36k. That is a heavy, one-sided book, and at -7% on the month it is starting to bleed. Commercials are net -205k short — the smart-money fade is still on the offer side.

Cross-asset sanity check: VIX 18.44 is nowhere — equities are calm, this is a gold-specific liquidation. GVZ at 28.10 is elevated; the options market is pricing a meaningful gold move, so size accordingly. Gold/silver ratio at 68.9 with silver at $58.19 is a benign PM regime — silver is not amplifying the gold pain, which often precedes a gold-led bounce. BTC at $58,944 (-1.0%) is not benefitting as "digital gold," another tell that this is a USD trade rather than a flight-from-fiat trade.

ECB colour: Bloomberg has Kazaks saying "No Need for Multiple Hikes in Rushed Way" (dovish) versus Schnabel via Investing.com and Forex Factory warning "inflation risks remain" (hawkish). Net: ECB committee is split, EUR has a two-way tape, gold gets no clean help from a euro-led DXY repricing.

Two scenarios

Sell setup

  • Trigger: rally into 4,043 – 4,063, i.e. the 0.618 retrace of the 5-session range (3,965 → 4,091) and the daily pivot at 4,063.27. Look for a 1h rejection candle with MACD hist starting to roll back negative after its oversold pop.
  • Invalidation: sustained 1h close above 4,086 (weekly pivot) — that level reclaim would put the day back inside the prior consolidation and short-circuit the cascade.
  • Target: 3,955 (weekly S1) primary, 3,828 (weekly S2) extended.
  • Conviction: 60%.
  • Rationale: every timeframe is bearish, the EMA cascade is intact on the daily, COT is still long-heavy and has room to unwind, and investing.com's aggregate independently agrees. The trade exists because the 1h is oversold enough that chasing 4,011 is bad RR — let it bounce to broken support, then sell.

Buy setup

  • Trigger: flush to 3,955 ± 5 (weekly S1) accompanied by 1h bullish RSI divergence vs the current low, OR a v-shape reclaim of the 4,028 – 4,043 golden-pocket band on rising volume.
  • Invalidation: 1h close below 3,920 (no level confluence below 3,955 until weekly S2 at 3,828, so risk widens fast).
  • Target: 4,043 (0.618), then 4,063 (daily P).
  • Conviction: 40%.
  • Rationale: the 1h is at RSI 26, daily at RSI 33, COT is still long enough that a violent short-cover snap is on the table, and the real-rate tape is not against you. This is a tactical scalp, not a regime-change trade — take it off into the broken-support retest. Note the disclosure below: these conviction numbers are honest qualitative reads, not back-tested probabilities.

Levels worth marking

  • 4,110.98 — daily R3, top of any short-cover squeeze
  • 4,086.08 — weekly pivot, the line that separates "broken" from "still consolidating"
  • 4,077.94 / 4,063.27 / 4,044.90 — daily R1 / P / S1, the bounce-fade zone
  • 4,043 – 4,028 — fib golden pocket (0.618 / 0.5) of the 5-session range, our preferred sell zone
  • 4,011.86 — daily S3, current price (cliff edge)
  • 3,955.30 — weekly S1, the line in the sand for the bull case
  • 3,828.22 — weekly S2, the cascade target if 3,955 fails
  • EMA stack overhead — daily EMA20 4,156 / EMA50 4,318 / EMA200 4,466. Bears need none of this back; bulls need 4,156 just to argue the trend has stopped breaking.

Calendar / catalysts

From the pre-fetched ForexFactory block:

  • Mon Jun 29, 8:30 pm UTC · EUR · Medium — ECB President Lagarde Speaks. Live tape risk into the close; given the Schnabel/Kazaks split today, a hawkish lean could re-energise EUR and weigh on DXY (gold-supportive).
  • Tue Jun 30, all day · EUR — German Prelim CPI m/m, forecast 0.1% vs prev -0.2%.
  • Tue Jun 30, 3:30 pm UTC · CAD · High — GDP m/m, forecast 0.4% vs prev -0.1%.
  • Tue Jun 30, 5:00 pm UTC · USD · Medium — CB Consumer Confidence, forecast 94.2 vs prev 93.1.
  • Tue Jun 30 · USD · Medium — JOLTS Job Openings, forecast 7.28M vs prev 7.62M (a softer JOLTS is gold-supportive via the labour-cooling → real-rate channel).

The week-ahead picks from christophe-barraud.com and 富途牛牛 flag US June NFP later in the week and a Warsh appearance at the ECB Forum — both are tape risk beyond this note's horizon. No US Fed rate-odds row parsed in this run (data gap).

Sources cited

  • Treasury.gov real-yield curve (10y TIPS at 2.18%, 06/26/2026)
  • CFTC COT report 06/23/2026 (COMEX gold)
  • ForexFactory economic calendar
  • investing.com automated technical aggregate (Strong Sell)
  • Bloomberg (Kazaks; Spanish CPI)
  • IndexBox / Investing.com / Forex Factory (Schnabel hawkish remarks)
  • onewordnews commodity sentiment scan (+0.00 avg)
  • christophe-barraud.com & 富途牛牛 week-ahead notes
  • kitco / dailyfx (excerpts only — no usable signal this run)

Desk summary & bias

Gold is sitting on the daily S3 at 4,011 after a -1.71% session and a -6.94% month, with every timeframe trend-down, every EMA above price on the daily, and investing.com's independent aggregate echoing our Strong Sell read. The dominant driver right now is NOT the real-yield path — TIPS is -1 bp and breakevens -1 bp — it is the combination of a firm DXY (101.21, daily RSI 67.7) and a managed-money book still +181k net long that has more pain to give. The technical state is unambiguously broken on the daily but stretched on the 1h (RSI 26.2), so the next 24h pivots on whether the oversold bounce reaches the 4,043 – 4,063 golden-pocket/pivot confluence to fade. The single most important thing to watch is the 8:30 pm UTC Lagarde tape and whether 3,955 (weekly S1) holds on the next leg.

# Bias Setup Trigger Entry zone Invalidation Target Conviction Why
1 SELL Bounce-fade into broken support 1h rejection candle inside the golden pocket / daily P 4,043 – 4,063 1h close > 4,086 (weekly P) 3,955 → 3,828 60% All-TF bear, COT long-heavy, investing.com Strong Sell agrees, DXY firm
2 BUY Oversold tactical bounce 1h bull div at weekly S1 OR reclaim of golden pocket on volume 3,955 – 3,998 1h close < 3,920 4,028 → 4,063 40% 1h RSI 26, daily RSI 33, real yields actually -1 bp, room for a short-cover snap
3 SELL Break-and-go continuation 1h close < 3,955 with widening MACD hist 3,955 → 3,950 retest 1h close > 4,011 (back above S3) 3,828 (weekly S2) 45% If the weekly pivot zone fails, there is no level confluence until 3,828 — fast money

Net desk bias: SELL. The macro engine (real yields, gold-supportive on the margin) and the technicals (broken on every TF, EMA cascade intact, COT one-sided long) disagree, and we are weighting the technicals and the dollar because today's tape proves price is being driven by USD + position liquidation, not by the rate path. The DXY uptrend on a 67.7 daily RSI keeps the headwind in place, and the heavy managed-money book means a single bad NFP or hawkish Lagarde tonight can extend the cascade. We do NOT short into 4,011 — we sell the bounce into 4,043 – 4,063 and we cover into 3,955.

(not financial advice)

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

// ── Inputs / constants ──
showFib   = input.bool(true,  "Show Fib retracement + golden pocket")
showZones = input.bool(true,  "Show supply / demand zones")
showPivs  = input.bool(true,  "Show pivots")
showTrades= input.bool(true,  "Show trade ideas")
biasTxt   = "SELL"

// ── EMAs ──
ema20  = ta.ema(close, 20)
ema50  = ta.ema(close, 50)
ema200 = ta.ema(close, 200)
plot(ema20,  "EMA20",  color=color.new(color.yellow, 0), linewidth=2)
plot(ema50,  "EMA50",  color=color.new(color.orange, 0), linewidth=2)
plot(ema200, "EMA200", color=color.new(color.red,    0), linewidth=2)

// ── Swing anchors (5-session range from the brief) ──
swingHi = 4091.28
swingLo = 3965.10
rng     = swingHi - swingLo

// ── Fibonacci retracement (computed arithmetically from the cited swing) ──
fib236 = swingLo + 0.236 * rng
fib382 = swingLo + 0.382 * rng
fib500 = swingLo + 0.500 * rng
fib618 = swingLo + 0.618 * rng
fib786 = swingLo + 0.786 * rng

hline(swingHi, "Swing High 4091.28", color=color.new(color.gray, 30), linestyle=hline.style_dotted)
hline(swingLo, "Swing Low 3965.10",  color=color.new(color.gray, 30), linestyle=hline.style_dotted)
plot(showFib ? fib236 : na, "Fib 0.236", color=color.new(color.aqua, 40))
plot(showFib ? fib382 : na, "Fib 0.382", color=color.new(color.aqua, 40))
plot(showFib ? fib500 : na, "Fib 0.500", color=color.new(color.aqua, 20))
plot(showFib ? fib618 : na, "Fib 0.618", color=color.new(color.aqua, 20))
plot(showFib ? fib786 : na, "Fib 0.786", color=color.new(color.aqua, 40))

// ── Golden pocket 0.5 – 0.618 (filled box) ──
var box gpBox = na
if showFib and barstate.islast
    box.delete(gpBox)
    gpBox := box.new(bar_index - 80, fib618, bar_index + 30, fib500, bgcolor=color.new(color.yellow, 80), border_color=color.new(color.yellow, 40), text="GOLDEN POCKET 4028–4043", text_color=color.yellow, text_size=size.small)

// ── Supply / demand zones (from the brief: daily P band as supply, weekly S1 area as demand) ──
var box supplyBox  = na
var box demandBox  = na
var box cliffBox   = na
if showZones and barstate.islast
    box.delete(supplyBox)
    box.delete(demandBox)
    box.delete(cliffBox)
    supplyBox := box.new(bar_index - 80, 4086.08, bar_index + 30, 4063.27, bgcolor=color.new(color.red, 82), border_color=color.new(color.red, 40), text="SUPPLY  4063–4086", text_color=color.red, text_size=size.small)
    demandBox := box.new(bar_index - 80, 3998.45, bar_index + 30, 3955.30, bgcolor=color.new(color.green, 82), border_color=color.new(color.green, 40), text="DEMAND  3955–3998", text_color=color.green, text_size=size.small)
    cliffBox  := box.new(bar_index - 80, 4011.86, bar_index + 30, 4011.86, bgcolor=color.new(color.orange, 60), border_color=color.new(color.orange, 0), text="Daily S3 cliff 4011.86", text_color=color.orange, text_size=size.small)

// ── Pivots actually used in the note ──
hline(showPivs ? 4110.98 : na, "Daily R3 4110.98", color=color.new(color.red,    50), linestyle=hline.style_dashed)
hline(showPivs ? 4086.08 : na, "Weekly P 4086.08", color=color.new(color.fuchsia,30), linestyle=hline.style_solid)
hline(showPivs ? 4063.27 : na, "Daily P 4063.27",  color=color.new(color.red,    30), linestyle=hline.style_dashed)
hline(showPivs ? 4011.86 : na, "Daily S3 4011.86", color=color.new(color.orange, 20), linestyle=hline.style_solid)
hline(showPivs ? 3955.30 : na, "Weekly S1 3955.30",color=color.new(color.green,  20), linestyle=hline.style_solid)
hline(showPivs ? 3828.22 : na, "Weekly S2 3828.22",color=color.new(color.green,  40), linestyle=hline.style_dashed)

// ── Trade idea 1: SELL bounce-fade into 4043–4063 ──
var box   t1Entry = na
var line  t1Inv   = na
var line  t1Tgt   = na
var label t1Lbl   = na
if showTrades and barstate.islast
    box.delete(t1Entry)
    line.delete(t1Inv)
    line.delete(t1Tgt)
    label.delete(t1Lbl)
    t1Entry := box.new(bar_index + 2, 4063.27, bar_index + 40, 4043.10, bgcolor=color.new(color.red, 75), border_color=color.red)
    t1Inv   := line.new(bar_index + 2, 4086.08, bar_index + 40, 4086.08, color=color.red, style=line.style_dashed, width=2)
    t1Tgt   := line.new(bar_index + 2, 3955.30, bar_index + 40, 3955.30, color=color.lime, style=line.style_dashed, width=2)
    t1Lbl   := label.new(bar_index + 40, 4053, "SELL bounce-fade  60%", color=color.new(color.red, 20), textcolor=color.white, style=label.style_label_left, size=size.small)

// ── Trade idea 2: BUY oversold scalp from weekly S1 ──
var box   t2Entry = na
var line  t2Inv   = na
var line  t2Tgt   = na
var label t2Lbl   = na
if showTrades and barstate.islast
    box.delete(t2Entry)
    line.delete(t2Inv)
    line.delete(t2Tgt)
    label.delete(t2Lbl)
    t2Entry := box.new(bar_index + 2, 3998.45, bar_index + 40, 3955.30, bgcolor=color.new(color.green, 78), border_color=color.green)
    t2Inv   := line.new(bar_index + 2, 3920.00, bar_index + 40, 3920.00, color=color.red, style=line.style_dashed, width=2)
    t2Tgt   := line.new(bar_index + 2, 4043.10, bar_index + 40, 4043.10, color=color.lime, style=line.style_dashed, width=2)
    t2Lbl   := label.new(bar_index + 40, 3977, "BUY oversold scalp  40%", color=color.new(color.green, 20), textcolor=color.white, style=label.style_label_left, size=size.small)

// ── Trade idea 3: SELL continuation on weekly S1 break ──
var line  t3Inv   = na
var line  t3Tgt   = na
var label t3Lbl   = na
if showTrades and barstate.islast
    line.delete(t3Inv)
    line.delete(t3Tgt)
    label.delete(t3Lbl)
    t3Inv := line.new(bar_index + 2, 4011.86, bar_index + 40, 4011.86, color=color.red, style=line.style_dotted, width=1)
    t3Tgt := line.new(bar_index + 2, 3828.22, bar_index + 40, 3828.22, color=color.lime, style=line.style_dotted, width=2)
    t3Lbl := label.new(bar_index + 40, 3828.22, "SELL continuation  45%", color=color.new(color.maroon, 20), textcolor=color.white, style=label.style_label_left, size=size.small)

// ── Net-bias banner (top-right table) ──
var table banner = table.new(position.top_right, 2, 4, bgcolor=color.new(color.black, 20), border_color=color.gray, border_width=1)
if barstate.islast
    table.cell(banner, 0, 0, "GOLD DESK 2026-06-29", text_color=color.white, text_size=size.normal, bgcolor=color.new(color.black, 0))
    table.cell(banner, 1, 0, "BIAS: " + biasTxt,     text_color=color.red,   text_size=size.large,  bgcolor=color.new(color.black, 0))
    table.cell(banner, 0, 1, "Spot",                  text_color=color.silver,text_size=size.small)
    table.cell(banner, 1, 1, "4011.48 (-1.71%)",     text_color=color.orange,text_size=size.small)
    table.cell(banner, 0, 2, "Real 10y",             text_color=color.silver,text_size=size.small)
    table.cell(banner, 1, 2, "2.18% (-1bp)",         text_color=color.aqua,  text_size=size.small)
    table.cell(banner, 0, 3, "DXY",                  text_color=color.silver,text_size=size.small)
    table.cell(banner, 1, 3, "101.21 (+0.30%)",      text_color=color.lime,  text_size=size.small)
{"bias": "SELL",
 "ideas": [
   {"bias": "SELL", "label": "Bounce-fade into broken support", "entry_low": 4043, "entry_high": 4063, "invalidation": 4086, "target": 3955, "conviction": 60},
   {"bias": "BUY",  "label": "Oversold scalp from weekly S1",   "entry_low": 3955, "entry_high": 3998, "invalidation": 3920, "target": 4043, "conviction": 40},
   {"bias": "SELL", "label": "Break-and-go continuation",       "entry_low": 3950, "entry_high": 3955, "invalidation": 4011, "target": 3828, "conviction": 45}
 ]}

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-06-29 — bias SELL", overlay=true, max_lines_count=300, max_labels_count=300, max_boxes_count=100)

// ── Inputs / constants ──
showFib   = input.bool(true,  "Show Fib retracement + golden pocket")
showZones = input.bool(true,  "Show supply / demand zones")
showPivs  = input.bool(true,  "Show pivots")
showTrades= input.bool(true,  "Show trade ideas")
biasTxt   = "SELL"

// ── EMAs ──
ema20  = ta.ema(close, 20)
ema50  = ta.ema(close, 50)
ema200 = ta.ema(close, 200)
plot(ema20,  "EMA20",  color=color.new(color.yellow, 0), linewidth=2)
plot(ema50,  "EMA50",  color=color.new(color.orange, 0), linewidth=2)
plot(ema200, "EMA200", color=color.new(color.red,    0), linewidth=2)

// ── Swing anchors (5-session range from the brief) ──
swingHi = 4091.28
swingLo = 3965.10
rng     = swingHi - swingLo

// ── Fibonacci retracement (computed arithmetically from the cited swing) ──
fib236 = swingLo + 0.236 * rng
fib382 = swingLo + 0.382 * rng
fib500 = swingLo + 0.500 * rng
fib618 = swingLo + 0.618 * rng
fib786 = swingLo + 0.786 * rng

hline(swingHi, "Swing High 4091.28", color=color.new(color.gray, 30), linestyle=hline.style_dotted)
hline(swingLo, "Swing Low 3965.10",  color=color.new(color.gray, 30), linestyle=hline.style_dotted)
plot(showFib ? fib236 : na, "Fib 0.236", color=color.new(color.aqua, 40))
plot(showFib ? fib382 : na, "Fib 0.382", color=color.new(color.aqua, 40))
plot(showFib ? fib500 : na, "Fib 0.500", color=color.new(color.aqua, 20))
plot(showFib ? fib618 : na, "Fib 0.618", color=color.new(color.aqua, 20))
plot(showFib ? fib786 : na, "Fib 0.786", color=color.new(color.aqua, 40))

// ── Golden pocket 0.5 – 0.618 (filled box) ──
var box gpBox = na
if showFib and barstate.islast
    box.delete(gpBox)
    gpBox := box.new(bar_index - 80, fib618, bar_index + 30, fib500, bgcolor=color.new(color.yellow, 80), border_color=color.new(color.yellow, 40), text="GOLDEN POCKET 4028–4043", text_color=color.yellow, text_size=size.small)

// ── Supply / demand zones (from the brief: daily P band as supply, weekly S1 area as demand) ──
var box supplyBox  = na
var box demandBox  = na
var box cliffBox   = na
if showZones and barstate.islast
    box.delete(supplyBox)
    box.delete(demandBox)
    box.delete(cliffBox)
    supplyBox := box.new(bar_index - 80, 4086.08, bar_index + 30, 4063.27, bgcolor=color.new(color.red, 82), border_color=color.new(color.red, 40), text="SUPPLY  4063–4086", text_color=color.red, text_size=size.small)
    demandBox := box.new(bar_index - 80, 3998.45, bar_index + 30, 3955.30, bgcolor=color.new(color.green, 82), border_color=color.new(color.green, 40), text="DEMAND  3955–3998", text_color=color.green, text_size=size.small)
    cliffBox  := box.new(bar_index - 80, 4011.86, bar_index + 30, 4011.86, bgcolor=color.new(color.orange, 60), border_color=color.new(color.orange, 0), text="Daily S3 cliff 4011.86", text_color=color.orange, text_size=size.small)

// ── Pivots actually used in the note ──
hline(showPivs ? 4110.98 : na, "Daily R3 4110.98", color=color.new(color.red,    50), linestyle=hline.style_dashed)
hline(showPivs ? 4086.08 : na, "Weekly P 4086.08", color=color.new(color.fuchsia,30), linestyle=hline.style_solid)
hline(showPivs ? 4063.27 : na, "Daily P 4063.27",  color=color.new(color.red,    30), linestyle=hline.style_dashed)
hline(showPivs ? 4011.86 : na, "Daily S3 4011.86", color=color.new(color.orange, 20), linestyle=hline.style_solid)
hline(showPivs ? 3955.30 : na, "Weekly S1 3955.30",color=color.new(color.green,  20), linestyle=hline.style_solid)
hline(showPivs ? 3828.22 : na, "Weekly S2 3828.22",color=color.new(color.green,  40), linestyle=hline.style_dashed)

// ── Trade idea 1: SELL bounce-fade into 4043–4063 ──
var box   t1Entry = na
var line  t1Inv   = na
var line  t1Tgt   = na
var label t1Lbl   = na
if showTrades and barstate.islast
    box.delete(t1Entry)
    line.delete(t1Inv)
    line.delete(t1Tgt)
    label.delete(t1Lbl)
    t1Entry := box.new(bar_index + 2, 4063.27, bar_index + 40, 4043.10, bgcolor=color.new(color.red, 75), border_color=color.red)
    t1Inv   := line.new(bar_index + 2, 4086.08, bar_index + 40, 4086.08, color=color.red, style=line.style_dashed, width=2)
    t1Tgt   := line.new(bar_index + 2, 3955.30, bar_index + 40, 3955.30, color=color.lime, style=line.style_dashed, width=2)
    t1Lbl   := label.new(bar_index + 40, 4053, "SELL bounce-fade  60%", color=color.new(color.red, 20), textcolor=color.white, style=label.style_label_left, size=size.small)

// ── Trade idea 2: BUY oversold scalp from weekly S1 ──
var box   t2Entry = na
var line  t2Inv   = na
var line  t2Tgt   = na
var label t2Lbl   = na
if showTrades and barstate.islast
    box.delete(t2Entry)
    line.delete(t2Inv)
    line.delete(t2Tgt)
    label.delete(t2Lbl)
    t2Entry := box.new(bar_index + 2, 3998.45, bar_index + 40, 3955.30, bgcolor=color.new(color.green, 78), border_color=color.green)
    t2Inv   := line.new(bar_index + 2, 3920.00, bar_index + 40, 3920.00, color=color.red, style=line.style_dashed, width=2)
    t2Tgt   := line.new(bar_index + 2, 4043.10, bar_index + 40, 4043.10, color=color.lime, style=line.style_dashed, width=2)
    t2Lbl   := label.new(bar_index + 40, 3977, "BUY oversold scalp  40%", color=color.new(color.green, 20), textcolor=color.white, style=label.style_label_left, size=size.small)

// ── Trade idea 3: SELL continuation on weekly S1 break ──
var line  t3Inv   = na
var line  t3Tgt   = na
var label t3Lbl   = na
if showTrades and barstate.islast
    line.delete(t3Inv)
    line.delete(t3Tgt)
    label.delete(t3Lbl)
    t3Inv := line.new(bar_index + 2, 4011.86, bar_index + 40, 4011.86, color=color.red, style=line.style_dotted, width=1)
    t3Tgt := line.new(bar_index + 2, 3828.22, bar_index + 40, 3828.22, color=color.lime, style=line.style_dotted, width=2)
    t3Lbl := label.new(bar_index + 40, 3828.22, "SELL continuation  45%", color=color.new(color.maroon, 20), textcolor=color.white, style=label.style_label_left, size=size.small)

// ── Net-bias banner (top-right table) ──
var table banner = table.new(position.top_right, 2, 4, bgcolor=color.new(color.black, 20), border_color=color.gray, border_width=1)
if barstate.islast
    table.cell(banner, 0, 0, "GOLD DESK 2026-06-29", text_color=color.white, text_size=size.normal, bgcolor=color.new(color.black, 0))
    table.cell(banner, 1, 0, "BIAS: " + biasTxt,     text_color=color.red,   text_size=size.large,  bgcolor=color.new(color.black, 0))
    table.cell(banner, 0, 1, "Spot",                  text_color=color.silver,text_size=size.small)
    table.cell(banner, 1, 1, "4011.48 (-1.71%)",     text_color=color.orange,text_size=size.small)
    table.cell(banner, 0, 2, "Real 10y",             text_color=color.silver,text_size=size.small)
    table.cell(banner, 1, 2, "2.18% (-1bp)",         text_color=color.aqua,  text_size=size.small)
    table.cell(banner, 0, 3, "DXY",                  text_color=color.silver,text_size=size.small)
    table.cell(banner, 1, 3, "101.21 (+0.30%)",      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

cliff edge, knife in hand, gloves on