feat: jauges macro + signaux déclencheurs dans card Régime Macro

Partie basse de la card : 5 indicateurs clés expliquant le régime
(VIX, S&P vs 200j MA, Pente 10Y-3M, Cuivre, Or) avec couleur
contextuelle et hint court, puis chips des signaux déclencheurs
du régime dominant issus de scenarios.reasons[dominant].

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-20 06:47:11 +02:00
parent bcd1a3a0d5
commit 2a77007dc3

View File

@@ -620,6 +620,45 @@ export default function Dashboard() {
: dom === 'inflation_shock' ? 'text-orange-400'
: 'text-slate-400'
const ranked = macroInfo?.ranked ?? []
// Key gauges from macroData
const gauges = (macroData as any)?.gauges ?? {}
const reasons: string[] = dom ? ((macroData as any)?.scenarios?.reasons?.[dom] ?? []) : []
// 5 key indicators that explain the regime
const KEY_GAUGES = [
{
key: 'vix', label: 'VIX',
color: (v: number) => v < 18 ? 'text-emerald-400' : v < 25 ? 'text-yellow-400' : 'text-red-400',
fmt: (v: number) => v.toFixed(1),
hint: (v: number) => v < 18 ? '↓ risque bas' : v < 25 ? '↑ alerte' : '↑ crise',
},
{
key: 'spx_vs_200d', label: 'S&P/200j',
color: (v: number) => v >= 0 ? 'text-emerald-400' : 'text-red-400',
fmt: (v: number) => `${v >= 0 ? '+' : ''}${v.toFixed(1)}%`,
hint: (v: number) => v >= 5 ? 'bull fort' : v >= 0 ? 'bull mod.' : 'bear',
},
{
key: 'slope_10y3m', label: 'Pente 10Y-3M',
color: (v: number) => v >= 0.5 ? 'text-emerald-400' : v >= 0 ? 'text-yellow-400' : 'text-red-400',
fmt: (v: number) => `${v >= 0 ? '+' : ''}${v.toFixed(2)}`,
hint: (v: number) => v >= 0.5 ? 'normale' : v >= 0 ? 'plate' : 'inversée',
},
{
key: 'copper', label: 'Cuivre',
color: (v: number, chg: number) => chg >= 0 ? 'text-emerald-400' : 'text-red-400',
fmt: (v: number, chg: number) => `${chg >= 0 ? '+' : ''}${chg.toFixed(2)}%`,
hint: (v: number, chg: number) => chg >= 0 ? '↑ croissance' : '↓ ralentis.',
},
{
key: 'gold', label: 'Or',
color: (v: number, chg: number) => chg >= 1 ? 'text-amber-400' : chg <= -1 ? 'text-emerald-400' : 'text-slate-400',
fmt: (v: number, chg: number) => `${chg >= 0 ? '+' : ''}${chg.toFixed(2)}%`,
hint: (v: number, chg: number) => chg >= 1 ? '↑ refuge' : chg <= -1 ? '↓ risk-on' : '≈ neutre',
},
]
return (
<Link to="/macro" className="card block hover:border-slate-600/60 transition-all cursor-pointer">
<div className="flex items-center justify-between mb-1">
@@ -654,6 +693,40 @@ export default function Dashboard() {
})}
</div>
)}
{/* Key macro gauges */}
{Object.keys(gauges).length > 0 && (
<div className="mt-2 pt-2 border-t border-slate-700/30 space-y-1">
{KEY_GAUGES.map(({ key, label, color, fmt, hint }) => {
const g = gauges[key]
if (!g) return null
const val: number = g.value ?? 0
const chg: number = g.change_pct ?? 0
const c = color(val, chg)
const h = hint(val, chg)
return (
<div key={key} className="flex items-center gap-1.5">
<span className="text-[9px] text-slate-600 w-16 shrink-0">{label}</span>
<span className={clsx('text-[9px] font-mono font-semibold shrink-0', c)}>
{fmt(val, chg)}
</span>
<span className="text-[8px] text-slate-700 truncate">{h}</span>
</div>
)
})}
</div>
)}
{/* Trigger signals for dominant regime */}
{reasons.length > 0 && (
<div className="mt-1.5 flex flex-wrap gap-1">
{reasons.slice(0, 4).map((r: string, i: number) => (
<span key={i} className="text-[8px] bg-blue-900/20 text-blue-400/80 border border-blue-800/30 px-1.5 py-0.5 rounded">
{r}
</span>
))}
</div>
)}
</Link>
)
})()}