4.3 KiB
jepa-fx-risk
Identity
- Name: jepa-fx-risk
- Owner: Mathias
- Client: personal research
- Repo: gitea.d-ma.be/mathias/jepa-fx-risk
- Status: active — Phase 0
Purpose
Research project: apply JEPA-based self-supervised representation learning to FX risk management for a corporate bank with an internal global FX trading desk.
Primary tasks: FX volatility forecasting and VaR/CVaR estimation. Target output: internal PoC for the trading desk.
Architecture decision (see DECISIONS.md ADR-001)
TS-JEPA + SIGReg — TS-JEPA temporal patchwise architecture (Ennadir et al., arXiv:2509.25449) with EMA replaced by Sketched Isotropic Gaussian Regularization (SIGReg, Balestriero & LeCun, arXiv:2511.08544). Single search axis: λ ∈ [0.01, 1.0].
Phase 2 hypothesis: MTS-JEPA multi-resolution objective (arXiv:2602.04643).
Stack
Go (src/): data pipeline (DUKASCopy fetch + hourly processing), evaluation
harness (silhouette, linear probe R², collapse diagnostic, Kupiec/Christoffersen),
results dashboard (Templ + HTMX + CDN Tailwind).
Python (model/): all training and embedding export only. PyTorch cu130
(Blackwell sm_120 compatible). No evaluation logic in Python.
Infra: koala (Arch Linux, Blackwell GPU 12 GB VRAM) for training. iguana (Mac Studio M2 Ultra) + LiteLLM on piguard for autoresearch agent LLM.
Repository layout
jepa-fx-risk/
├── src/ # Go — data pipeline + eval harness + dashboard
│ ├── data/ # DUKASCopy fetch, hourly processing, validation
│ └── eval/ # silhouette, linear probe, collapse, backtest
├── model/ # Python — training only
│ ├── train.py # TS-JEPA + SIGReg backbone (autoresearch edits this)
│ ├── prepare.py # LOCKED — data loading, tokenization, export
│ └── requirements.txt
├── specs/ # Research specs (one per phase/experiment type)
├── experiments/ # Per-run outputs: embeddings, metrics.json, git tag
├── results/summaries/ # Human-readable outcome per experiment
├── program.md # Autoresearch agenda — researcher edits this
├── DECISIONS.md # Architecture Decision Records
└── Taskfile.yml # task data:fetch, task experiment:run, task eval:*
Phase structure
- Phase 0 (current): MAE baseline on EUR/USD hourly 2008–2022. Gate: silhouette > 0.20, MAE > PCA, ±10% over 3 reruns.
- Phase 1: TS-JEPA + SIGReg autoresearch sweep, 50 experiments. Gate: val_vol_r2 > GARCH baseline AND Kupiec p > 0.05.
- Phase 2: MTS-JEPA multi-resolution hypothesis.
- Phase 3: Internal bank tick/position data (future, out of current scope).
Data
DUKASCopy hourly OHLCV, 10 G10 pairs, 2008–2022 train / 2023 val / 2024 test. Features: log-return, log rolling-20-period HV, VIX (daily interpolated). Weekend gaps handled explicitly. See ADR-002.
Key conventions
prepare.pyis LOCKED — never modified by agents or autoresearch- Evaluation metrics are always computed by the Go harness, never in Python
- Every experiment gets a git tag:
exp/YYYYMMDD-description - Null results are recorded explicitly in
results/summaries/— do not iterate silently program.mdis the only file the researcher edits to steer autoresearch- CI runs
task check(lint + vet + test) only — no GPU, no training
Evaluation metrics
Primary (autoresearch optimizes): val_vol_r2 — linear probe R² on 1-day
realized volatility from frozen embeddings, computed by Go harness.
Secondary (logged, not optimized): Kupiec p-value (VaR 99% backtest on EUR/USD). Must co-move with val_vol_r2 — checked from experiment 1.
Diagnostics: silhouette score (regime clustering), PC1/HV correlation (collapse check).
Benchmarks to beat (trading desk comparison)
- GARCH(1,1) — volatility forecasting baseline
- Historical Simulation VaR (250-day rolling) — Basel default
- EWMA RiskMetrics (λ=0.94)
Agent guidance
Read DECISIONS.md before making architecture suggestions.
Do not modify prepare.py or src/eval/.
Do not suggest changing the Python/Go separation.
Training runs are always manual via task experiment:run — never triggered by CI.
When implementing, follow Go conventions in .skills/go-patterns/SKILL.md.