The sources module wraps yfinance to download live options chains in one call. Use list_expiry_dates to browse available dates, then fetch_chain to download a chain or surface.List available expiry datesfrom oipd import sources
expiries = sources.list_expiry_dates("AAPL")
# e.g. ["2026-05-15", "2026-06-19", "2026-09-18", ...]
print(expiries)
Download a single expirychain, snapshot = sources.fetch_chain("AAPL", expiries=expiries[1])
Download a multi-expiry surfacePass horizon instead of expiries to fetch all listed expiries within the window:chain_surface, snapshot_surface = sources.fetch_chain(
"AAPL",
horizon="12m", # "3m", "6m", "1y", etc.
)
You cannot pass both expiries and horizon — OIPD raises a ValueError if you do.Using the VendorSnapshotfetch_chain returns a (DataFrame, VendorSnapshot) tuple. The snapshot records the download context. Use its fields to populate MarketInputs:| Field | Type | Description |
|---|
.asof | datetime | Timestamp of the data pull |
.underlying_price | float | None | Underlying spot price at download time |
.vendor | str | Source vendor, e.g. "yfinance" |
from oipd import MarketInputs
market = MarketInputs(
valuation_date=snapshot.asof,
underlying_price=snapshot.underlying_price,
risk_free_rate=0.04,
)
fetch_chain caches network responses for 15 minutes by default. Pass cache_enabled=False or cache_ttl_minutes=5 to change the caching behavior.
sources.from_csv reads a CSV file and normalizes it to the OIPD standard column schema. It returns a DataFrame ready to pass directly to fit.Minimal examplefrom oipd import sources
chain = sources.from_csv("path/to/options.csv")
Data-loading minimum (after any remapping): strike, expiry, option_type, and one supported price source.Most vendor files use one of two shapes:
- BBO or CBBO quotes: use
bid and ask. This is preferred for fitting because OIPD can use the mid quote and keep spread diagnostics.
- OHLCV-style snapshots: use
last_price; include volume when you have it. OIPD preserves volume and uses it during SVI fitting when it relies on last-price data.
Use one row per option contract. The option_type column identifies calls and puts; the reader normalizes "call" / "put" to "C" / "P".BBO/CBBO is quote data: the current best bid and offer. OHLCV is trade data: the last traded price plus volume. Prefer bid and ask when you have them; use last_price with volume when your source only gives trades.
Other standard columns: last_trade_date is used for staleness filtering.Remapping non-standard column namesIf your CSV uses different column names, provide a column_mapping dictionary. The left side is the column in your file; the right side is the OIPD standard name. See Standard columns for the target names.chain = sources.from_csv(
"path/to/options.csv",
column_mapping={
"type": "option_type",
"expiration": "expiry",
"last": "last_price",
},
)
Here, "type" is a column in your CSV. OIPD treats it as option_type.The same reader is also available as the CSVReader class:from oipd.data_access.readers import CSVReader
reader = CSVReader()
chain = reader.read("path/to/options.csv", column_mapping={"type": "option_type"})