feat: options technical agent — IV/skew/term structure validation per trade

- New options_technical_agent.py: rule engine (IVR, skew, term structure, flow)
  + GPT-4o narrative per trade; verdict OK/WARN/ALERT + fit_score
- options_trade_assessments table in DB for Journal badge persistence
- auto_cycle.py step 5.2: assess newly logged trades after log_trade_entries;
  results embedded in cycle report
- suggest_patterns_from_market_context: +iv_context param + explicit IV→strategy
  rules in prompt (IVR<30%→Long, 30-60%→Spread, >60%→no naked long, >80%→short)
- Pre-fetch iv_context at step 1.9 so suggestion step gets strategy rules
- reports.py: /api/reports/assessments/latest + /assessments/{run_id} endpoints
- RapportIA.tsx: "Validation Technique Options" section with per-trade IVBar,
  VerdictBadge, issues list, GPT-4o analysis, optimal strategy suggestion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-20 09:36:35 +02:00
parent 1aadf98fe4
commit 3ee39d5f08
6 changed files with 783 additions and 8 deletions

View File

@@ -1,5 +1,8 @@
from fastapi import APIRouter, HTTPException
from services.database import get_cycle_reports, get_cycle_report, get_latest_cycle_report
from services.database import (
get_cycle_reports, get_cycle_report, get_latest_cycle_report,
get_trade_assessments, get_latest_trade_assessments,
)
router = APIRouter(prefix="/api/reports", tags=["reports"])
@@ -23,3 +26,15 @@ def cycle_report_detail(run_id: str):
if not report:
raise HTTPException(404, "Rapport de cycle introuvable")
return report
@router.get("/assessments/latest")
def assessments_latest(limit: int = 20):
"""Latest options technical assessments (one per trade, for Journal badges)."""
return {"assessments": get_latest_trade_assessments(limit)}
@router.get("/assessments/{run_id}")
def assessments_by_run(run_id: str):
"""Options technical assessments for a specific cycle run."""
return {"assessments": get_trade_assessments(run_id)}