cycleTrades inclut tous les trades du scoring run (anciens patterns
re-scorés inclus). On filtre par cyclePatternIds pour ne compter
que les trades issus de patterns ajoutés pendant ce cycle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GeoRadar:
- Filtre période : Aujourd'hui / 7j / 30j / Toutes
- Tri : Impact ↓/↑ · Récentes/Anciennes
- Compteur de news filtrées
Dashboard:
- Remplace Super Contexte par "Top Trades" (top 5 par PnL%)
avec ticker, stratégie, date d'entrée, PnL%
- Card "Scores Patterns" : ajoute la date d'ajout (created_at)
sous le nom de chaque pattern
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
For patterns added in the cycle but below log threshold, display the
recommended_trade (underlying + strategy + score) from scoreMap instead
of just the pattern name. Pattern name moves to secondary small italic line.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PnL simulated: Investi ~ et P&L € calculés avec entry_price quand
capital_invested est null (label ~ pour indiquer estimation)
- Dernier Cycle: rename trades loggés -> trades ajoutés + mini mention
des non-loggés quand patternsAdded > tradesLogged
- Trades du cycle: supprime le grand header +N Trades (info déplacée
dans Dernier Cycle); layout inversé — trade en primaire, pattern
en secondaire petit en dessous; trades non loggés affichés en gris
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Backend: get_status() now resolves scoring_run_id by querying
trade_entry_prices within the cycle time window, fixing the mismatch
between cycle run_id and the id actually written to trades
- Dashboard: Trades du cycle filters by scoring_run_id (no stale fallback)
- Dashboard: Pattern du cycle shows only patterns added in last cycle
(created_at >= started_at), renamed from Top Patterns
- Dashboard: Dernier Cycle now shows 4 stats (patterns/scorés/loggés/fermés)
+ IA commentary snippet
- Dashboard: P&L simulated mode bottom half shows open/closed/capital/profit
- Dashboard: Régime Macro shows top 4 scenario score bars
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PnL card: rename to P&L, add Simulé/Portfolio toggle (localStorage),
simulated shows target/stop alert counts, portfolio shows invested € + P&L €
- Risk card: add asset class allocation horizontal bars (bullish=color/bearish=red)
from simPortfolioRisk.concentration, conflicts badge
- Dernier Cycle: full bilan layout — patterns added / scored / trades logged
in 3 mini-stat boxes
- Trades du cycle: show direction, ticker, strategy, PnL%, score for each trade
- Top Patterns: replaces Meilleur Pattern — shows top 4 scored with rank + ticker
- Top News: replaces Patterns Actifs — useGeoNews sorted by impact_score,
top 3 with title + impact bar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract TradeCard/TradeRow/IBKRTicket + TradeIdeasTab self-contained
component to frontend/src/components/TradeIdeas.tsx
- Dashboard: remove trade ideas section, MtM section, all related hooks/
state/computations; replace Signaux Géo mini-card with Trades du cycle;
add News géo link on Risque Géopolitique card
- JournalDeBord: add Idées de trade tab (left of Ouverts) using TradeIdeasTab
- Config: reorganize into 5 tabs — IA & Analyse, Auto-Cycle & Logging,
Sources, Journal & Sortie, Profils de risque; expose min_score_threshold
as a prominent slider in the Auto-Cycle tab
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dashboard: insert 2 rows of 4 mini-cards between top row and trade ideas
- Row 1: PnL Simulé, Risque Simulé, Dernier Cycle, Régime Macro
- Row 2: Super Contexte, Signaux Géo, Meilleur Pattern, Patterns Actifs
- All cards link to underlying pages via react-router Link
Journal: add 'Non loggés' tab exposing trades suggested by cycle
but skipped because no risk profile was matched
- New skipped_trades table (auto-created on backend restart)
- log_trade_entries() persists each skip with score/gain/asset_class
- GET /api/journal/skipped-trades + useSkippedTrades hook
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- portfolio_risk.py: add _infer_asset_class() with ticker→asset_class map
covering energy/metals/agri/indices/forex/rates futures, ETFs, forex pairs,
exchange prefixes (NSE:). Fallback applied when JOIN finds no match (orphaned
pattern_id after re-seed). Fixes "unknown 100%" shown in screenshot.
- RiskDashboard.tsx: add Portefeuille Réel / Simulé toggle at top.
New SimRiskPanel component with KPI row + concentration bars + conflict cards
+ AI recommendations — all visible inline in Risk Dashboard.
Red badge on Simulé tab when danger alerts exist.
- JournalDeBord.tsx: remove standalone Risque Sim. tab (moved to Risk Dashboard).
Replace with a red banner in summary cards when conflicts are detected,
pointing user to Risk Dashboard → Simulé.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- auto_cycle.py: replace _log with logger (NameError at lines 484/489)
- auto_cycle.py: normalize underlying via _normalize_ticker before _resolve_ticker
so WHEAT→ZW=F→WEAT and EUR/USD→EURUSD=X→FXE reach the IV watchlist correctly
- iv_engine.py: _resolve_ticker now strips slash-format forex (EUR/USD→EURUSD=X)
before _PROXY lookup, fixing yfinance 500/404 spam from get_atm_iv
- database.py: _fetch in log_trade_entries uses _normalize_ticker (not _normalize_yf_ticker)
so commodity aliases like WHEAT→ZW=F are applied at price-fetch time
- ai_analyzer.py: max_workers=1 for batch scorer — parallel workers both slept and
retried simultaneously after 429, causing repeated bursts; sequential fixes the pattern
- journal.py + JournalDeBord.tsx: add price_warning field (no_price_data/no_entry_price/
no_live_price) with visible ⚠ badge and amber color on affected ticker/price cells
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DB: 9 new columns on trade_entry_prices (status, closed_at, close_reason,
close_note, pnl_realized, close_price, target_pct, stop_loss_pct, signal_threshold)
via ALTER TABLE migration; close_trade(), get_closed_trades(),
update_trade_exit_params() helpers; exit_defaults config key
- Backend: PATCH /trades/{id}/close, PATCH /trades/{id}/exit-params,
GET/PUT /exit-defaults, GET /closed-trades with win-rate/avg-PnL stats;
trade-mtm now computes alert_type (target_reached|stop_loss) per trade
- Journal: new "Fermés" tab with closed trades table + stats banner (win rate,
avg PnL, total PnL, best trade); open trades show Cible/Stop progress bar +
🎯/🛑 alert badges + 1-click close modal (price, reason, note)
- Config: new "Paramètres de sortie" panel — target_pct, stop_loss_pct,
signal_reversal_mode, signal_reversal_threshold with live sliders
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Hook ai_score_news_batch() into /api/geo/news so every news fetch is enriched
by GPT-4o-mini: corrected impact_score, ai_dir_energy/metals/indices, ai_resolution
(ceasefire/peace deal flag), ai_insight (1 French sentence). Gracefully no-ops
when OpenAI is not configured.
Add _compute_ai_alignment() in geo_analyzer: for each pattern compares the news
AI directional signals against the pattern's expected_move direction and produces
a -25..+25 bonus injected into similarity/relevance scores. Contra-signals
(e.g. peace deal → oil bearish while pattern expects oil spike) are flagged.
Frontend GeoRadar: PatternRelevanceCard shows AI alignment badge (green = aligned,
red = contra-signal) + base relevance diff + AI insights. NewsCard shows ai_insight,
directional arrows per asset class (⛽↑ 🥇↓) and resolution badge when expanded.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace 1-day change_pct with weighted blend (20% 1d / 50% 5d / 30% 10d)
for all 20 scored signals. Add Bayesian prior from rolling 25-day history
(weight 15%→45%) and a 10-point persistence threshold before regime switch.
Bootstrap on first load: replays last 20 trading days via yf.download batch
(45d) to pre-populate _regime_history, so stability is visible immediately.
Frontend: adds 'stable Xj' badge and history depth indicator on regime banner.
Doc: updates v4.0→v4.1, rewrites Étape 1 Régime Macro and glossary entry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds full Interactive Brokers order ticket to both the Dashboard cockpit
and the Journal de Bord MtM expanded rows. Each ticket shows the
underlying, computed strike in dollars, estimated expiry date (nearest
Friday), per-leg BUY/SELL CALL/PUT breakdown, order type LIMIT, budget
and target.
Also adds Strike and DTE columns to the MtM table and persists
strike_guidance + expiry_days_at_entry in trade_entry_prices.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend:
- DB: add system_logs table (level/source/cycle_id/ticker/message) and
iv_watchlist table (ticker/added_by/is_active); seed builtin 18 tickers
- DBLogHandler attached at startup — all WARNING+ logs auto-persist to DB
- log_system_event() helper for structured manual events
- New router /api/logs: GET with filters (level, source, cycle_id, ticker,
date range), GET /sources, GET /cycles for dropdowns, DELETE /clear
- iv_watchlist now read from DB instead of hardcoded constant; options_vol
watchlist/refresh/bootstrap endpoints all use get_watchlist_tickers()
- New endpoints: POST/DELETE /options-vol/watchlist-tickers/{ticker} to
add/remove tickers; adding triggers background 1-year bootstrap
- auto_cycle: after log_trade_entries(), auto-detect new underlying proxies
not yet in watchlist, add them and bootstrap their IV history
Frontend:
- New page SystemLogs (/logs): log table with level/source/cycle/ticker/date
filters, color-coded rows, expandable JSON details, auto-refresh 30s
- Options Lab: WatchlistManager section — add ticker input, chip list with
builtin/auto/manual color coding, remove button for non-builtins
- Sidebar: Logs Système nav link (ScrollText icon)
- useApi: useSystemLogs, useLogSources, useLogCycles, useClearLogs,
useWatchlistTickers, useAddWatchlistTicker, useRemoveWatchlistTicker
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- iv_engine/options_vol: when get_atm_iv() returns None (yfinance chain unavailable),
fall back to most recent iv_history row so IV Rank is always computable from
bootstrapped data; live vs history source tagged as iv_source field
- Dashboard: build mtmMap from tradeMtmData.trades (trade_entry_prices, cycle auto-log)
keyed by pattern_id; getAddedInfo() falls back to mtmMap so Entrée/Durée columns
populate automatically after each AI cycle without manual portfolio add
- OptionsLab: show '~' prefix and 'IV estimée' label when IV comes from history fallback;
fix near-invisible text-slate-700 on 'Sans historique' section header
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Toggle between Cards (existing) and Grid (new) via icons next to Top N.
Grid view: compact table with score bar, EV, gain, max/cible, profil,
macro bias per row. Click any row to expand inline (full-width) showing
score justification, contra-signals, macro context, and add button.
Added 'Tous' option (topN=0) to show all scored patterns without limit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- JournalDeBord: trade rows now expand inline (full-width) instead of
PostmortemPanel appearing below the whole table. Click anywhere on a
row to toggle. Period selector extended to 15/30/60/90j.
- Config: added Rétention Journal (30/60/90/180j) and Seuil Maturité
(20/30/35/50%) controls, wired to the Appliquer button.
- Backend: journal_retention_days and maturity_threshold_pct read from
config table; seeded at startup with defaults 90d / 35%. get_status()
now returns both values so Config page can initialise correctly.
- cycle.py: CycleConfigRequest accepts and validates both new params.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- main.py startup: if DB has no openai_api_key but OPENAI_API_KEY env var is set, auto-save it so cycle trigger returns 200 instead of 400
- Config.tsx: move NextRunCountdown outside cs?.last_cycle block so it renders even when no cycle has run yet
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- auto_cycle.py: next_run_at now set to future timestamp (now + interval)
instead of current time — was always showing wrong value
- Config.tsx: NextRunCountdown component shows live countdown (updates
every second) + absolute local time, only visible when auto-cycle enabled
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>
- Add ScorePillars: compact 4-pillar mini-bars always visible under score
bar (📰/📅/📈/⚖️ with color-coded fill — instant visual of pillar distribution)
- Add ScoreJustification: replaces old per-click BucketBreakdown with full
text reasoning shown at once — key_catalyst highlighted in yellow callout,
each pillar shows score + GPT-4o comment + all sub-pillars with comments
- Rename expand button to "↳ Justification du score" for clarity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>