fix(demo): vendor 2008 hindcast data excluded by .gitignore - #5
Merged
Merged
Conversation
Ajay03299
force-pushed
the
impl/vendor-2008-demo-data
branch
from
July 30, 2026 21:51
7ae22bc to
c5972d0
Compare
The unanchored `*.csv` rule in .gitignore silently excluded the four public-data fixtures that demo/hindcast_2008.py expects in demo/data/2008/, so the demo failed with FileNotFoundError on any fresh clone. - Add `!demo/data/**/*.csv` negation so vendored fixtures are tracked - Vendor the four CSVs (~225 KB total, all public and keyless) - Add demo/data/fetch_2008.py, the script that regenerates them from Ken French's Data Library and FRED Verified: `python demo/hindcast_2008.py` exits 0 and reproduces the README's headline result — sustained signal 2007-08-16, 272 trading days before Lehman, 0 false positives before 2007. Fixes hongjin-he#1
Guards hongjin-he#1 by asserting the fixtures are git-tracked (not merely present on disk), that the two French files share an identical date index, that no missing-data sentinels survive parsing, and that hindcast_2008.py exits 0 while reproducing its headline result.
Test dependencies were only reaching CI via `pip install -r requirements.txt || true`, which silently no-ops if any pin fails to resolve (requirements.txt pins jax[cuda12] and apache-airflow). The new hindcast fixture tests import pandas and invoke a matplotlib-based demo, so both are now installed on the explicit, failing line.
Generalizes the guard past the 2008 fixtures. The same .gitignore rule also dropped the seven CSVs documented in demo/data/memory2026/SOURCES.md, so the check walks demo/data/ rather than naming individual files.
Ajay03299
force-pushed
the
impl/vendor-2008-demo-data
branch
from
August 2, 2026 17:43
c5972d0 to
d11d3bd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1.
demo/hindcast_2008.py— the walk-forward replay featured in the README — failed withFileNotFoundErroron any fresh clone. The unanchored*.csvrule in.gitignorematches at every depth, so the four fixtures the script expects indemo/data/2008/were silently skipped bygit addand never committed, despite the module docstring stating they are meant to be vendored.Changes
.gitignore— adds!demo/data/**/*.csvafter the*.csvrule so the demo fixtures are tracked. Scoped narrowly; no other CSV path is affected.demo/data/2008/*.csv— the four fixtures, ~225 KB total, all public and keyless:ff_factors_0309.csvind10_0309.csvted.csvTEDRATEvix.csvVIXCLSdemo/data/fetch_2008.py— regenerates the fixtures from source. Committing data without the code that produces it makes provenance unverifiable, so the script ships alongside. It handles the two format hazards in the French files: the 10-industry file contains a second equal-weighted section (truncated at its marker, otherwise every date would appear twice and corruptrolling(63).corr()), and missing data is encoded as-99.99, which would survive/100.0as a −99.99% return — the script raises instead. Row parsing whitelists on^\d{8},rather than a fixedskiprows, so a change to the upstream preamble fails loudly instead of shifting the header into the data.Verified deterministic: re-running the fetcher into a clean directory produces byte-identical output to the committed files.
tests/test_hindcast_data.py— 15 tests, no network. The most important asserts the fixtures are git-tracked, not merely present on disk; that is the precise condition that failed here, and a test for file existence alone would have passed on the author's machine. Also covers date-index alignment between the two French files (they feedvol21andcorr63separately, so a mismatch would reindex toNaNand silently degrade Λ rather than raise), required columns, sentinel values, and window coverage. An end-to-end test runs the demo and asserts it exits 0 while reproducing its headline result; it restoresfigures/hindcast_2008.pngafterward so the run is non-destructive..github/workflows/ci.yml— addspandas matplotlibto the explicit install. They were only reaching CI throughpip install -r requirements.txt || true, which silently no-ops if any pin fails to resolve — andrequirements.txtpinsjax[cuda12]andapache-airflow, neither of which is reliable on a GPU-less runner. Test dependencies shouldn't depend on a best-effort install.Verification
Matches the README's stated result.
pytest tests/ -q→ 65 passed (50 existing + 15 new) on Python 3.13, macOS arm64.Notes
requirements.txtpinsjax[cuda12], which can't install on non-NVIDIA machines (it blocked my local setup on Apple Silicon), andsetup.shassumes conda plus Docker containers for TimescaleDB and Kafka. Neither is needed to run the demos. Worth a separate issue if useful.