HistoricalData

Historical Options Data for Python Research: A Reproducible Example

Load one daily CSV, select a SPY options chain and check which observations are usable before building a research dataset. This example runs on the free sample with Python's standard library.

Run the example

The sample includes TSLA, KO, SPY and SPX/SPXW for July–December 2022 in the paid archive's 34-column CSV format. The example selects SPY calls observed on 25 August 2022, expiring on 16 September 2022, with strikes from $400 to $440 inclusive.

Save these two scripts in the same folder. Use Python 3.10 or newer. No additional packages are needed.

Download sample-fetch script · Download research example · Free sample ZIP (239 MB)

python download_options_sample.py
python options_research.py

The download script verifies the pinned ZIP checksum. The research script then checks the selected daily file against its manifest, including its hash, byte size, row count and column order. It reads the CSV directly inside the ZIP, so extraction is unnecessary. A different sample version stops the example rather than silently changing its inputs.

The selection in Python

selected = [r for r in rows
    if r['underlying'] == 'SPY'
    and r['quote_date'] == '2022-08-25'
    and r['expiration'] == '2022-09-16'
    and r['type'] == 'call'
    and Decimal('400') <= number(r['strike']) <= Decimal('440')]

The script exposes each filter as a command-line argument. Symbols are matched exactly. It does not merge ticker histories or infer a contract's identity from its strike alone.

Actual results for this selection

Run on 9 November 2026 with Python 3.12.14, tutorial revision 1. These counts describe the selected sample rows, not an estimate of archive-wide completeness or accuracy.

CheckResult
Rows in the daily sample CSV, across all included symbols32,418
SPY calls matching the stated filters41
Positive, non-crossed bid and ask41 of 41
Midpoint IV with parity-derived forward, iv_flag = 041 of 41
Quote midpoint range, per share$0.805 to $21.78
Midpoint IV range, decimal units0.159196 to 0.239328

Download the complete run result (JSON). The midpoint is a calculation from the reported bid and ask, not a trade price or an executable fill. An IV of 0.159196 means 15.9196% in percentage units.

Keep missing values and zero values distinct

The narrow chain above has two-sided quotes throughout. Widening the strike range demonstrates why the missing-value checks matter.

python options_research.py --strike-min 0 --strike-max 1000

For the same SPY observation date, expiry and call type, the wider selection contains 283 contracts. Of those, 75 have no bid, 172 have recorded zero volume, and 126 have no midpoint IV. These populations can overlap. There are 208 positive, non-crossed two-sided quotes. View the wider run result (JSON).

def number(cell):
    return None if cell == '' else Decimal(cell)

bid, ask = number(row['bid']), number(row['ask'])
usable = bid is not None and ask is not None and 0 < bid <= ask
midpoint = (bid + ask) / 2 if usable else None

A blank bid or ask is unavailable. Filling the blank with zero would manufacture a midpoint. A recorded volume of zero remains zero and must not be dropped merely because it is false-like in Python. The example preserves both cases.

Read iv_flag with iv. Flags 0 and 1 identify solved midpoint IV, using respectively a parity-derived forward or the documented fallback forward. The wider run has 157 flag-0 rows, 75 flag-2 rows and 51 flag-3 rows. A usable two-sided quote alone does not guarantee a midpoint IV solution. Bid-side and ask-side IV are solved separately and must be checked independently. See the field definitions and current options README.

IV is a decimal. For the supplied Greeks, theta is per year, vega per 1.00 volatility and rho per 1.00 interest rate. Confirm these units before combining the data with another library.

Exact sample identity

The sample has 127 daily files. This tutorial reads one of them. Its checksum checks establish that the run used the stated bytes; they do not independently validate market prices.

ZIP SHA-256
8517b069f4d41e44f950dc79a3cdab694359b0fae91664190011e39dd8e48b76
Manifest SHA-256
be929e8164c92a6c0368af2e0877eb077bbc6cdaa5cb27365de5d102e958e160
2022-08-25_options.csv SHA-256
4eb2102efafc74d665cac5da8b938456bf2132843f2e4025d8a9e4ab5aada492

Keep the ZIP, scripts and result JSON together. The download script refuses a future sample with a different checksum. A revised tutorial requires a new run and updated results.

What this example does and does not establish

Next, compare CSV archives with APIs, inspect the other free samples, or review options coverage and purchase choices.