Skip to main content

option-chain-analytics

Point-in-time option-chain containers, feed normalisation, reconstruction, and queries for quantitative research

OCA is the data-container layer: provider credentials and data rights, stochastic-volatility models, strategy backtests, and proprietary datasets remain separate.

Install: pip install option-chain-analytics · Import: option_chain_analytics · Status: Beta

PyPI Python CI Docs License Downloads Monthly

Documentation: optionchainanalytics.readthedocs.io · schema contract · point-in-time reconstruction · data-source guide · examples guide


Why option-chain-analytics

Provider feeds disagree on schemas, timestamps, identifiers, units, and available fields, and a scheduled research path that reads them directly can silently select future data. OCA normalises those feeds into one long-form OptionsDataDFs panel, then reconstructs an auditable SlicesChain at an exact observation time or the latest explicitly requested prior observation.

Key differentiators

  • One schema for every feed. SliceColumn defines the common option-feed schema — source time, contract, forward, discount factor, strike, expiry, quote, implied volatility, Greeks, volume, and open interest — and every adapter (simulated, CBOE, Deribit/Tardis, ThetaData, Bloomberg) lands on it; see the schema contract.
  • Point-in-time by contract. Observation and expiry timestamps are timezone-aware; exact lookup is the reconstruction default, and scheduled studies can explicitly select the latest previous observation but never a later one; see point-in-time reconstruction.
  • Stated units. Volatilities are decimals (0.20 means 20%), time to maturity is in years, and each adapter must preserve and document its price/multiplier convention.
  • Analytics delegated, not duplicated. Every bid, mark, and ask implied volatility and every mark Greek is computed by vanilla-option-pricers; the call-put parity utility under option_chain_analytics.utils has no provider or optional-solver dependency.
  • A credential-free path. The deterministic simulated-data path exercises the same containers and queries as the optional empirical adapters.

When to use it — and when not

Use option-chain-analytics to normalise option feeds into one panel, to reconstruct a chain at an exact historical observation time, to query one expiry for ATM, delta-strike, volatility, open-interest and execution-price values, to run quote-quality and parity diagnostics, and to build resumable local caches for repeated empirical studies.

OCA is the data-container layer: provider credentials and data rights, stochastic-volatility models (see stochvolmodels), strategy backtests, and proprietary datasets remain separate. Vanilla pricing is vanilla-option-pricers; portfolio analytics and reporting are qis.

Installation

OptionChainAnalytics 6.0.0 requires Python 3.11 or newer. CI covers Python 3.11 through 3.14. Python 3.10 users must remain on the 5.3.x release line.

Install the published package:

pip install option-chain-analytics

Provider-specific integrations are optional:

Extra Capability
cboe Local Arrow/Feather CBOE fitted-chain files
deribit Deribit HTTP collection helpers
bloomberg Bloomberg retrieval through bbg-fetch
thetadata ThetaData national EOD equity/ETF option reports (Python 3.12+)
docs, all Documentation, or every optional integration

For example, pip install "option-chain-analytics[cboe]" installs the CBOE file dependency without installing unrelated network providers. Contributor test and lint tools live in the locked test and lint dependency groups rather than a published dev extra; see Testing.

Empirical datasets are not distributed. OCA_DATA_PATH holds raw provider archives, OCA_CACHE_PATH holds normalised reusable chains, and OCA_OUTPUT_PATH holds generated reports; their source-checkout defaults are the ignored data/, resources/, and outputs/ directories. The data catalogue defines every supported provider directory, cache filename, and loader.

Table of contents

  1. Why option-chain-analytics
  2. Installation
  3. Statement of need
  4. Overview
  5. Five-minute quickstart
  6. Examples
  7. Testing
  8. Changelog
  9. Feedback & contributing
  10. Citation
  11. Ecosystem
  12. License
  13. Disclaimer

Statement of need

Empirical option research needs a public, auditable input layer: a chain reconstructed at a stated observation time from a stated provider record, with stated units and no look-ahead, so that a replication can start from the same object the study used. OCA provides that layer. Strategy logic and the QF-paper backtests remain in SigmaStrats, and a public example is not expected to reproduce results computed from a private production dataset exactly. Dataset licences and access terms are separate from the software licence. No research paper is implemented in this package; OCA is upstream of stochvolmodels, whose paper replications consume OCA chains through its optional research workflow.

Overview

The installable package lives under src/option_chain_analytics/; repository-only scripts live in examples/. Provider adapters own feed-specific choices such as report alignment, rate symbols, settlement timestamps, product scope, and admissible bounds; reusable numerical kernels live separately under option_chain_analytics.utils. Component development diagnostics live beside their implementation in src/option_chain_analytics/**/run_local/*_run.py, expose Locals and run_local(local=...), and are excluded from distributions (the run_local folders use implicit namespace-package support and contain no __init__.py). Raw datasets, normalised caches, agent reports, and generated outputs live in ignored data/, resources/, agents/, and outputs/ directories.

Data model:

  • OptionsDataDFs holds an option-observation panel (chain_ts) plus an aligned spot-price frame.
  • SlicesChain reconstructs all available expiries at one exact observation time.
  • ExpirySlice provides call/put, ATM, delta-strike, volatility, open-interest, and execution-price queries for one expiry.
  • SliceColumn defines the common option-feed schema, including source time, contract, forward, discount factor, strike, expiry, quote, implied volatility, Greeks, volume, and open interest.

Analytics at a glance

Area What the package computes
Normalisation Provider feeds (deterministic simulator, local CBOE fitted-chain files, Deribit/Tardis crypto histories, ThetaData national EOD reports, Bloomberg through bbg-fetch) → one long-form OptionsDataDFs panel on the SliceColumn schema; the CBOE mapper infers bid/ask implied volatilities from source bid/ask prices with the contemporaneous forward, discount factor and time to maturity
Reconstruction create_chain_at_time → SlicesChain at an exact observation time, or the latest explicitly requested prior observation, never a later one; every provider report retains its actual timestamp
Queries ExpirySlice call/put, ATM strike and volatility, delta-strike, volatility, open-interest and execution-price queries; weekly roll maturity selection; see queries
Diagnostics Quote-quality, parity and source-row diagnostics on synthetic or empirical data, exact-pair parity attribution and recovery from original records; see quote diagnostics
Caches Normalised Parquet caches per underlying (build_local_cboe_options_cache, build_thetadata_eod_cache / load_thetadata_eod_cache with resumable monthly partitions, schema and source-file fingerprints, stale-cache rejection); standardized local SPX, VIX, BTC and ETH cache construction
Reports Cache-first ATM/skew time-series plots and multi-expiry PDF chain reports (run_chain_report)

Five-minute quickstart

The authoritative offline repository example constructs a deterministic Black-Scholes-Merton option panel, reconstructs a historical chain, queries its front-expiry ATM strike and volatility, and selects a weekly roll maturity. The examples/ directory is not included in the wheel, so run this from a source clone:

git clone https://github.com/ArturSepp/OptionChainAnalytics.git
cd OptionChainAnalytics
python examples/first_success.py

Expected evidence:

ticker=SYNTH
observation_times=2
contracts_at_first_time=30
expiries=['12Jan2024', '19Jan2024', '16Feb2024']
first_expiry_atm=100.00, vol=0.2057
weekly_roll_expiries=['12Jan2024']

See examples/first_success.py for the executable source. The documentation includes that file directly, so the tutorial cannot drift into a second implementation.

Examples

Highlighted examples

Local CBOE fitted-chain files (the cboe extra):

from option_chain_analytics import OptionsDataDFs
from option_chain_analytics.data.cboe import load_local_cboe_options_data

options_data = OptionsDataDFs(
    **load_local_cboe_options_data(
        ticker='SPX',
        start='2023-01-03',
        end='2023-01-03',
    )
)

For repeated empirical studies, build one normalised Parquet cache per underlying with build_local_cboe_options_cache(ticker='SPX'); the normal loader uses a valid cache automatically and still accepts start/end filters, and OCA rejects stale caches. CBOE data supplies implied forwards but no independent spot series: pass spot_data, or use is_use_front_forward_as_spot=True only for visualisation; a forward proxy is not a valid spot return series for backtesting.

ThetaData EOD cache, reconstruction and report (the thetadata extra; the official client reads THETADATA_API_KEY, and credentials and raw provider responses are never written to OCA's normalised cache):

import pandas as pd

from option_chain_analytics import (
    build_thetadata_eod_cache, create_chain_at_time, load_thetadata_eod_cache,
)

cache_root = build_thetadata_eod_cache(
    ticker='NVDA',
    start_date='2023-06-01',
    min_dte=0,
    max_dte=60,
    strike_range=20,
)
nvda_july = load_thetadata_eod_cache(cache_root, start_date='2026-07-01', end_date='2026-07-31')

# Every provider report retains its actual timestamp; reconstruct the chain exactly at one of them
value_time = nvda_july.get_timeindex()[-1]
chain = create_chain_at_time(nvda_july, value_time)
print('value_time:', chain.value_time)
print('expiries:', list(chain.expiry_slices))
print('contracts:', len(chain.options_df))

The builder requests one month at a time and checkpoints each completed partition, so an interrupted request can be rerun safely; monthly Parquet files are only the resumable physical layout and the loader returns one continuous OptionsDataDFs. Index options with product-specific or AM settlement conventions are deliberately outside this adapter. The adapter records the provider's actual EOD report time, joins only an underlying report available at or before that time, and preserves both calls and puts; direct snapshot and time-series loads retrieve ThetaData SOFR EOD by default to anchor the discount factor and then infer forwards from parity (rate_symbol=None for a parity-only fit), while the partitioned cache builder uses the parity-only policy. The equivalent repository commands:

python examples/build_thetadata_eod_cache.py --ticker NVDA --start-date 2023-06-01
python examples/run_chain_report.py --ticker NVDA --date 2026-07-17 --output nvda_chain_report.pdf

Runnable examples

The examples guide lists every script, its required data, whether it makes a network request, and its output. Removed research prototypes are not retained as runnable examples.

Testing

uv sync --locked --group test
uv run --no-sync pytest -q
uv run --locked --only-group lint ruff check .

Automated checks use tests/test_*.py and need no provider credentials; the credential-free simulated-data path exercises the same containers and queries as the optional empirical adapters. The documentation and distribution checks from a source checkout are:

uv sync --locked --extra docs
uv run --no-sync python -m sphinx -E -W --keep-going -b html docs docs/_build/html
uv build --sdist --clear --out-dir dist
uv build --wheel dist/*.tar.gz --out-dir dist
uv run --no-project python tools/verify_distribution.py dist

Changelog

Release history is maintained in CHANGELOG.md.

Feedback & contributing

  • Bug: report a reproducible bug, including the package version, Python/platform, provider or simulated-data path, timestamps, and expected versus actual result.
  • Feature: request a feature, explaining which field, provider, or normalisation workflow is missing, the current workaround, and the smallest useful API.
  • Question or methodology: search or open an issue and name the adapter, schema column, or point-in-time rule involved.
  • Contribution: read CONTRIBUTING.md for the data-licensing boundary, development commands, point-in-time rules, and pull-request guidance.

Citation

Machine-readable citation metadata is provided in CITATION.cff.

A copyable software citation is:

@software{sepp2026optionchainanalytics,
  title={option-chain-analytics: Point-in-time option-chain containers, feed normalisation, reconstruction, and queries for quantitative research},
  author={Sepp, Artur},
  year={2026},
  version={6.0.0},
  url={https://github.com/ArturSepp/OptionChainAnalytics}
}

Ecosystem

This package is part of an open-source Python stack for quantitative finance. The ArturSepp profile is the canonical catalogue:

Package Purpose
qis Performance analytics, backtesting, and factsheet reporting
optimalportfolios Portfolio construction and rolling backtesting
factorlasso Sparse factor-model estimation
bbg-fetch Bloomberg data in pandas DataFrames
option-chain-analytics (this package) Point-in-time option-chain data and queries
vanilla-option-pricers Numba-vectorised BSM and Bachelier pricing
stochvolmodels Stochastic-volatility pricing and calibration
trendfollowing Closed-form trend-following analytics
privateassets Multi-factor PME for private assets
goal-based-allocation Goal-based allocation under regime-switching jump-diffusions

OCA depends on qis for general time-series and visualisation utilities and on vanilla-option-pricers for vanilla prices, Greeks, and implied-volatility inversion. bbg-fetch is an optional provider integration. OCA remains upstream of stochvolmodels, which consumes it only through the optional research workflow.

License

The software is released under the MIT License. The software licence does not grant rights to any empirical dataset loaded through an optional provider integration.

Disclaimer

option-chain-analytics is distributed FREE & WITHOUT ANY WARRANTY under the MIT License. See LICENSE in the release for details. Use the routes in Feedback & contributing for bugs, feature requests and methodology questions.

Metadata

Release files for option-chain-analytics 6.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for option-chain-analytics 6.0.0
File Size Uploaded Provenance
option_chain_analytics-6.0.0.tar.gz 166.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for option-chain-analytics 6.0.0
File Interpreter ABI Platform
option_chain_analytics-6.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 260.1 kB

Release files / option_chain_analytics-6.0.0.tar.gz

Download URL option_chain_analytics-6.0.0.tar.gz
Size 166.5 kB
Tags Source
SHA-256 checksum
How to use checksums
022a5162f8ae62da74477cbefda95557698bf216d283d007cd87ed0ddd6b9bc6
BLAKE2b-256 checksum
How to use checksums
01cd8e3973ecc875fc4623e8ef065368c7b5475e5062a1569f64d3b4a6902a25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / option_chain_analytics-6.0.0-py3-none-any.whl

Download URL option_chain_analytics-6.0.0-py3-none-any.whl
Size 93.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ea621b39b1721d9451ee134111a95acb53ad771b81347e4246bf095e03e865b4
BLAKE2b-256 checksum
How to use checksums
2b238d85d2c51040e26402732c9147bcaacf2e00844c4dd86f9b3a6327957744
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for option-chain-analytics 6.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for option_chain_analytics-6.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

6.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page