Skip to main content
OIPD needs a small market snapshot before it can read an options chain. That snapshot is MarketInputs.

Fields

MarketInputs has two required fields:
FieldMeaning
valuation_dateThe date or time the option prices belong to
risk_free_rateThe rate used to discount option payoffs
It also accepts one optional field:
FieldMeaning
underlying_priceThe current price of the asset or futures contract
The dataclass allows underlying_price=None, but fitting does not. Before you call .fit, populate it yourself or take it from a VendorSnapshot.
By default, you do not need to enter dividends. OIPD infers the forward price from put-call parity and uses Black-76 for IV inversion. The fitted forward already reflects the market’s expected carry, including dividends.

Valuation date

Options are priced over time to expiry. If the valuation date is wrong, OIPD will measure the remaining time incorrectly. That affects implied volatility and the probability distribution derived from it. Use the timestamp attached to the data where possible.

Underlying price

underlying_price means the price of the thing the option is written on. For stock or ETF options, it is the spot price. For futures options, it is the relevant futures price. This distinction matters because OIPD uses the price and the option chain to infer a forward price during calibration.

Rates

By default, risk_free_rate is read as a simple annualized rate. Pass risk_free_rate_mode="continuous" if your rate is continuously compounded.

Manual example

from oipd import MarketInputs

market = MarketInputs(
    valuation_date="2024-01-15",
    underlying_price=175.0,
    risk_free_rate=0.04,
)

Vendor example

sources.fetch_chain returns both an options chain and a VendorSnapshot. By default, OIPD tries to fetch the ticker from yfinance. The snapshot stores the vendor timestamp and underlying price.
from oipd import MarketInputs, sources

expiry = sources.list_expiry_dates("AAPL")[0]
chain, snapshot = sources.fetch_chain("AAPL", expiries=[expiry])

market = MarketInputs(
    valuation_date=snapshot.asof,
    underlying_price=snapshot.underlying_price,
    risk_free_rate=0.04,
)
Use snapshot.asof rather than datetime.now(). It ties the model to the time when the option prices were observed.