fix: PMI US — coloration dynamique + ajout dans fed_fwd_signal

PMI US colorisé rouge/vert selon déviation vs 50 dans le SVG
Flèche PMI US → FED prend la même couleur que le nœud
PMI US ajouté dans fed_fwd_signal (+0.18 par pt) pour symétriser avec PMI EU
Les deux canaux PMI US sont maintenant visibles : CB expectations (→10Y) + direct c_pmi (croissance diff)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-26 23:25:48 +02:00
parent 91e624aa56
commit 6b850091eb

View File

@@ -83,6 +83,7 @@ function compute(p: Params, base: Params): ModelResult {
-p.fed_tone * 1.2
+ p.cpi_us_surprise / 0.1 * 0.50 // hot CPI → more hikes expected
+ p.nfp_surprise / 100 * 0.35 // strong jobs → Fed stays restrictive
+ (p.pmi_us - 50) / 5 * 0.18 // strong activity → Fed stays restrictive longer
const ecb_fwd_signal =
-p.ecb_tone * 1.2
@@ -268,7 +269,7 @@ function ToneSelector({ label, value, onChange }: { label: string; value: number
// Solid arrows = rate channel (taux directeurs → 2Y)
// Dashed arrows = tone/expectations channel (ton + données → 10Y)
function CausalChain({ r, base }: { r: ModelResult; base: Params }) {
function CausalChain({ r, base, p }: { r: ModelResult; base: Params; p: Params }) {
const sign = (v: number) => v > 0 ? '+' : ''
const delta2yVal = r.rate_diff_2y - (base.us_2y - base.eu_2y)
@@ -278,9 +279,10 @@ function CausalChain({ r, base }: { r: ModelResult; base: Params }) {
Math.abs(v) < threshold ? '#94a3b8' : v > 0 ? '#f87171' : '#34d399'
const fedRateC = col3(r.fed_rate_pressure, 0.3)
const fedFwdC = col3(r.fed_fwd_signal, 0.5)
const ecbRateC = col3(-r.ecb_rate_pressure, 0.3) // flipped: ECB hawkish → EUR up → green
const ecbFwdC = col3(-r.ecb_fwd_signal, 0.5)
// PMI US: positive deviation (> 50) = US strong = bearish EUR = red
const pmiUsC = col3(p.pmi_us - 50, 1.5)
const us2C = col3(r.us_2y_implied - base.us_2y)
const us10C = col3(r.us_10y_implied - base.us_10y)
@@ -334,9 +336,9 @@ function CausalChain({ r, base }: { r: ModelResult; base: Params }) {
{/* 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 + 30} y={yIn2} label="PMI US" col="#94a3b8" w={70} />
<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="#94a3b8" w={1.1} 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} />
@@ -593,7 +595,7 @@ export default function EuroSimulator() {
))}
</div>
<CausalChain r={r} base={base} />
<CausalChain r={r} base={base} p={p} />
<div className="mt-2 text-[10px] text-slate-600 text-center">
Base: EURUSD {base.eurusd.toFixed(4)} · US 2Y {base.us_2y.toFixed(2)}% · US 10Y {base.us_10y.toFixed(2)}% · Bund 10Y {base.eu_10y.toFixed(2)}%