feat: score-history chart on the regime tab
Plots the index, early-warning, and combined scores over time beneath the live gauges, with a 1M/3M/6M/All range toggle and band reference lines — so the trend and any divergence between the scores is visible, not just today's snapshot. - Backend: GET /regime/history + get_regime_history (the three scores per snapshot date from regime_snapshots). - Frontend: recharts line chart, lazy-loaded so recharts ships in its own regime-tab chunk instead of nearly doubling the main bundle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -681,6 +681,30 @@ async def get_regime_monitor(db: AsyncSession) -> dict:
|
||||
return result
|
||||
|
||||
|
||||
async def get_regime_history(db: AsyncSession, days: int = 400) -> list[dict]:
|
||||
"""Daily history of the index, early-warning, and combined scores for the
|
||||
score-over-time chart. One point per snapshot date, ascending."""
|
||||
cutoff = date.today() - timedelta(days=days)
|
||||
res = await db.execute(
|
||||
select(RegimeSnapshot)
|
||||
.where(RegimeSnapshot.date >= cutoff)
|
||||
.order_by(RegimeSnapshot.date.asc())
|
||||
)
|
||||
out: list[dict] = []
|
||||
for row in res.scalars().all():
|
||||
try:
|
||||
data = json.loads(row.breakdown_json)
|
||||
except (TypeError, ValueError):
|
||||
data = {}
|
||||
out.append({
|
||||
"date": row.date.isoformat(),
|
||||
"index": row.total_score,
|
||||
"early_warning": (data.get("early_warning") or {}).get("score"),
|
||||
"combined": (data.get("combined") or {}).get("score"),
|
||||
})
|
||||
return out
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# F1/F3 via grounded LLM (reuses the configured sentiment provider)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user