feat: Phase 4+5 — price discovery status + replay historique

Phase 4 — Price Discovery Status (la pièce maîtresse) :
- price_discovery.py (nouveau) : capture_price_snapshots() sauve les prix des tickers
  liés à chaque news scorée (energy→BZ=F/NG=F, metals→GC=F/HG=F, indices→^GSPC/IWM)
- compute_absorptions() mesure combien du mouvement attendu s'est déjà produit
  (status: not_yet_priced <30% / partially_priced 30-80% / fully_priced >80%)
- build_price_discovery_block() → bloc prompt avec opportunités classées
- database.py : table news_price_snapshots + save/get/purge fonctions
- auto_cycle.py : capture après ai_score_news_batch, compute avant suggestions,
  block injecté dans suggestion + scoring prompts + context snapshot
- ai_analyzer.py : param price_discovery_block dans suggest + score

Phase 5 — Replay historique :
- cycle.py : POST /api/cycle/contexts/{run_id}/replay — recharge le snapshot historique
  et relance suggest_patterns_from_market_context avec le contexte original
- useApi.ts : hook useReplayCycle
- SystemLogs.tsx : bouton "Rejouer ce cycle" dans onglet Contexte IA avec champ
  notes, résultats inline (liste des patterns générés), section price_discovery
  ouverte par défaut en rouge

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-20 16:58:57 +02:00
parent 9c0ebbd138
commit a21699805b
7 changed files with 499 additions and 15 deletions

View File

@@ -882,6 +882,12 @@ export const useCycleContextSnapshot = (runId: string | null) =>
staleTime: 300_000,
})
export const useReplayCycle = () =>
useMutation({
mutationFn: ({ runId, notes }: { runId: string; notes?: string }) =>
api.post(`/cycle/contexts/${runId}/replay`, { override_notes: notes ?? null }).then(r => r.data),
})
// ── IV Watchlist Management ───────────────────────────────────────────────────
export const useWatchlistTickers = () =>