Files
WeHub Mirror ba5b1d8398
Tests / changes (push) Has been cancelled
Tests / lint (push) Has been cancelled
Tests / guards (push) Has been cancelled
Tests / test-unit (push) Has been cancelled
Tests / ${{ matrix.name }} (push) Has been cancelled
Tests / cs-${{ matrix.case-study }} (push) Has been cancelled
Tests / test-py312 (push) Has been cancelled
Tests / test-neo4j (push) Has been cancelled
Tests / test-benchmark (push) Has been cancelled
WeHub snapshot of c2c7b6ca46223f2522af92054ac1c53327ee2799
2026-08-07 17:42:00 +08:00

19 KiB
Raw Permalink Blame History

ML4T Data Infrastructure

Central data management for Machine Learning for Trading, 3rd Edition.

Each dataset has its own directory with a download script, loader, config, and exploration notebook. All loaders return Polars DataFrames with a consistent API.


Quick Start

# 1. Set data path in repository root .env file
ML4T_DATA_PATH=/path/to/your/data

# 2. Download free datasets (no API keys needed)
uv run python data/download_all.py --free-only

# 3. Use in notebooks
from data import load_etfs
df = load_etfs()

Dataset Catalog

Organized by asset class and data type. "Type" column maps each dataset to its place in the Ch2/Ch4 taxonomy: market (OHLCV / microstructure / options), fundamentals (accounting + regulatory filings), positioning (positions / insider activity), onchain (crypto-native fundamentals), or cross-asset (factors, macro, prediction markets, news, text).

Dataset Asset Class Type Frequency Symbols Coverage Source Access
ETF Universe Equity Market Daily 100 2006-2025 Yahoo Finance No
US Equities Equity Market Daily 3,199 1962-2018 NASDAQ DL Free
S&P 500 Bars Equity Market Daily ~638 2017-2021 AlgoSeek Pending
S&P 500 Options Equity Market Daily 634 2017-2021 AlgoSeek Convert
NASDAQ-100 Bars Equity Market Minute ~100 2020-2021 AlgoSeek Convert
TAQ Tick Equity Market Tick 1 Mar 2020 AlgoSeek Pending
MBO Tick Equity Market Tick 1 Nov 2024 Databento Manual
NASDAQ ITCH Equity Market Tick all varies NASDAQ FTP No
IEX DEEP/TOPS Equity Market Tick all varies IEX public No
SEC XBRL Fundamentals Equity Fundamentals Quarterly 20 2022-2024 SEC EDGAR No
SEC 10-K (SP100) Equity Fundamentals Annual ~100 2020-2025 SEC EDGAR No
SEC 10-Q MD&A (SP500) Equity Fundamentals Quarterly ~600 2017-2021 SEC EDGAR No
SEC 8-K (SP100) Equity Fundamentals Event ~100 2024-2025 SEC EDGAR No
13F Institutional Equity Positioning Quarterly 10 inst rolling SEC EDGAR No
Form 4 Insider Equity Positioning Event varies varies SEC EDGAR No
Firm Characteristics Equity Packaged Monthly anon 1967-2016 GitHub No
CME Futures Futures Market Daily/Hourly 30 2011-2025 Databento Paid
CFTC Commitment of Traders Futures Positioning Weekly 25+ 2020-2025 CFTC public No
Crypto Perps Crypto Market 1h 19 2020-2025 Binance Public No
Crypto Premium Crypto Market 8h 19 2020-2025 Binance Public No
DefiLlama TVL Crypto Onchain Daily chains varies DefiLlama No
CoinGecko OHLCV Crypto Onchain Daily varies 365 days CoinGecko No
FX Pairs Currency Market 4h/Daily 20 2011-2025 OANDA Free
FF Factors Cross-asset Factors Monthly 5 1926-now Ken French No
AQR Factors Cross-asset Factors Monthly 8 varies AQR No
FRED Macro Cross-asset Macro Various 40 2000-2025 FRED Free
Kalshi events Cross-asset Prediction Daily varies 2021-2025 Kalshi public No
Polymarket events Cross-asset Prediction Daily varies 2020-2025 Polymarket public No
FNSPID news Cross-asset News Daily 4,775 1999-2023 HuggingFace No
Bloomberg news archive Cross-asset News Daily mixed 2006-2013 HuggingFace No
Financial Phrasebank Cross-asset Text Static n/a HuggingFace No

Access legend. No — included with the repo or fetched by an unauthenticated script. Free — script-download, free API key required. Paid — script-download, billed API (see per-dataset estimates). Manual — reader downloads from a hosted URL or provider portal and places the files under $ML4T_DATA_PATH (no script); the DataBento MBO one-off has step-by-step instructions below. Convert — AlgoSeek hosts the archive openly, and one script turns it into what the loaders read; see AlgoSeek datasets. Pending — AlgoSeek has not published this one yet, and nothing you can run substitutes for it.


Download Commands

Times below are rough, indicative estimates only. Actual duration depends on your bandwidth, the providers' current rate limits, and disk speed — treat them as ballpark, not guarantees.

Free Datasets (No API Keys)

# All free datasets at once: about 4.1 GB and 12 minutes, of which the
# firm-characteristics dataset is 4.0 GB. Without it the whole set is ~75 MB:
uv run python data/download_all.py --free-only
uv run python data/download_all.py --free-only --skip-firm-characteristics

# Individual datasets (from repo root)
uv run python data/etfs/market/download.py                           # ~30s
uv run python data/crypto/market/download.py                         # ~10-15 min (see note)
uv run python data/factors/ff_download.py                     # ~5s
uv run python data/factors/aqr_download.py                    # ~5s
uv run python data/equities/firm_characteristics/download.py  # ~4.0 GB on disk, largest free dataset by far; downloads + converts (minutes, bandwidth-dependent)
uv run python data/futures/positioning/cot_download.py                    # ~2-3 min (CFTC CoT)

Note on crypto download time: The Binance public API returns max 1,500 rows per request with ~1s server response time. Downloading 5 years of hourly data for 19 symbols requires ~700 API calls. Downloads run in parallel (5 concurrent), but the total still takes 10-15 minutes. This is a Binance server-side rate limit, not a bug.

If a symbol is missing from the result, the script names it and exits non-zero. Re-running fetches every symbol again and merges into what is already on disk, so one that failed can arrive on the second run; the status is then computed from the merged data, not from the second run's failures. Pass --allow-partial to keep what arrived and exit 0.

Free API Key Required

# FRED macro indicators
uv run python data/macro/download.py

# US Equities (NASDAQ Data Link — frozen, ends 2018)
uv run python data/equities/market/us_equities/download.py

# FX pairs (OANDA)
uv run python data/fx/market/download.py              # 4-hourly (default)
uv run python data/fx/market/download.py --daily      # Daily

Paid API Key (Databento)

# CME Futures — ALWAYS estimate cost first!
uv run python data/futures/market/download.py --estimate-only
uv run python data/futures/market/download.py

Manual Download (Databento Download Center)

The Chapter 3 MBO slice (NVDA, 10 trading days in November 2024) is best obtained as a one-off download from the Databento Download Center — total cost is under $10 and the files stay available for 30 days.

See data/equities/market/microstructure/MBO_DOWNLOAD.md for step-by-step instructions. An API-based alternative (mbo_download.py) is available for users who already have a DATABENTO_API_KEY.

AlgoSeek datasets

AlgoSeek publishes two of the four datasets this book uses at https://algoseek.com/ml-for-trading/ — plain download links, no account, no API key. Both are CSV; every loader reads parquet, so one conversion step sits between the download and the notebooks.

Archive Size What it is
nasdaq-100-constituents-taq-ext.zip 5.9 GB NASDAQ-100 extended minute bars, 505 days, 2020-01-02 to 2021-12-31
options_daily_greeks_sp500.zip 13.8 GB S&P 500 daily option chains with Greeks, 1,259 days 2017-2021, 634 symbols
# NASDAQ-100 minute bars -> equities/market/nasdaq100/minute_bars/
uv run python data/equities/market/algoseek_convert.py \
    --dataset nasdaq100-minute-bars --source ~/Downloads/nasdaq-100-constituents-taq-ext.zip

# S&P 500 raw option chains -> equities/market/sp500/options/
uv run python data/equities/market/algoseek_convert.py \
    --dataset sp500-options --source ~/Downloads/options_daily_greeks_sp500.zip

# then build what the options notebooks actually load
uv run python data/equities/market/sp500/build_options_eda.py
uv run python data/equities/market/sp500/build_options_straddles_raw.py
uv run python data/equities/market/sp500/materialize_options.py

--source also takes a directory you have already extracted, which is considerably faster for the options archive: it holds 1,275,314 gzipped files, and reading them out of the zip pays the archive's index on every open. Both conversions resume, so an interrupted run continues where it stopped.

Two datasets are not published yet. AlgoSeek staged them for hosting and has not packaged them; nothing in this repo substitutes for either.

Missing Blocks
S&P 500 daily bars 18_transaction_costs/01_cost_taxonomy, 02_spread_estimation, 03_market_impact_calibration, and the sp500_equity_option_analytics backtest
NASDAQ-100 TAQ ticks 03_market_microstructure/11_algoseek_taq_eda, 12_algoseek_taq_lob_reconstruction

The published minute-bar archive cannot stand in for the ticks: it is quote-aware bar aggregates, and reconstructing an order book needs the events.

Update Existing Data

Extend datasets beyond the default end date:

uv run python data/download_all.py --update

Using Loaders

All loaders are importable from data and return Polars DataFrames:

from data import (
    load_etfs,
    load_crypto_perps,
    load_crypto_premium,
    load_cme_futures,
    load_cot,
    load_fx_pairs,
    load_macro,
    load_us_equities,
    load_ff_factors,
    load_aqr_factors,
    load_firm_characteristics,
    load_nasdaq100_bars,
    load_sp500_daily_bars,
    load_sp500_options,
    load_sp500_options_eda,
    load_sp500_options_straddles_raw,
    load_sp500_options_surface,
    load_sp500_options_straddles,
    load_nasdaq100_taq,
    load_mbo_data,
    load_nasdaq_itch,
    load_iex_hist,
)

# All loaders support filtering
df = load_etfs(symbols=["SPY", "QQQ"], start_date="2020-01-01")

# Futures use 'products' instead of 'symbols'
futures = load_cme_futures(products=["ES", "NQ"], start_date="2020-01-01")

# Test mode: limit to N random symbols (seed-deterministic)
df = load_etfs(max_symbols=15)

When data is missing, loaders raise DataNotFoundError with download instructions.


API Keys

Free API Keys

Provider Variable Sign Up
FRED FRED_API_KEY https://fred.stlouisfed.org/docs/api/api_key.html
NASDAQ Data Link QUANDL_API_KEY https://data.nasdaq.com/sign-up
OANDA OANDA_API_KEY https://www.oanda.com/

Paid API Keys

Provider Variable Cost
Databento DATABENTO_API_KEY $125 free credit

Configuration

Create .env in repository root:

ML4T_DATA_PATH=/path/to/your/data

# Free API keys
FRED_API_KEY=your-fred-key
QUANDL_API_KEY=your-nasdaq-key
OANDA_API_KEY=your-oanda-key

# Paid
DATABENTO_API_KEY=db-your-key

Directory Structure

Every dataset directory is self-contained: a download script, a loader (or re-export from a parent loader), a README with the full instructions that DataNotFoundError points readers to, and optionally a config and exploration notebook.

Data is organized by asset class × data type, matching the Ch2 / Ch4 taxonomy. Each asset class has market/ for OHLCV-style data, and optionally fundamentals/, positioning/, or other type-specific subdirectories. Cross-asset datasets (factors/, macro/, prediction_markets/, alternative/) sit at the top level.

data/
├── __init__.py              # Single import point for all loaders
├── exceptions.py            # DataNotFoundError, DownloadError, MissingDependencyError
├── download_all.py          # Download orchestrator
├── README.md                # (this file)
│
├── equities/                # US equities
│   ├── market/              # us_equities, sp500 (daily + options), nasdaq100, microstructure
│   ├── fundamentals/        # 10-K / 10-Q / 8-K filings, XBRL financials
│   ├── positioning/         # 13F institutional holdings, Form 4 insider
│   ├── firm_characteristics/  # Chen-Pelger-Zhu panel (standalone packaged dataset)
│   └── loader.py            # All equities loaders in one module
│
├── futures/                 # CME futures
│   ├── market/              # Databento continuous + individual contracts
│   ├── positioning/         # CFTC Commitment of Traders (CoT)
│   └── loader.py
│
├── crypto/                  # Crypto
│   ├── market/              # Binance perps OHLCV + premium index
│   ├── onchain/             # DefiLlama TVL + CoinGecko OHLCV
│   └── loader.py
│
├── fx/market/               # FX pairs (OANDA)
├── etfs/market/             # ETF universe (Yahoo)
│
├── factors/                 # Fama-French, AQR (cross-asset, academic)
├── macro/                   # FRED macro indicators (cross-asset)
├── prediction_markets/      # Kalshi + Polymarket events
│
└── alternative/             # Cross-asset third-party alt data
    ├── news/                # Bloomberg, FNSPID
    └── text/                # Financial Phrasebook sentiment benchmark

Every subdirectory owns its data's lifecycle — a reader can open any leaf README and find the download command and file layout without consulting the top-level doc.

Equities Loaders (all in equities/loader.py)

Market (OHLCV, microstructure, options):

Loader Dataset Source
load_sp500_index() S&P 500 index OHLCV Bundled
load_us_equities() 3,199 US stocks (1962-2018) NASDAQ DL
load_sp500_daily_bars() S&P 500 daily OHLCV AlgoSeek
load_sp500_options() Raw options chains (legacy) AlgoSeek
load_sp500_options_eda() Options EDA slice (8 symbols, 2019-2020) AlgoSeek (slim)
load_sp500_options_straddles_raw() ATM-band raw chains, lifecycle-preserving (2017-2021) AlgoSeek (slim)
load_sp500_options_surface() Daily IV surface summary Materialized
load_sp500_options_straddles() Daily ATM straddles Materialized
load_nasdaq100_bars() NASDAQ-100 bars (minute default; resampling, quotes, full microstructure) AlgoSeek
load_nasdaq100_taq() TAQ tick data (AAPL, 2020-03-13 / 2020-03-16) AlgoSeek (slim)
load_mbo_data() MBO order book data Databento
load_nasdaq_itch() NASDAQ ITCH messages NASDAQ FTP
load_iex_hist() IEX DEEP/TOPS data IEX (free)

Fundamentals (SEC filings + XBRL):

Loader Dataset Source
load_sp500_10q_mda() S&P 500 10-Q MD&A text (2017-2021) SEC EDGAR
load_sec_filings(form_type) 10-K / 10-Q / 8-K aggregate text SEC EDGAR
resolve_sec_filings_dir() Per-ticker filings directory (Ch22 RAG) SEC EDGAR
load_sec_xbrl_fundamentals() XBRL financial facts (CIK × quarter × concept) SEC XBRL Frames

Positioning (13F):

Loader Dataset Source
load_institutional_holdings_13f() 13F holdings (per-cik, 10 curated managers) SEC EDGAR
load_13f_bulk_holdings(quarter) 13F full universe (~3M rows per quarter) SEC bulk
load_13f_stock_features() Stock-level features (breadth, concentration) Derived
load_13f_edges() Institution → stock edge list (graph) Derived

Firm characteristics (packaged dataset):

Loader Dataset Source
load_firm_characteristics() Chen-Pelger-Zhu panel (~180 features, returns + accounting) GitHub

Storage Requirements

Each row is a complete profile, not an increment on the row above. The first three were measured on a clean install; the additions below them are the individual dataset sizes to add on top.

Profile Contents Size How you get it
Minimum ETFs, Crypto, Factors (Fama-French + AQR) ~70 MB the individual download scripts above
Free, without firm characteristics Minimum + CFTC CoT, prediction markets ~75 MB --free-only --skip-firm-characteristics
Free the row above + firm characteristics ~4.1 GB --free-only

--free-only covers seven datasets and does not include Macro or FX; fetch those with their own scripts when a chapter needs them.

Add on top of any profile Size
US Equities ~670 MB
CME Futures ~85 MB
AlgoSeek slim package, ITCH, MBO ~6 GB

The Free row is where most readers land, because --free-only is what the README tells you to run. It is 4.1 GB rather than 75 MB entirely because of firm characteristics, which is 4.0 GB on its own, of which 3.5 GB is the dl_asset_pricing source archive.

These are data sizes only. The uv environment is a further ~11 GB on Linux and ~3 GB on macOS, and the cloned git history is ~0.9 GB.


Canonical Schema

All loaders return data with consistent column names:

  • Entity column: symbol (exception: CME futures use product)
  • Time column: timestamp (for all frequencies — daily, hourly, minute, tick)

Notebooks should always use these canonical names. If older data files use legacy names like asset, date, ticker, or pair, the loaders normalize them automatically.