feat: macro gauge DB + regime triggers + date-aware instrument snapshot

DB:
- New table macro_gauge_snapshots (daily snapshot of all 28+ gauges + dominant + scores)
- save_macro_gauge_snapshot / get_macro_gauge_snapshot_at / get_macro_gauge_history
- Auto-save once per calendar day on every macro-regime fetch (not just force=True)

API:
- GET /api/market/macro-gauges/at?date=YYYY-MM-DD — nearest snapshot ≤ date
- GET /api/market/macro-gauges/history?days=N

Detector (_check_macro_gauges in Eco Desk):
- Regime transition events (goldilocks→stagflation etc.) with severity scoring
- Yield curve inversion / désinversion (slope_10y3m sign change)
- DXY shock (% change over lookback window)
- Credit stress (HYG drop threshold)
- Gold/Copper ratio regime crossings

InstrumentDashboard:
- macroAtDate state: fetches /api/market/macro-gauges/at when crosshair date ≠ last date
- RegimeCard uses historical macro regime when on a past date
- MacroGaugePanel: full breakdown of all gauges by bloc (liquidité, crédit, énergie...)
  visible only when on a historical date — shows value + change_pct + regime scores bar

AIDesks: added fundamental + sentiment to AIDesk type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-26 09:34:35 +02:00
parent a12d7a1ef3
commit 85eb864584
5 changed files with 513 additions and 5 deletions

View File

@@ -123,6 +123,8 @@ def macro_regime(force: bool = False):
_macro_cache["data"] = result
_macro_cache["ts"] = now
today = now.strftime("%Y-%m-%d")
if force:
# Build a compact gauge summary (key → value + change_pct) for the journal
gauges_summary = {
@@ -138,4 +140,31 @@ def macro_regime(force: bool = False):
gauges_summary=gauges_summary,
)
# Always persist full snapshot once per calendar day (all gauges + regime)
from services.database import save_macro_gauge_snapshot, macro_gauge_snapshot_exists_today
if force or not macro_gauge_snapshot_exists_today():
save_macro_gauge_snapshot(
snapshot_date=today,
gauges=gauges,
dominant=scenarios.get("dominant", "incertain"),
regime_scores=scenarios.get("scores", {}),
)
return result
@router.get("/macro-gauges/at")
def macro_gauges_at(date: str = Query(..., description="YYYY-MM-DD")):
"""Return the macro gauge snapshot at or before a given date."""
from services.database import get_macro_gauge_snapshot_at
snap = get_macro_gauge_snapshot_at(date)
if not snap:
return {"snapshot_date": None, "gauges": {}, "dominant": "incertain", "regime_scores": {}}
return snap
@router.get("/macro-gauges/history")
def macro_gauges_history(days: int = Query(30, ge=1, le=365)):
"""Return gauge snapshots for the last N days (daily, most recent first)."""
from services.database import get_macro_gauge_history
return get_macro_gauge_history(days=days)