SPB Git

spb/wp41_uqo

Public
9.0 KB

# ⏱️ CHRONOS-X

UQO Working Paper No. 41 — Universal Intraday Representation Learning for Probabilistic Financial Forecasting

Paper Python Data Reproducible Institution Author

TL;DR — Can a compact multi-resolution patch Transformer (MRPT) that reads the last 390 one-minute bars plus five days of 5-minute and twenty days of 30-minute past-only aggregates produce better-calibrated distributions of the next 5/15/30/60-minute returns than equal-budget one-minute-only models and well-specified volatility baselines? Tested on 300 U.S. stocks and ETFs (2018–2025, 234 M one-minute bars from FinData OS), with matched information sets, proper scoring rules, day-cluster inference, 60 held-out instruments and an untouched 2025 test. See docs/PHASE_5..7_REPORT.md and the paper for the measured answer; no claim is made beyond them.


# 📌 Status

Item Value
Version 1.0 (November 2026) — built autonomously on 2026-11-02 under the owner's brief (CLAUDE.md)
SSRN not yet submitted
Journal — (research software + working paper)
Code & data reproducible from scripts/ against FinData OS (private FirstRate Data license); synthetic example runs without a license

# 🎯 What this paper does

Five pre-registered, falsifiable hypotheses (paper/sections/hypotheses.tex): H1 multi-resolution context vs one-minute-only at equal parameters; H2 transfer to unseen instruments; H3 history-only regime conditioning and calibration under stress; H4 coherent joint paths (low-rank Gaussian copula over the 60 future minutes) vs independent marginals; H5 (exploratory) economic content after assumed costs. Targets are return distributions (per-minute Student-t marginals, cumulative returns, realised variance, tail events), never price levels.

# 🏆 Headline results (scaled CRPS of the cumulative return; 2024 development test, 986 468 origins; 2025 untouched, 1 008 425)

Object 2024 (H=5 / H=60) 2025 (H=5 / H=60)
Random walk (trailing scale) 0.4699 / 0.4347 0.4759 / 0.4409
HAR-RV (minute scale, Student-t) 0.4615 / 0.4166 0.4674 / 0.4232
MRPT-S multi-resolution (3.5 M params) 0.4531 / 0.4187 0.4594 / 0.4256
MRPT-S one-minute only 0.4533 / 0.4192 0.4594 / 0.4257
MRPT-B (20.7 M params) 0.4532 / 0.4189 0.4595 / 0.4257
H1 multi-res vs 1m-only −0.04 % / −0.10 % (t −5) +0.01 % / +0.01 % (Holm p ≥ 0.36) → rejected in substance
H2 zero-shot on 60 unseen instruments vs random walk −4.1 % / −4.3 % (pooled −4.05 % / −4.27 %) → no transfer penalty same in 2025
H3 regime conditioning +0.02 … +0.03 % CRPS, identical stress-day coverage → rejected
H4 copula paths vs independent energy −0.003 %, variogram −0.002 % (CIs ∋ 0) → rejected
H5 economic content corr(median, realised) ≤ 0.025; net 0.0 bp [−1.7, +1.8] at 1 bp cost → rejected
Time-only inputs (no returns/volumes) +0.2 … +0.3 % vs full model: ≈ 90 % of the skill is trailing volatility + clock

# 🗂 Repository layout

text
wp41_uqo/
├── CLAUDE.md · README.md · pyproject.toml · Makefile
├── configs/        pilot · feasibility · main · ablations · baselines · final · synthetic_smoke (.yaml)
├── src/chronos_x/
│   ├── data/       client · exports · universe · calendar · quality · adjustments · features · windows · synthetic
│   ├── models/     patches · encoder · fusion · regime · student_t · joint_path · model
│   ├── train/      trainer · losses · sampling · checkpoint · tracking
│   ├── eval/       scores · calibration · statistics · subgroups · economic · figures
│   ├── baselines/  naive · har · garch · trees · neural · features
│   ├── inference/  predict · serialization · cli
│   └── pipeline.py · experiment.py · config.py
├── scripts/        audit_api · build_universe · audit_coverage · download_pilot · run_experiment · train_pilot · train_main
│                   · benchmark · evaluate · make_figures · build_references · make_synthetic · node_run.sh
├── tests/          unit · integration (live API, synthetic pipeline) · leakage · synthetic · numerical
├── data/manifests  universe_main.json (hash inside) · universe_main_v1_precoverage.json · candidates · universe_synthetic.json
├── results/        metrics/<exp>/ (summaries, leaderboards, comparisons, train logs) · logs/ (provenance JSONL)
├── paper/          main.tex · sections/ · tables/ (generated) · figures/ (generated) · references.bib (Crossref-verified) · main.pdf
└── docs/           DATA_CARD · MODEL_CARD · REPRODUCIBILITY · LICENSE · OPERATIONS · PHASE_0..9_REPORT

# 🚀 Quick start

bash
make install && make test                                   # venv + 26 offline tests
.venv/bin/python scripts/make_synthetic.py                  # license-free fixtures in the FinData schema
.venv/bin/python scripts/run_experiment.py --config configs/synthetic_smoke.yaml   # bars -> grids -> baselines -> MRPT -> scores (~3 min)
.venv/bin/python scripts/evaluate.py --exps synthetic_smoke && .venv/bin/python scripts/make_figures.py --exps synthetic_smoke
cd paper && make                                            # latexmk -> main.pdf

Full study: docs/REPRODUCIBILITY.md. Compute node and operations: docs/OPERATIONS.md.

# 🗃 Data

FinData OS (https://findata.spboucher.ai/api/v1), FirstRate Data one-minute bars, private license (no raw data in this repository). Universe: 300 instruments selected point-in-time at 2017-12-29 (ADV ≥ 5 M USD, ≥ 80 % regular-hours minute coverage, stratified by asset class × dollar volume × volatility, SIC / ETF category balanced), 60 held out. Sample 2018-01-02 → 2025-12-31: 233 958 776 rows, 220 142 835 in regular hours. Details and conventions (bar-open stamps, 391/211-slot sessions, masks, split policy): docs/DATA_CARD.md, docs/PHASE_0_REPORT.md, docs/PHASE_1_REPORT.md.

# 🔬 Methodology

  1. Audit the live API and conventions on real rows (scripts/audit_api.py, live tests).
  2. Build the PIT universe, audit coverage, freeze the manifest (build_universe.py, audit_coverage.py).
  3. Export bars per instrument, build dense grids and past-only aggregates (download_pilot.py, data/features.py).
  4. Index origins and build causal windows and masked targets (data/windows.py; leakage tests).
  5. Fit baselines on the same origins (baselines/, experiment.fit_and_predict_baselines).
  6. Train MRPT variants with the Student-t NLL, early stopping and checkpoints (train/trainer.py).
  7. Predict, sample, score, bootstrap and test (inference/predict.py, eval/, pipeline.py).
  8. Ablations, zero-shot instruments, untouched 2025 (configs/ablations.yaml, --heldout, configs/final.yaml).
  9. Tables, macros and figures from saved results only (evaluate.py, make_figures.py); LaTeX build.

# 🖼 Figures & tables inventory

Generated into paper/figures/ and paper/tables/ by the scripts above (see docs/PHASE_8_REPORT.md).

# ⚠️ Limitations

Survivor-heavy liquid universe (coverage gate; delisted archives partial), bars without quotes, regular hours only, single-node compute without mixed precision, foundation-model baselines not run. Full list: paper/sections/limitations.tex.

# 📝 Citation

bibtex
@techreport{boucher2026chronosx,
  author      = {Boucher, Simon-Pierre},
  title       = {CHRONOS-X: Universal Intraday Representation Learning for Probabilistic Financial Forecasting},
  institution = {Universit\'e du Qu\'ebec en Outaouais, D\'epartement des sciences administratives},
  type        = {Working Paper},
  number      = {41},
  year        = {2026},
  month       = {November}
}

# 👤 Author & contact

Simon-Pierre Boucher — Département des sciences administratives, Université du Québec en Outaouais (UQO), Gatineau, QC. 📧 simon-pierre.boucher@uqo.ca

# 🗒 Notes

  • Directory named wp41_uqo as requested by the brief (the standard would be a descriptive slug).
  • Intraday data: FirstRate Data (private license), accessed through FinData OS; attribution required, redistribution prohibited.
Files · main
Menu

Theme