Sprint 3.1 — Vue Portefeuille Consolidée
- database.py: get_portfolio_exposure() — exposition par classe d'actif + facteur de risque
- database.py: get_pnl_timeline() — courbe P&L cumulé pour equity curve
- Alertes concentration automatiques (>40% par classe, >50% par facteur)
- _RISK_FACTOR_MAP: classification géopolitique/inflation/récession/liquidité/dollar
Sprint 3.2 — Risk Cluster Engine
- database.py: get_risk_clusters() — saturation par facteur + risk_prompt_context
- database.py: get_pattern_correlations() — matrice Pearson sur trades matures
- auto_cycle.py: injection du contexte risque dans le prompt de scoring (Step 3.5)
- ai_analyzer.py: paramètre risk_context dans score_patterns_with_context()
- Pénalisation automatique des patterns sur facteurs saturés dans le scoring GPT
Sprint 3.3 — Position Sizing Kelly Fractionnel
- database.py: compute_kelly_sizing() — f* = (p×G - (1-p))/G, Kelly ×33% par défaut
- Ajustement cluster: sizing ÷2 si facteur saturé
- Ajustement fiabilité: sizing ÷2 si win_rate historique <40% (≥5 trades)
- JournalDeBord.tsx: colonne "Kelly" avec KellyCell (% + €, ajustements signalés)
- routers/risk.py: GET /api/risk/kelly/{pattern_id}
Sprint 3.4 — Tableau de Bord Risque Global
- database.py: get_risk_dashboard() — HHI, score diversification, drawdown attendu, recommandation
- database.py: _build_risk_recommendation() — alerte Risk Committee automatique
- RiskDashboard.tsx: nouvelle page — jauges concentration, courbe P&L, corrélations, recommandation
- Dashboard.tsx: banner d'alerte concentration sur le Cockpit avec lien vers /risk
- routers/risk.py: GET /api/risk/exposure|timeline|clusters|correlations|dashboard
- App.tsx + Sidebar.tsx: route /risk + entrée menu Risk Dashboard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
52 lines
1.5 KiB
Python
52 lines
1.5 KiB
Python
from fastapi import APIRouter, Query
|
|
from services.database import (
|
|
get_portfolio_exposure,
|
|
get_pnl_timeline,
|
|
get_risk_clusters,
|
|
get_pattern_correlations,
|
|
compute_kelly_sizing,
|
|
get_risk_dashboard,
|
|
)
|
|
|
|
router = APIRouter(prefix="/api/risk", tags=["risk"])
|
|
|
|
|
|
@router.get("/exposure")
|
|
def portfolio_exposure():
|
|
"""Exposure by asset class + risk factor for open positions."""
|
|
return get_portfolio_exposure()
|
|
|
|
|
|
@router.get("/timeline")
|
|
def pnl_timeline(days: int = Query(default=90, ge=7, le=365)):
|
|
"""Daily aggregated P&L timeline for equity curve."""
|
|
return {"timeline": get_pnl_timeline(days=days)}
|
|
|
|
|
|
@router.get("/clusters")
|
|
def risk_clusters():
|
|
"""Risk factor clustering + saturation detection + prompt context."""
|
|
return get_risk_clusters()
|
|
|
|
|
|
@router.get("/correlations")
|
|
def pattern_correlations():
|
|
"""Pearson correlation matrix between patterns (mature trades only)."""
|
|
return get_pattern_correlations()
|
|
|
|
|
|
@router.get("/kelly/{pattern_id}")
|
|
def kelly_sizing(
|
|
pattern_id: str,
|
|
capital: float = Query(default=10000.0, ge=100, le=10_000_000),
|
|
fractional: float = Query(default=0.33, ge=0.1, le=1.0),
|
|
):
|
|
"""Fractional Kelly position sizing for a pattern."""
|
|
return compute_kelly_sizing(pattern_id=pattern_id, capital_available=capital, fractional=fractional)
|
|
|
|
|
|
@router.get("/dashboard")
|
|
def risk_dashboard():
|
|
"""Full portfolio risk snapshot: concentration, diversification, expected drawdown, recommendation."""
|
|
return get_risk_dashboard()
|