feat: 6 AI desks complets — fundamental, report, sentiment (options triggers)

- Fundamental Desk: filtre corporate news (layoffs, M&A, earnings, credit)
  avec prompt dédié + dedup sémantique
- Report Desk: wiring desk config (days, min_importance, system_prompt)
- Sentiment Desk: 5 signaux VIX/SKEW pour options lab
  (vix_level thresholds, vix_spike %, vix_term_structure, vvix_extreme, skew_extreme)
  Chaque event contient options_note actionnable (vente puts, straddles, calendar spreads)
- check_new_market_events() couvre les 6 sources, charge desk configs dynamiquement
- Signal catalog: 12 signaux (7 technical + 5 sentiment), filtrés par desk_type dans UI
- AIDesks.tsx: FundamentalConfig + ReportConfig + SignalToggle filtré par desk type
- 3 nouveaux desks seedés dans init_db (idempotent)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-26 09:21:29 +02:00
parent 97706dea7b
commit a12d7a1ef3
4 changed files with 670 additions and 90 deletions

View File

@@ -76,20 +76,71 @@ SIGNAL_CATALOG: List[Dict[str, Any]] = [
"id": "macd_crossover",
"label": "Croisement MACD",
"description": "Croisement de la ligne MACD avec la ligne signal",
"desk_type": "technical",
"params": {
"fast": {"type": "int", "label": "EMA rapide", "default": 12, "min": 5, "max": 30},
"slow": {"type": "int", "label": "EMA lente", "default": 26, "min": 15, "max": 60},
"signal": {"type": "int", "label": "Signal", "default": 9, "min": 3, "max": 20},
},
},
# ── Sentiment signals ───────────────────────────────────────────────────
{
"id": "vix_level",
"label": "VIX — franchissement de seuil",
"description": "Signal quand le VIX franchit un niveau clé (20, 25, 30, 35, 45)",
"desk_type": "sentiment",
"params": {
"thresholds": {"type": "multi_int", "label": "Niveaux VIX", "default": [20, 25, 30, 35, 45]},
},
},
{
"id": "vix_spike",
"label": "VIX — spike journalier",
"description": "VIX progresse de X% ou plus en une séance",
"desk_type": "sentiment",
"params": {
"min_pct_change": {"type": "float", "label": "Variation min %", "default": 15.0, "min": 5.0, "max": 50.0},
},
},
{
"id": "vix_term_structure",
"label": "VIX — inversion structure de terme",
"description": "VIX9D > VIX (peur concentrée court terme)",
"desk_type": "sentiment",
"params": {
"inversion_threshold": {"type": "float", "label": "Ratio VIX9D/VIX min", "default": 1.05, "min": 1.0, "max": 1.5},
},
},
{
"id": "vvix_extreme",
"label": "VVIX extrême",
"description": "VVIX (volatilité du VIX) dépasse un seuil",
"desk_type": "sentiment",
"params": {
"threshold": {"type": "float", "label": "Seuil VVIX", "default": 100.0, "min": 80.0, "max": 150.0},
},
},
{
"id": "skew_extreme",
"label": "CBOE SKEW extrême",
"description": "SKEW index très haut (protection tail coûteuse) ou très bas (complaisance)",
"desk_type": "sentiment",
"params": {
"low_threshold": {"type": "float", "label": "Seuil bas", "default": 120.0, "min": 100.0, "max": 130.0},
"high_threshold": {"type": "float", "label": "Seuil haut", "default": 145.0, "min": 135.0, "max": 170.0},
},
},
]
# ── Schemas ───────────────────────────────────────────────────────────────────
DESK_TYPES = {"news", "fundamental", "technical", "eco", "report", "sentiment"}
class AIDeskUpsert(BaseModel):
name: str
type: str
type: str # one of DESK_TYPES
active: bool = True
system_prompt: str = ""
instruments: List[str] = []