fix: SVG causal chain — tous les nœuds dynamiques
Bugs corrigés : - VIX : hardcodé gris → rouge si > base (risk-off = bearish EUR), valeur affichée dans le nœud, flèche épaisseur dynamique - CPI US/NFP : hardcodé gris/unidirectionnel → fedFwdC bidirectionnel (rouge si hawkish, vert si dovish) - CPI EU/PMI : idem → ecbFwdC bidirectionnel - FED : utilisait fedRateC (rate only) → fedC combinant rate + tone (réagit au ton seul) - BCE : idem → ecbC combiné - Flèches CPI→FED/BCE : utilisaient la couleur du canal taux → corrigé vers canal forward guidance (tirets) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -278,15 +278,25 @@ function CausalChain({ r, base, p }: { r: ModelResult; base: Params; p: Params }
|
||||
const col3 = (v: number, threshold = 0.03): string =>
|
||||
Math.abs(v) < threshold ? '#94a3b8' : v > 0 ? '#f87171' : '#34d399'
|
||||
|
||||
const fedRateC = col3(r.fed_rate_pressure, 0.3)
|
||||
const ecbRateC = col3(-r.ecb_rate_pressure, 0.3) // flipped: ECB hawkish → EUR up → green
|
||||
// ── Node colors ────────────────────────────────────────────────────────────
|
||||
// CPI/NFP/PMI inputs → forward guidance signal (positive = hawkish Fed = red for EUR)
|
||||
const fedFwdC = col3(r.fed_fwd_signal, 0.4)
|
||||
const ecbFwdC = col3(-r.ecb_fwd_signal, 0.4) // ECB hawkish fwd signal → green for EUR
|
||||
|
||||
// CB nodes: combined rate + tone signal dominates
|
||||
const fedC = col3(r.fed_rate_pressure + r.fed_fwd_signal * 0.4, 0.25)
|
||||
const ecbC = col3(-(r.ecb_rate_pressure + r.ecb_fwd_signal * 0.4), 0.25)
|
||||
|
||||
// PMI US: positive deviation (> 50) = US strong = bearish EUR = red
|
||||
const pmiUsC = col3(p.pmi_us - 50, 1.5)
|
||||
|
||||
// VIX: above baseline = risk-off = USD safe haven = bearish EUR = red
|
||||
const vixC = col3(p.vix - base.vix, 2)
|
||||
|
||||
// Yield node colors
|
||||
const us2C = col3(r.us_2y_implied - base.us_2y)
|
||||
const us10C = col3(r.us_10y_implied - base.us_10y)
|
||||
const eu2C = col3(-(r.eu_2y_implied - base.eu_2y)) // EU yield up → EUR/USD up → green
|
||||
const eu2C = col3(-(r.eu_2y_implied - base.eu_2y))
|
||||
const eu10C = col3(-(r.eu_10y_implied - base.eu_10y))
|
||||
|
||||
const diff2C = col3(delta2yVal, 0.02)
|
||||
@@ -335,22 +345,22 @@ function CausalChain({ r, base, p }: { r: ModelResult; base: Params; p: Params }
|
||||
<defs>{COLORS.map(c => mk(`a${c.replace('#', '')}`, c))}</defs>
|
||||
|
||||
{/* US inputs */}
|
||||
<Node x={fedX - 22} y={yIn1} label="CPI US / NFP" col={r.fed_fwd_signal > 0.4 ? '#f87171' : '#94a3b8'} w={98} />
|
||||
<Node x={fedX - 22} y={yIn1} label="CPI US / NFP" col={fedFwdC} w={98} />
|
||||
<Node x={fedX + 30} y={yIn2} label="PMI US" col={pmiUsC} w={70} />
|
||||
<Arr x1={fedX - 8} y1={yIn1 + 14} x2={fedX - 5} y2={yCB - 17} col={fedRateC} w={1.4} />
|
||||
<Arr x1={fedX + 28} y1={yIn2 + 13} x2={fedX + 8} y2={yCB - 17} col={pmiUsC} w={1.1} dashed />
|
||||
<Arr x1={fedX - 8} y1={yIn1 + 14} x2={fedX - 5} y2={yCB - 17} col={fedFwdC} w={1.4} dashed />
|
||||
<Arr x1={fedX + 28} y1={yIn2 + 13} x2={fedX + 8} y2={yCB - 17} col={pmiUsC} w={1.1} dashed />
|
||||
|
||||
{/* EU inputs */}
|
||||
<Node x={ecbX + 22} y={yIn1} label="CPI EU / PMI" col={r.ecb_fwd_signal > 0.4 ? '#34d399' : '#94a3b8'} w={98} />
|
||||
<Arr x1={ecbX + 8} y1={yIn1 + 14} x2={ecbX + 5} y2={yCB - 17} col={ecbRateC} w={1.4} />
|
||||
<Node x={ecbX + 22} y={yIn1} label="CPI EU / PMI" col={ecbFwdC} w={98} />
|
||||
<Arr x1={ecbX + 8} y1={yIn1 + 14} x2={ecbX + 5} y2={yCB - 17} col={ecbFwdC} w={1.4} dashed />
|
||||
|
||||
{/* CB nodes */}
|
||||
<Node x={fedX} y={yCB} label="FED"
|
||||
sub={`taux ${sign(r.fed_rate_pressure)}${r.fed_rate_pressure.toFixed(1)} | ton ${sign(r.fed_fwd_signal)}${r.fed_fwd_signal.toFixed(1)}`}
|
||||
col={fedRateC} w={118} />
|
||||
col={fedC} w={118} />
|
||||
<Node x={ecbX} y={yCB} label="BCE"
|
||||
sub={`taux ${sign(r.ecb_rate_pressure)}${r.ecb_rate_pressure.toFixed(1)} | ton ${sign(r.ecb_fwd_signal)}${r.ecb_fwd_signal.toFixed(1)}`}
|
||||
col={ecbRateC} w={118} />
|
||||
col={ecbC} w={118} />
|
||||
|
||||
{/* FED → US 2Y (solid, rate) and FED → US 10Y (dashed, tone) */}
|
||||
<Arr x1={fedX - 18} y1={yCB + 17} x2={us2X + 8} y2={yYld - 17} col={us2C} w={aw(Math.abs(r.fed_rate_pressure) * 0.085)} />
|
||||
@@ -376,9 +386,9 @@ function CausalChain({ r, base, p }: { r: ModelResult; base: Params; p: Params }
|
||||
<Node x={diff2X} y={yDiff} label="Δ 2Y (taux)" sub={`${r.rate_diff_2y.toFixed(2)}% US−EU`} col={diff2C} w={108} />
|
||||
<Node x={diff10X} y={yDiff} label="Δ 10Y (anticipations)" sub={`${r.rate_diff_10y.toFixed(2)}% US−EU`} col={diff10C} w={114} />
|
||||
|
||||
{/* VIX (left) */}
|
||||
<Node x={vixX} y={yDiff} label="VIX" sub="risk" col="#94a3b8" w={48} />
|
||||
<Arr x1={vixX + 24} y1={yDiff + 8} x2={cX - 68} y2={yFX - 16} col="#94a3b8" w={1.2} />
|
||||
{/* VIX (left) — risk-off = USD safe haven = bearish EUR = red */}
|
||||
<Node x={vixX} y={yDiff} label="VIX" sub={`${p.vix.toFixed(1)}`} col={vixC} w={52} />
|
||||
<Arr x1={vixX + 26} y1={yDiff + 8} x2={cX - 68} y2={yFX - 16} col={vixC} w={aw(Math.abs(p.vix - base.vix) * 0.06)} />
|
||||
|
||||
{/* Differentials → EURUSD */}
|
||||
<Arr x1={diff2X + 12} y1={yDiff + 17} x2={cX - 22} y2={yFX - 22} col={diff2C} w={aw(Math.abs(delta2yVal) * 5)} />
|
||||
|
||||
Reference in New Issue
Block a user