feat: institutional reports — CFTC COT + EIA petroleum weekly

- New institutional_reports table (DB) with importance, signals per asset class, key points, absorption tracking
- cot_fetcher.py: CFTC Socrata API (6dca-aqww), 7 instruments (Gold/Silver/Copper/WTI/NatGas/SP500/EURUSD), net positioning + 52-week z-score
- eia_fetcher.py: EIA API v2, 4 series (crude/Cushing/gasoline/distillates), WoW surprise detection
- institutional.py router: GET /reports, GET /reports/{id}, POST /refresh, GET /stats
- institutional_scheduler.py: weekly auto-fetch (COT Saturdays, EIA Wednesday afternoons)
- ai_analyzer.py: build_institutional_block() + institutional_block param injected into AI scoring prompt
- auto_cycle.py: inject institutional block into suggestion + scoring, absorption tracking via keyword overlap after each cycle commentary
- InstitutionalReports.tsx: full page with filter bar (type/category/importance/period), cards with key point bullets, EXTREME alerts highlighted, signal badges, absorption badge, trading implications, expandable detail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-22 13:45:07 +02:00
parent 4423ad91db
commit 3edbd6b0b7
12 changed files with 1228 additions and 2 deletions

View File

@@ -4,6 +4,7 @@ from routers import market_data, geopolitical, options, backtest, ai, portfolio,
from routers import logs as logs_router
from routers import var as var_router
from routers import reports as reports_router
from routers import institutional as institutional_router
from services.database import init_db, get_config, cleanup_stale_running_cycles
import os
import logging
@@ -80,6 +81,9 @@ def startup():
from services.var_scheduler import start_var_scheduler, start_pnl_scheduler
start_var_scheduler()
start_pnl_scheduler()
# Start institutional reports weekly scheduler (COT Fridays, EIA Wednesdays)
from services.institutional_scheduler import start_institutional_scheduler
start_institutional_scheduler()
@app.on_event("shutdown")
@@ -89,6 +93,8 @@ def shutdown():
from services.var_scheduler import stop_var_scheduler, stop_pnl_scheduler
stop_var_scheduler()
stop_pnl_scheduler()
from services.institutional_scheduler import stop_institutional_scheduler
stop_institutional_scheduler()
app.include_router(market_data.router)
@@ -110,6 +116,7 @@ app.include_router(risk_router.router)
app.include_router(logs_router.router)
app.include_router(var_router.router)
app.include_router(reports_router.router)
app.include_router(institutional_router.router)
@app.get("/")