feat: 4 remaining institutional reports — Earnings, VX curve, Central Bank RSS, Sentiment

New fetchers (no API keys required):
- earnings_fetcher.py: yfinance EPS calendar + surprise tracking for 23 geo-relevant tickers
- vx_fetcher.py: VIX term structure (^VIX/^VXV/^VXMT) + CBOE delayed futures, regime detection
- central_bank_fetcher.py: Fed + ECB RSS feeds, keyword-based hawkish/dovish classification
- sentiment_fetcher.py: CNN Fear & Greed (primary) + NAAIM + AAII (optional fallbacks)

Wiring:
- institutional_scheduler.py: all 4 now scheduled daily (≥08:00 UTC), deduplicated per day
- institutional.py /refresh: all 6 types handled with _run() helper
- ai_analyzer.py build_institutional_block(): limit 6→12, generic header text
- InstitutionalReports.tsx: 6-type color map, individual refresh buttons, expanded filters

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-22 14:26:19 +02:00
parent d178615c74
commit acc8bef29d
8 changed files with 1193 additions and 103 deletions

View File

@@ -1208,7 +1208,7 @@ def build_institutional_block(days: int = 7) -> str:
rows = conn.execute(
"SELECT report_type, report_date, key_points_json, trading_implications, "
"signal_energy, signal_metals, signal_indices, signal_forex, importance "
"FROM institutional_reports WHERE report_date >= ? ORDER BY report_date DESC LIMIT 6",
"FROM institutional_reports WHERE report_date >= ? ORDER BY importance DESC, report_date DESC LIMIT 12",
(cutoff,),
).fetchall()
finally:
@@ -1218,7 +1218,7 @@ def build_institutional_block(days: int = 7) -> str:
return ""
import json as _json
lines = ["## INSTITUTIONAL REPORTS (CFTC COT + EIA — last 7 days)"]
lines = [f"## INSTITUTIONAL REPORTS (COT · EIA · Earnings · VX · Central Banks · Sentiment — last {days}d)"]
for r in rows:
rtype = r["report_type"].upper()
rdate = r["report_date"]