Commit Graph

176 Commits

Author SHA1 Message Date
OpenSquared
40d6f14901 feat: causal lab — chip filters, editor zoom, AI modify prompt
Library:
- Color chip filters: category (with per-category colors), sub_type, instrument
- Date range filter (created_at) + text search
- Category labels unified to cover event_calendar, fundamental, calendar_event etc.
- Editer button on selected template → opens in editor tab
- Show created_at + created_by in template detail

Editor:
- Accepts initialId prop so Library can pre-load a template
- AI Modify zone: textarea prompt + button calls /api/causal-lab/template/{id}/ai-modify
- Returns modified graph_json from GPT-4o, applied live — user reviews then saves

Backend:
- New POST /api/causal-lab/template/{id}/ai-modify endpoint
  - Sends current graph_json + user prompt to GPT-4o
  - Returns validated modified graph_json (nodes/edges required)
  - Does not auto-save (user controls save)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 09:04:15 +02:00
OpenSquared
5e37cd81a2 fix: pass prediction_json and actual_json through to snapshot events
The filtered event dict was built with explicit fields and omitted these two columns,
so the frontend always received null despite the DB having valid data.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 23:34:32 +02:00
OpenSquared
b33d06cb97 debug: add db_state display + raw pred_json, expand YFINANCE_MAP
YFINANCE_MAP now includes GBPUSD, USDJPY, USDCHF, AUDUSD, NZDUSD, USDCAD, XAGUSD, NASDAQ, DAX, FTSE, WTI, US30Y, DXY.
Frontend diagnostic panel shows db_state rows after Recalculer and raw prediction_json prefix per event.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 23:31:15 +02:00
OpenSquared
05236c31f3 fix: preserve debug info across snapshot re-fetch + widen refresh filter
- refreshDebug state lives in parent (InstrumentDashboard) so it survives
  fetchSnapshotSilent re-render (ExplanationScore no longer loses debugInfo
  when onRefreshDone triggers setLoading → unmount)
- fetchSnapshotSilent: re-fetches snapshot without setLoading(true) so
  ExplanationScore stays mounted with its state
- Refresh filter now catches rows where prediction_json is empty even if
  actual_json is populated, and handles '[]' / null variants

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 23:20:17 +02:00
OpenSquared
c73bedd7d0 debug: expose full inputs/outputs in Recalculer response for diagnosis
_run_auto_analysis now returns a rich dict {ok, inputs, node_values, actual_moves, error}
instead of bool. The refresh endpoint captures and forwards:
- inputs: what values were fed to evaluate_graph
- node_keys: which nodes were computed in prediction
- actual_moves: actual price pips fetched
- run_error: exception message if it failed

Frontend shows all of this after clicking Recalculer so the root cause is visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 23:09:49 +02:00
OpenSquared
af73b77cba fix: ensure actual_json is computed for auto-generated templates
Auto-generated templates had no lag_days on edges → effective_lag_days=0 →
_drift_metrics used exact-date daily bar (often empty) → actual_json='{}' →
comprehensionScore returned null even after prediction_json was populated.

- Default effective_lag_days=5 when computed as 0 in _run_auto_analysis
- Add lag_days:3 to all auto-generated template edges in _build_graph_json_from_spec

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 23:05:10 +02:00
OpenSquared
c93eba7a7f fix: compute surprise_pct from actual/expected when NULL for auto-analysis scoring
Events with surprise_pct=NULL (bootstrap or older events) got inputs={} → evaluate_graph
returned {} → prediction_json='{}' → all scores showed 'En attente'.

Three-step fallback in _run_auto_analysis:
1. Use event.surprise_pct if set (existing behaviour)
2. Compute from actual_value / expected_value stored in market_events
3. Look up most recent ff_calendar release by currency + date

Frontend diagnostic now shows surprise_pct per event and exposes actual/expected
in the refresh result panel to make the source visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 22:54:57 +02:00
OpenSquared
959c2825df feat: instrument analysis 2026-06-29 22:38:50 +02:00
OpenSquared
b223f50f8b feat: market event 2026-06-29 21:16:29 +02:00
OpenSquared
5e819b5b67 feat: instrument analysis 2026-06-29 20:44:03 +02:00
OpenSquared
f4a55a8009 feat: desk ia 2026-06-29 20:21:52 +02:00
OpenSquared
551ebc3ef4 feat: desk ia 2026-06-29 19:50:18 +02:00
OpenSquared
f7acca2152 feat: desk ia 2026-06-29 17:16:57 +02:00
OpenSquared
69418ab650 feat: desk ia 2026-06-29 15:45:21 +02:00
OpenSquared
9c30b58f22 feat: market event 2026-06-29 14:41:25 +02:00
OpenSquared
ac441ad5cb feat: market event 2026-06-29 12:49:12 +02:00
OpenSquared
79593a8fd3 feat: instrument analysis 2026-06-29 12:38:28 +02:00
OpenSquared
495ccfdee4 feat: market event 2026-06-29 11:48:52 +02:00
OpenSquared
c5d1f7b4bc feat: causal lab 2026-06-29 11:37:35 +02:00
OpenSquared
7ac7c4c619 feat: market event 2026-06-29 11:27:28 +02:00
OpenSquared
4be3ad9ce3 feat: market event 2026-06-29 11:15:08 +02:00
OpenSquared
9f90c97461 feat: market event 2026-06-29 11:05:25 +02:00
OpenSquared
bcdf1fbf2e feat: causal lab 2026-06-29 10:32:18 +02:00
OpenSquared
97077af369 feat: market event 2026-06-29 08:14:25 +02:00
OpenSquared
5e65424500 feat: instrument analysis 2026-06-29 00:06:14 +02:00
OpenSquared
3bcecdab09 feat: instrument analysis 2026-06-28 23:43:52 +02:00
OpenSquared
6ebbf4326e feat: causal lab 2026-06-28 18:08:09 +02:00
OpenSquared
c286c7c000 feat: desk IA 2026-06-28 17:14:40 +02:00
OpenSquared
bab09a1b09 feat: causal lab 2026-06-28 17:03:37 +02:00
OpenSquared
e4e17330b4 feat: instrument analysis 2026-06-28 16:36:28 +02:00
OpenSquared
1e44557551 feat:: causal lab 2026-06-28 15:38:19 +02:00
OpenSquared
863ba67610 feat: causal lab 2026-06-28 14:18:43 +02:00
OpenSquared
20f1897211 feat: instrument analysis 2026-06-28 13:52:34 +02:00
OpenSquared
b94291623d feat: instrument analysis 2026-06-28 13:04:24 +02:00
OpenSquared
79d4a9f741 Calendar synchro 2026-06-28 12:15:25 +02:00
OpenSquared
98d6be8212 feat: temporal params (lag/diffusion/decay) sur aretes causales
- CausalEdge: lag_min, diffusion_min, decay_days
- SVG: labels +Xm (jaune, source) et decay (gris, cible) sur les aretes
- Editeur: champs lag/diffusion/decay dans add-edge et edit-edge
- Bibliotheque: section Parametres temporels avec grille editable + sauvegarde PATCH
- Backend: _drift_metrics utilise lag_min pour decaler fenetre intraday 5min
- analyze: calcule effective_lag depuis aretes → market_asset, retourne dans resultat

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 11:47:04 +02:00
OpenSquared
1117e9ee8a feat: causal lab - delete template + observable mapping + edge editing
- TabLibrary: bouton Supprimer (templates user uniquement)
- TabEditor: inputMapping dans EditorState, panneau mapping visible quand noeud observable selectionne
- TabEditor: edition d aretes (cliquer sur arête pour modifier style/force/signe/label)
- Backend: GET /api/causal-lab/data-sources (prices/macro_series/ff_events)
- analyze: auto-fetch market_watchlist+economic_events+ff_calendar depuis input_mapping
- TabAnalyze: affiche inputs auto-recuperes vs manuels dans les resultats

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 10:53:50 +02:00
OpenSquared
dd31f92aaf feat: causal lab - bouton Mettre a jour + PATCH endpoint
- TabEditor: updateExisting() + bouton bleu visible si templateId set
- Bouton Creer renomme en copie pour clarifier
- PATCH /api/causal-lab/template/{id} pour graph_json + metadonnees

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 10:02:28 +02:00
OpenSquared
e8fb7c13aa feat: causal lab — éditeur visuel, types nœuds, force/signe arêtes, NFP v2 2026-06-28 09:28:43 +02:00
OpenSquared
7a0263989a feat: causal lab — debug endpoint + error display in UI 2026-06-27 23:36:22 +02:00
OpenSquared
a7f5369d7b Causal lab v2 2026-06-27 23:25:59 +02:00
OpenSquared
9ac3ebb4b5 causal lab 2026-06-27 21:45:10 +02:00
OpenSquared
e27ff72c1c feat: simulateur EUR/USD — canaux taux/ton séparés + saisie directe sliders
Modèle causal refactorisé en deux canaux distincts :
- Canal taux (solid) : variations taux directeurs → principalement 2Y (ancrage court terme)
- Canal ton/anticipations (tirets) : discours CB + surprises CPI/NFP → principalement 10Y (anticipations long terme)

Slider : clic sur la valeur affichée → input éditable (Enter/Blur pour valider, Escape pour annuler)

Backend : endpoint /api/simulator/baseline expose us_10y et eu_10y (yfinance ^TNX + GE10YT=RR)

SVG mis à jour : 4 nœuds de taux (2Y/10Y US+EU), 2 nœuds différentiels, flèches solides/tirets
Strip métrique : 6 cellules (US 2Y, US 10Y, Bund 2Y, Bund 10Y, Δ 2Y, Δ 10Y)
Décomposition : séparation "Δ 2Y — taux directeurs" / "Δ 10Y — anticipations/ton"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 23:08:08 +02:00
OpenSquared
fe86cc1994 feat: EUR/USD simulator — live baseline from market data
Backend (routers/simulator.py):
- GET /api/simulator/baseline aggregates current market values:
  1. macro_gauge_snapshots → VIX, Brent oil
  2. FRED economic_events  → FEDFUNDS, ECBDFR, DFII10 (real yield)
  3. yfinance live         → EURUSD=X, ^IRX+^FVX interpolated US 2Y,
                             DE2YT=RR EU 2Y (or ECB rate +15bps fallback),
                             ^VIX, BZ=F
- Returns sources dict so frontend can show data provenance

Frontend (EuroSimulator.tsx):
- Fetch /api/simulator/baseline on mount; use as base anchors
- compute(p, base) now takes dynamic base instead of hardcoded constants
- Reset button returns to today's live baseline, not hardcoded fallback
- Live/Fallback status badge with fetch date
- Sources panel showing data origin per field
- Chart reference line updates to show live base values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 22:42:18 +02:00
OpenSquared
a24cac38ad feat: eco desk enhanced config + EUR/USD causal simulator
Eco desk (market_event_detector.py + AIDesks.tsx):
- Add currencies filter (USD via FRED, EUR/GBP/JPY/etc via ff_calendar)
- Add min_impact filter (high / high+medium / all levels)
- Add create_market_event toggle — detect surprises without creating events
- Add lookback_releases — inject last N historical releases into event description
- New _check_ff_calendar_surprises() for non-USD surprising releases
- Frontend EcoConfig: currency chips, impact dropdown, releases input, toggle

EUR/USD Simulator (EuroSimulator.tsx):
- Pure frontend causal model — no API calls, no historical data
- 3-column layout: controls | causal chain SVG | results
- FED/BCE rate sliders + hawkish/dovish tone selector
- CPI/NFP/PMI surprise inputs
- SVG causal chain: CPI→CB→2Y→ΔRate→EURUSD with dynamic colors
- Real-time pip decomposition by factor, sensitivity bars
- Route /simulator + sidebar entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 22:17:33 +02:00
OpenSquared
87ded9434f feat: import Trading Economics HTML calendar — 993 events with forecasts
Adds a one-click upload+parse flow for the TE calendar page HTML.
The TE page (tradingeconomics.com/calendar) contains ~1000 events with
actuals, previous, and analyst consensus (forecast) values.

- Add backend/services/te_html_parser.py:
  - parse_html(html): extracts events from <tr data-event> rows
  - Maps 14 countries to major currencies (all Eurozone → EUR)
  - Impact inferred from data-category (high/medium/low)
  - Times converted from Europe/Zurich (CET/CEST) → UTC via zoneinfo
  - Actual=td[5], Forecast=td[7] (analyst consensus), Previous=td[6]
- Add POST /api/eco/te-html-upload (saves file to /tmp)
- Add POST /api/eco/te-html-import + GET /status (background parse)
- Add "Import TE HTML" upload button in CalendarPage ImportPanel

Tested locally: 993 events parsed, 854 with forecast, 861 with actual,
date range 2025-03-31 → 2026-06-17, timezone conversion verified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 18:15:02 +02:00
OpenSquared
bdbb87962d feat: FXStreet calendar — free upcoming events with forecasts (no API key)
FXStreet calendar.fxstreet.com/eventdate/ returns ~300-400 events over
6 weeks including consensus forecasts, no authentication required.
FF HTML scraper is blocked by Cloudflare even on residential IPs.
FMP free plan returns 403 on /economic_calendar (requires Starter plan).

- Add backend/services/fxstreet_calendar.py: single GET request returning
  all major currencies; maps Volatility 0/1/2 → low/medium/high
- Add POST /api/eco/fxs-sync + GET /api/eco/fxs-sync/status endpoints
- Add FXStreet to daily background sync in main.py (runs every 24h)
- Add "Sync Upcoming (FXStreet)" button in ImportPanel (no key needed)
- Fix FMP 403 error message to say endpoint requires Starter plan
- Keep FMP panel for users who upgrade to FMP Starter ($14.99/month)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 17:54:15 +02:00
OpenSquared
5c86d6e715 feat: replace Trading Economics with FMP for upcoming calendar forecasts
TE costs $199/month and its Economic Calendar is not in the free tier.
FMP (Financial Modeling Prep) offers a free API key (250 req/day) with
full economic calendar coverage including consensus estimates (forecasts).

- Add backend/services/fmp_calendar.py: fetches upcoming events from
  GET /api/v3/economic_calendar (one request, all countries, date range)
- Replace /api/eco/te-key + te-sync endpoints with fmp-key + fmp-sync
- Update daily background sync in main.py to use fmp_calendar
- Replace TEPanel with FMPPanel in CalendarPage.tsx (link to FMP docs)
- Remove broken Cloudflare-blocked FF HTML scrape button from ImportPanel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 17:42:09 +02:00
OpenSquared
ec6fcc1e3d feat: Trading Economics API for upcoming events with forecasts
- New services/te_calendar.py: fetch_upcoming(weeks_ahead) calls TE API
  for 9 countries (USD/EUR/GBP/JPY/AUD/CAD/NZD/CHF/CNY), converts to
  ff_calendar format, upserts with source='te_api'
- New endpoints: GET/POST /api/eco/te-key, POST /api/eco/te-sync,
  GET /api/eco/te-sync/status
- Daily scheduler in main.py: FF live sync + TE sync (if key configured)
  run 60s after startup then every 24h
- CalendarPage: TEPanel with key input (password field, Enter to save,
  "Get free key" link to tradingeconomics.com/api/login),
  "Sync upcoming (6 weeks)" button with polling

FF HTML scraper kept as fallback but TE API is the primary source
for upcoming forecasts (no Cloudflare blocking on server IPs).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 17:30:16 +02:00
OpenSquared
d9762deca7 feat: custom date range filter on calendar page
- Backend: /api/eco/calendar accepts date_from + date_to query params
  when period=custom; get_calendar() uses them directly without override
  Limit raised to 5000 for wide date ranges
- Frontend: "Custom" tab at end of period list; shows two date inputs
  (from/to) with Apply button; displays day count; fetches on Apply click
  (not on every keystroke to avoid hammering the API)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 17:17:01 +02:00