Work in progress: this repo is actively being built out, and the replication notebook, strategy logic, and fit-to-paper results are still evolving.
This repository is for replicating JungleRocks's whitepaper around the VIX term-structure signal behind the Squid family of strategies.
Today the repo has two main pieces:
- a local data pipeline that downloads and normalizes monthly VX futures history from Cboe
- a notebook,
notebooks/signal_test.ipynb, that walks through the whitepaper signal tests, proxy comparisons, base strategies, refined strategies, and parameter calibration
The current workflow is:
- build the local VX datasets with the CLI
- open the notebook
- reproduce the paper's signal-section figures and tables using:
- official Cboe VX futures data
- official Cboe spot VIX history
- bundled
SPVXTSTRhistory - Yahoo
ES=FandSPYas equity proxies
What is already implemented:
- monthly VX futures download and cleaning
- generic UX ladder construction (
UX1throughUX7) - dislocation-count signal generation
- same-day and
t+1bucket studies - bundled normalized
SPVXTSTRhistory - base and refined Squid strategy weights
- notebook plots and performance tables for the current replication pass
What is still imperfect:
- the equity leg is still proxy-based (
ES=FandSPY), not a fully reconstructed historical ES roll series - some strategy details are still being calibrated against the paper
- alternate PnL constructions are still being tested in the notebook
The current notebook and pipeline use:
- Cboe settlement archive and current historical futures API for monthly VX contracts
- Cboe
cfevoloi.csvfor VX product-level volume and open interest - Cboe spot VIX history CSV
- bundled
data/external/spvxtstr_normalized.csv - Yahoo Finance for
ES=FandSPY
Install dependencies with uv:
uv syncGenerate the raw and clean VX datasets:
uv run squid-replicationOptional refresh:
uv run squid-replication --refreshOptional custom data directory:
uv run squid-replication --data-dir dataYou can also run the module directly:
uv run python -m squid_replicationThe notebook expects the clean VX parquet outputs to exist locally, so run the pipeline at least once before opening the notebook.
Start Jupyter:
uv run jupyter labThen open:
notebooks/signal_test.ipynb
The notebook currently covers:
- signal construction from the VX curve
- term-structure snapshot plots
- same-day and
t+1bucket tests SPVXTSTRcomparison- base strategy curves and stats
- refined strategy curves and stats
- proxy comparison and threshold calibration
- exported strategy weights
Running the VX pipeline creates local datasets like:
data/
raw/
vix_futures/
archive/
current/
archive_index.json
current_index.json
cfevoloi.csv
clean/
vix_futures/
monthly_contracts.parquet
product_daily.parquet
generic_contracts.parquet
The notebook also writes derived artifacts such as:
data/derived/
strategy_weights.csv
These generated folders are gitignored because they can be rebuilt locally.
monthly_contracts.parquet
- one row per trade date per monthly VX contract
- includes normalized OHLC, settle, volume, and open interest fields
Cleaning rules include:
- pre-
2007-03-26VX prices are rescaled by0.1 - placeholder rows with all-zero prices and activity are removed
- rows with non-positive
settleare removed
product_daily.parquet
- daily VX product-level volume and open interest
generic_contracts.parquet
- generic
UX1throughUX7ladder - roll metadata
- roll-aware generic returns and indices
- alternate
close_expiry_rollandsettle_expiry_rolllevels for hold-through-expiry analysis
Generic ladder behavior:
UX1throughUX7are assigned by monthly expiry offset from the front eligible contract- the default roll date is
3trading sessions before expiry settle_expiry_rollkeeps a hold-through-expiry version of the ladder for signal worknet_returnincludes the fixed transaction-cost treatment used by the generic builder
The notebook currently separates signal generation from PnL construction.
Examples:
- the signal often uses
settle_expiry_roll - VX PnL can be switched between generic
net_returnand alternate level-based experiments SPVXTSTRis read from the bundled normalized file- the equity side is still tested through proxies
Those choices are documented in the notebook itself and may continue to change while the replication is refined.
Run the full test suite with:
uv run pytestCoverage run:
uv run pytest --cov=squid_replication