feat: Phase 2 — Pattern Reliability, Contre-thèses & Calibration probabiliste

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>
This commit is contained in:
OpenSquared
2026-06-17 16:50:53 +02:00
parent 9a6b6f70b1
commit f09c5b8ee7
11 changed files with 718 additions and 14 deletions

View File

@@ -727,6 +727,7 @@ def suggest_patterns_from_market_context(
macro_regime: Optional[Dict] = None,
geo_score: Optional[Dict] = None,
portfolio_lessons: Optional[Dict] = None,
reliability_map: Optional[Dict] = None,
) -> List[Dict]:
"""Ask GPT-4o to propose new patterns based on current geo/market + macro regime context."""
top_news = sorted(news, key=lambda x: x.get("impact_score", 0), reverse=True)[:12]
@@ -810,8 +811,30 @@ Leçons clés :
Évite les erreurs identifiées dans les pertes. Privilégie les types de thèses qui ont fonctionné.
"""
reliability_block = ""
if reliability_map:
top_reliable = sorted(reliability_map.values(), key=lambda r: -r["reliability_score"])[:5]
bottom_reliable = [r for r in sorted(reliability_map.values(), key=lambda r: r["reliability_score"]) if r["trade_count"] >= 3][:3]
lines = []
for r in top_reliable:
lines.append(
f"{r['pattern_name']}: WR={r['win_rate_pct']}% | {r['trade_count']} trades | "
f"avgPnL={r['avg_pnl_pct']:+.1f}% | fiabilité={r['reliability_score']:.2f}"
)
for r in bottom_reliable:
lines.append(
f"{r['pattern_name']}: WR={r['win_rate_pct']}% | {r['trade_count']} trades | "
f"avgPnL={r['avg_pnl_pct']:+.1f}% → À ÉVITER ou reformuler"
)
if lines:
reliability_block = (
"\n## 📊 FIABILITÉ HISTORIQUE DES PATTERNS (trades matures uniquement)\n"
+ "\n".join(lines)
+ "\n⚠️ Inspire-toi des patterns fiables. Évite de reproduire les patterns en bas de liste.\n"
)
user = f"""Tu es un stratège géopolitique et financier senior.
{macro_block}{geo_block}{lessons_block}
{macro_block}{geo_block}{lessons_block}{reliability_block}
## Actualités géopolitiques du moment (triées par impact)
{news_block}
@@ -847,6 +870,9 @@ Retourne UNIQUEMENT ce JSON:
"expected_move_pct": <float, RENDEMENT OPTION MOYEN en % pour ce pattern, levier inclus. Typiquement 50-300%.>,
"probability": <float 0-1>,
"horizon_days": <int>,
"counter_thesis": "<1-2 phrases: principal scénario adverse qui invaliderait ce pattern — sois spécifique (ex: accord de paix inattendu, données CPI sous 3%, etc.)>",
"invalidation_trigger": "<événement précis et mesurable à surveiller — ex: 'prix pétrole < 70$/b 3j consécutifs', 'FOMC hawkish surprise', 'cessez-le-feu Russie-Ukraine'>",
"invalidation_probability": <float 0-1, probabilité que ce trigger d'invalidation se réalise dans l'horizon>,
"suggested_trades": [
{{
"strategy": "<Long Call|Long Put|Bull Call Spread|Bear Put Spread|Long Straddle>",