Vol Surface#
- class quantflow.options.surface.VolSurface(ref_date: ~datetime.datetime, spot: ~quantflow.options.surface.SpotPrice[~quantflow.options.surface.S], maturities: tuple[~quantflow.options.surface.VolCrossSection[~quantflow.options.surface.S], ...], day_counter: ~ccy.core.daycounter.DayCounter = <ccy.core.daycounter.ActAct object>, tick_size_forwards: ~decimal.Decimal | None = None, tick_size_options: ~decimal.Decimal | None = None)#
Represents a volatility surface, which captures the implied volatility of an option for different strikes and maturities.
Key Concepts:
- Implied Volatility: The market’s expectation of future volatility, derived
from the price of an option using a pricing model (e.g., Black-Scholes).
- Strike Price: The price at which the underlying asset can be bought
(call option) or sold (put option) at the option’s expiry.
Time to Maturity: The time remaining until the option’s expiration date.
- Volatility Smile/Skew: The often-observed phenomenon where implied
volatility varies across different strike prices for the same maturity. Typically, it forms a “smile” or “skew” shape.
This class provides a structure for storing and manipulating volatility surface data. It can be used for various tasks, such as:
- Option pricing and risk management: Using the surface to determine the
appropriate volatility input for pricing models.
- Volatility arbitrage: Identifying mispricings in options by comparing
market prices to model prices derived from the surface.
- Market analysis: Understanding market sentiment and expectations of
future volatility.
Methods:
Organize option prices in a numpy arrays for black volatility calculation
calculate Black-Scholes implied volatility for all options in the surface
calculate Black-Scholes prices for all options in the surface
List of selected option prices in the surface
Iterator over selected option prices in the surface
Time frame of Black-Scholes call input data
Plot the volatility surface
Plot the volatility surface
Iterator over all securities in the volatility surface
Return the term structure of the volatility surface
Attributes:
Day counter for time to maturity calculations - by default it uses Act/Act
Sorted tuple of
VolCrossSection
for different maturitiesReference date for the volatility surface
Spot price of the underlying asset
Tick size for rounding forward and spot prices - optional
Tick size for rounding option prices - optional
- as_array(*, select: OptionSelection = OptionSelection.best, index: int | None = None, initial_vol: float = 0.5, converged: bool = True) OptionArrays #
Organize option prices in a numpy arrays for black volatility calculation
- bs(*, select: OptionSelection = OptionSelection.best, index: int | None = None, initial_vol: float = 0.5) list[OptionPrice] #
calculate Black-Scholes implied volatility for all options in the surface
- Parameters:
select – the
OptionSelection
methodindex – Index of the cross section to use, if None use all
initial_vol – Initial volatility for the root finding algorithm
Some options may not converge, in this case the implied volatility is not calculated correctly and the option is marked as not converged.
- calc_bs_prices(*, select: OptionSelection = OptionSelection.best, index: int | None = None) ndarray #
calculate Black-Scholes prices for all options in the surface
- option_list(*, select: OptionSelection = OptionSelection.best, index: int | None = None, converged: bool = True) list[OptionPrice] #
List of selected option prices in the surface
- option_prices(*, select: OptionSelection = OptionSelection.best, index: int | None = None, initial_vol: float = 0.5, converged: bool = True) Iterator[OptionPrice] #
Iterator over selected option prices in the surface
- options_df(*, select: OptionSelection = OptionSelection.best, index: int | None = None, initial_vol: float = 0.5, converged: bool = True) DataFrame #
Time frame of Black-Scholes call input data
- plot(*, index: int | None = None, select: OptionSelection = OptionSelection.best, **kwargs: Any) Any #
Plot the volatility surface
- plot3d(*, select: OptionSelection = OptionSelection.best, **kwargs: Any) Any #
Plot the volatility surface
- securities() Iterator[SpotPrice[S] | FwdPrice[S] | OptionPrices[S]] #
Iterator over all securities in the volatility surface
- term_structure(frequency: float = 0) DataFrame #
Return the term structure of the volatility surface
- day_counter: DayCounter = <ccy.core.daycounter.ActAct object>#
Day counter for time to maturity calculations - by default it uses Act/Act
- maturities: tuple[VolCrossSection[S], ...]#
Sorted tuple of
VolCrossSection
for different maturities
- ref_date: datetime#
Reference date for the volatility surface
- spot: SpotPrice[S]#
Spot price of the underlying asset
- tick_size_forwards: Decimal | None = None#
Tick size for rounding forward and spot prices - optional
- tick_size_options: Decimal | None = None#
Tick size for rounding option prices - optional
- class quantflow.options.surface.VolCrossSection(maturity: ~datetime.datetime, forward: ~quantflow.options.surface.FwdPrice[~quantflow.options.surface.S], strikes: tuple[~quantflow.options.surface.Strike[~quantflow.options.surface.S], ...], day_counter: ~ccy.core.daycounter.DayCounter = <ccy.core.daycounter.ActAct object>)#
Represents a cross section of a volatility surface at a specific maturity.
Methods:
Return a dictionary with information about the cross section
Iterator over option prices in the cross section
Return a list of all securities in the cross section
Time to maturity in years
Attributes:
Day counter for time to maturity calculations - by default it uses Act/Act
Forward price of the underlying asset at the time of the cross section
Maturity date of the cross section
Tuple of sorted strikes and their corresponding option prices
- info_dict(ref_date: datetime, spot: SpotPrice[S]) dict #
Return a dictionary with information about the cross section
- option_prices(ref_date: datetime, *, select: OptionSelection = OptionSelection.best, initial_vol: float = 0.5, converged: bool = True) Iterator[OptionPrice] #
Iterator over option prices in the cross section
- securities() Iterator[FwdPrice[S] | OptionPrices[S]] #
Return a list of all securities in the cross section
- ttm(ref_date: datetime) float #
Time to maturity in years
- day_counter: DayCounter = <ccy.core.daycounter.ActAct object>#
Day counter for time to maturity calculations - by default it uses Act/Act
- forward: FwdPrice[S]#
Forward price of the underlying asset at the time of the cross section
- maturity: datetime#
Maturity date of the cross section
- strikes: tuple[Strike[S], ...]#
Tuple of sorted strikes and their corresponding option prices
- class quantflow.options.surface.GenericVolSurfaceLoader(spot: ~quantflow.options.surface.SpotPrice[~quantflow.options.surface.S] | None = None, maturities: dict[~datetime.datetime, ~quantflow.options.surface.VolCrossSectionLoader[~quantflow.options.surface.S]] = <factory>, day_counter: ~ccy.core.daycounter.DayCounter = <ccy.core.daycounter.ActAct object>, tick_size_forwards: ~decimal.Decimal | None = None, tick_size_options: ~decimal.Decimal | None = None)#
Helper class to build a volatility surface from a list of securities
Methods:
Add a forward to the volatility surface loader
Add an option to the volatility surface loader
Add a spot to the volatility surface loader
Build a volatility surface from the provided data
Attributes:
Day counter for time to maturity calculations - by default it uses Act/Act
Dictionary of maturities and their corresponding cross section loaders
Spot price of the underlying asset
Tick size for rounding forward and spot prices - optional
Tick size for rounding option prices - optional
- add_forward(security: S, maturity: datetime, bid: Decimal = Decimal('0'), ask: Decimal = Decimal('0'), open_interest: int = 0, volume: int = 0) None #
Add a forward to the volatility surface loader
- add_option(security: S, strike: Decimal, maturity: datetime, call: bool, bid: Decimal = Decimal('0'), ask: Decimal = Decimal('0'), open_interest: int = 0, volume: int = 0) None #
Add an option to the volatility surface loader
- add_spot(security: S, bid: Decimal = Decimal('0'), ask: Decimal = Decimal('0'), open_interest: int = 0, volume: int = 0) None #
Add a spot to the volatility surface loader
- surface(ref_date: datetime | None = None) VolSurface[S] #
Build a volatility surface from the provided data
- day_counter: DayCounter = <ccy.core.daycounter.ActAct object>#
Day counter for time to maturity calculations - by default it uses Act/Act
- maturities: dict[datetime, VolCrossSectionLoader[S]]#
Dictionary of maturities and their corresponding cross section loaders
- spot: SpotPrice[S] | None = None#
Spot price of the underlying asset
- tick_size_forwards: Decimal | None = None#
Tick size for rounding forward and spot prices - optional
- tick_size_options: Decimal | None = None#
Tick size for rounding option prices - optional
- class quantflow.options.surface.VolSurfaceLoader(spot: ~quantflow.options.surface.SpotPrice[~quantflow.options.surface.S] | None = None, maturities: dict[~datetime.datetime, ~quantflow.options.surface.VolCrossSectionLoader[~quantflow.options.surface.S]] = <factory>, day_counter: ~ccy.core.daycounter.DayCounter = <ccy.core.daycounter.ActAct object>, tick_size_forwards: ~decimal.Decimal | None = None, tick_size_options: ~decimal.Decimal | None = None)#
Methods:
Add a volatility security input to the loader
- add(input: VolSurfaceInput[Any]) None #
Add a volatility security input to the loader
- Params input:
The input data for the security, it can be spot, forward or option
- class quantflow.options.surface.OptionSelection(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)#
Option selection method
This enum is used to select which one between calls and puts are used for calculating implied volatility and other operations
- best = 1#
Select the best bid/ask options.
These are the options which are Out of the Money, where their intrinsic value is zero
- call = 2#
Select the call options only
- put = 3#
Select the put options only