IV Rank was stuck at 50 for all tickers because the formula returns 50.0
when iv_max == iv_min (not enough historical snapshots). Added:
- bootstrap_iv_history(): downloads 1y of closes per ticker, computes
30d rolling realized vol (annualized), saves each day to iv_history
- POST /api/options-vol/bootstrap-history endpoint (runs in background)
- OptionsLab: auto-detect when IV Rank needs bootstrapping and show
an amber banner with one-click "Initialiser historique" button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sprint 2.1 — Pattern Reliability Score
- database.py: get_pattern_reliability() — win_rate × log(n+1) sur trades matures (≥35% horizon)
- database.py: get_all_pattern_reliability_map() pour injection rapide dans les prompts
- ai_analyzer.py: inject reliability_map dans suggest_patterns (patterns fiables mis en avant)
- auto_cycle.py: charge reliability_map avant suggestion et le passe au suggéreur
- routers/analytics.py: GET /api/analytics/reliability
- PatternEditor.tsx: ReliabilityBadge sur chaque card + usePatternReliability hook
- useApi.ts: usePatternReliability, useCalibration hooks
Sprint 2.2 — Contre-thèses & Invalidation Triggers
- database.py: migration ALTER TABLE — counter_thesis, invalidation_trigger, invalidation_probability
- database.py: save_custom_pattern() persiste les 3 nouveaux champs
- ai_analyzer.py: counter_thesis + invalidation_trigger + invalidation_probability dans le JSON schema
- auto_cycle.py: détection automatique des triggers d'invalidation contre les news (keyword match)
- routers/analytics.py: GET /api/analytics/invalidation-alerts
- PatternEditor.tsx: affichage contre-thèse dans les cards + champs dans le formulaire
- PatternEditor.tsx: affichage dans AiSuggestModal (suggestions IA)
- routers/patterns.py: PatternRequest inclut les 3 nouveaux champs
Sprint 2.3 — Calibration probabiliste & Demi-vie KB
- database.py: migration — predicted_probability sur pattern_score_history
- database.py: save_pattern_scores() stocke probability du pattern à chaque scoring run
- database.py: get_calibration_data() — Brier score + buckets de calibration par décile
- database.py: expires_at + confidence_decay_days sur knowledge_base
- database.py: decay_kb_confidence() — decay automatique + archivage à 0
- auto_cycle.py: decay_kb_confidence() appelé au début de chaque cycle (non-bloquant)
- routers/analytics.py: GET /api/analytics/calibration + POST /api/analytics/kb/decay
- frontend/src/pages/Analytics.tsx: nouvelle page — tableau fiabilité + calibration Brier
- App.tsx + Sidebar.tsx: route /analytics + entrée menu
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- knowledge.py: trade_line crash when pnl_pct is None in dict
(t.get('pnl_pct',0) returns None if key exists with None value — use 'or 0')
- database.py: cleanup_stale_running_cycles() marks any 'running' cycle
as 'error' on startup (uvicorn reload mid-cycle left status stuck)
- main.py: call cleanup_stale_running_cycles() at startup with warning log
- database.py: _normalize_ticker() converts GPT-4o exchange:symbol format
(NSE:RELIANCE → RELIANCE.NS, BSE:X → X.BO, etc.) so yfinance stops
spamming 404 errors for every MTM request
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- database.py: add delete_ai_report(), delete_reasoning_state(), delete_kb_entry()
- reasoning.py: DELETE /api/reasoning/reports/{id}
- knowledge.py: DELETE /api/knowledge/history/{id} and /entries/{id}
- useApi.ts: useDeleteAiReport, useDeleteReasoningState, useDeleteKbEntry hooks
- RapportIA.tsx: trash icon on hover in archived reports sidebar
- SuperContexte.tsx: trash icon on hover for history versions and KB entries;
both propagate onDelete through CategorySection down to KbEntry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- knowledge.py: classify trades by maturity before building synthesis
prompt; only mature trades (≥35% elapsed) contribute to P&L stats
and conclusions; immature trades listed for transparency only
- Add 6h staleness gate on POST /synthesize (force=true to override)
- System prompt now includes hard timing rule: GPT-4o must not revise
existing conclusions because of newly-added immature trades
- useApi.ts: useSynthesizeKnowledge accepts force boolean param
- SuperContexte.tsx: shows amber notice with age when skipped + offers
"Force quand même" button; success banner uses new response shape
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>