Skip to content

Repository files navigation

CARRY-Net — Structure-Informed ML for Commodity Futures Curves

A machine-learning model for storable-commodity futures curves that compiles the theory of storage into its architecture:

  • Working layer — convenience yield = architecturally monotone-decreasing, convex function of latent inventory (Proposition 1 in the paper)
  • Full-carry projection layer — every decoded curve satisfies the cash-and-carry arbitrage bound by construction (Proposition 2)
  • Structured dynamics — OU pull of the convenience yield toward the Working curve, risk-premium spot drift linear in the convenience yield, neural network only for the nonlinear inventory flows
  • Two-stage estimator — exact concentrated least squares (Frisch–Waugh) inverts the pricing map; dynamics train end-to-end on the anchored-curve forecast objective

Pure NumPy (custom autodiff engine included). No framework, no GPU. Full experiment: < 10 min on one CPU core.

Files

  • carry_net_paper.md — technical paper (math, propositions, results, failure-mode appendix)
  • medium_article.md — narrative technical article
  • nanograd.py — minimal vectorized reverse-mode autodiff (gradcheck ~1e-9)
  • datagen.py — synthetic corn-like market with ground truth
  • carry2.py — Stage A estimator, Working layer, projection layer, structured dynamics, GRU baseline
  • run2.py — chunked training + evaluation driver
  • make_figs2.py — paper figures
  • metrics.json — final experiment metrics
  • fig1..fig4 *.png — figures

Reproduce

pip install -r requirements.txt   # just numpy + matplotlib
python3 gradcheck.py              # verify the autodiff engine (optional)
python3 run2.py dyn 40            # train CARRY-Net dynamics   (~2 min)
python3 run2.py gru2 40           # train unstructured ablation (~1 min)
python3 run2.py eval              # all baselines -> metrics.json (~2 min)
python3 make_figs2.py             # regenerate figures

Training is checkpointed (ckpt2_*.pkl), so each command can be re-run or resumed; run2.py dyn 10 five times is equivalent to run2.py dyn 50 once.

Headline results (synthetic corn-like market, 550-day test)

Curve RMSE (%): CARRY-Net 1.68 / 3.50 / 7.16 at h = 1/5/20 days — best-or-tied at every horizon (RW 7.23, DNS 7.60, Schwartz twin 8.88, unstructured GRU 12.53 at h=20). Cash-and-carry violations: 0 (RW 6.2%, GRU 17.7%). Curve-implied convenience yield tracks unobserved truth at corr 0.88; learned Working curve recovers the true decreasing-convex shape.

Writeups

License

MIT — see LICENSE. If you use the code or the synthetic-market design in academic work, please cite the technical paper.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages