Vol Surface#
- class quantflow.options.surface.VolSurface(ref_date: ~datetime.datetime, asset: str, 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
Create a new volatility surface with the last num_maturities maturities
Attributes:
Name of the underlying asset
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
- 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
- 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
- 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
- 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
- trim(num_maturities: int) Self #
Create a new volatility surface with the last num_maturities maturities
- asset: str#
Name of the underlying asset
- 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(asset: str = '', 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, exclude_open_interest: ~decimal.Decimal | None = None, exclude_volume: ~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:
Name of the underlying asset
Day counter for time to maturity calculations - by default it uses Act/Act
Exclude options with open interest at or below this value
Exclude options with volume at or below this value
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: Decimal = Decimal('0'), volume: Decimal = Decimal('0')) None #
Add a forward to the volatility surface loader
- add_option(security: S, strike: Decimal, maturity: datetime, option_type: OptionType, bid: Decimal = Decimal('0'), ask: Decimal = Decimal('0'), open_interest: Decimal = Decimal('0'), volume: Decimal = Decimal('0')) None #
Add an option to the volatility surface loader
- add_spot(security: S, bid: Decimal = Decimal('0'), ask: Decimal = Decimal('0'), open_interest: Decimal = Decimal('0'), volume: Decimal = Decimal('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
- asset: str = ''#
Name of the underlying asset
- day_counter: DayCounter = <ccy.core.daycounter.ActAct object>#
Day counter for time to maturity calculations - by default it uses Act/Act
- exclude_open_interest: Decimal | None = None#
Exclude options with open interest at or below this value
- exclude_volume: Decimal | None = None#
Exclude options with volume at or below this value
- 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(asset: str = '', 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, exclude_open_interest: ~decimal.Decimal | None = None, exclude_volume: ~decimal.Decimal | None = None)#
A volatility surface loader
Methods:
Add a volatility security input to the loader
- add(input: VolSurfaceInput) 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