Vol Slices¶
- class KVMVolSlice(spot, rf_rate, dividend_yield, strikes, vols, *, _id=<factory>)¶
Bases:
VolSlice- Parameters:
spot (float)
rf_rate (float)
dividend_yield (float)
strikes (List[float] | Tuple[float, ...] | PVector[float])
vols (List[float] | Tuple[float, ...] | PVector[float])
_id (ObjectIdField)
- atmf_ivol()¶
- Return type:
float
- atmf_skew(space='strike')¶
output is: - dIVol/dStrike[strike=forward] (if space = ‘strike’) - dIVol/dMoneyness[moneyness=0] (if space = ‘moneyness’)
- Parameters:
space (str)
- Return type:
float
- get_call_iprices(strikes=None, discounted=True)¶
This function is usefull to check the smile curve does not have butterfly arbitrage. See function “has_vol_arbitrages” for more details.
When we transform data using the isotonic regression we only get the overall trend/shape of the function. To fully specify the function we need to chose a value for a given point or an overall/mean value. Picking an arbitrary price level may lead to option prices below the intrinsic price. An alternative is to chose a level of the time-value curce i.e.
TimeValue = Price - IntrinsicValue
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
discounted (bool)
- Return type:
List[float | None]
- get_call_iprices_()¶
- Return type:
List[float | None]
- get_call_prices(strikes=None, discounted=True)¶
This function is usefull to check the smile curve does not have butterfly arbitrage. See function “has_vol_arbitrages” for more details.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
discounted (bool)
- Return type:
List[float | None]
- get_call_prices_()¶
- Return type:
List[float | None]
- get_call_prices_with_derivatives(strikes, discounted)¶
- Returns both following lists:
[CallPrice(strike) for strike in strikes]
[dCallPrice(strike)/dStrike for strike in strikes]
This utility is usefull when interpolating vol slices between 2 different expiration dates. We will be using the formula suggested by Gatheral and Jacquier in: - Arbitrage-free SVI volatility surfaces, Jim Gatheral and Antoine Jacquier, March 2013 - https://arxiv.org/pdf/1204.0646 The relevant formula from section 5.3 is:
C_t / K_t = α_t * (C_1 / K_1) + (1 - α_t) * (C_2 / K_2)
- where:
C_t: Value of C at time t
K_t: Value of K at time t
α_t: Weighting factor at time t
C_1, C_2: Constants
K_1, K_2: Constants
A key part of the interpolation is to also fit the skew dVol/dK. This requires dC/dK which can also be obtained as a weighted average of dC_1/dK and dC_2/dK.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
discounted (bool)
- Return type:
Tuple[List[float], List[float]]
- get_discount_factor()¶
- Return type:
float
- get_forward()¶
- Return type:
float
- get_pvalue(strike)¶
- Parameters:
strike (float)
- Return type:
float
- get_pvalues(strikes=None)¶
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
- Return type:
List[float]
- get_vol(strike)¶
- Parameters:
strike (float)
- Return type:
Tuple[float, float]
- get_vols(strikes=None)¶
This function returns the ivol and the derivative d_ivol/d_strike for each strike in the list.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
- Return type:
Tuple[List[float], List[float]]
- get_zscore(strike)¶
- Parameters:
strike (float)
- Return type:
float
- get_zscores(strikes=None)¶
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
- Return type:
List[float]
- has_vol_arbitrages()¶
Check the if smile curve has butterfly arbitrages. The conditions are:
- with function :
C : k -> bs_call(k, sigma(k))
that function “C” should be convex
that function C should be non-increasing
- Return type:
bool
- lk_interp()¶
Returns a function “log(strike) -> ivol”
- Return type:
Callable[[float], float]
- min_ivol()¶
- Return type:
float
- min_ivol_moneyness()¶
- Return type:
float
- min_ivol_strike()¶
- Return type:
float
- moneyness_bounds()¶
- Return type:
Tuple[float, float]
- p_interp(solver='Brent')¶
Returns a function “p_value -> (strike, ivol)”
Note that the interpolation is linear in the log(strike) space.
- Parameters:
solver (str)
- Return type:
Callable[[float], Tuple[float, float]]
- strike_bounds()¶
- Return type:
Tuple[float, float]
- total_variance()¶
- Return type:
float
- property as_of_date: date¶
- property dividend_yield: float¶
Dividend Yield between as_of_date and expiration_date
- property exercise_style: str¶
- property expiration_date: date¶
- property last_updated¶
- property rf_rate: float¶
Risk Free Rate between as_of_date and expiration_date
- property spot: float¶
Spot price of the option underlying
- property strikes: PVector[float]¶
A list of strike prices for which the volatility is mapped
- property ticker: str¶
- property vols: PVector[float]¶
A list of volatility aligned with the strike prices list
- class CHSVolSlice(spot, rf_rate, dividend_yield, strikes, vols, dvols, *, _id=<factory>)¶
Bases:
KVMVolSlice- A volatility slice representation based on the mapping:
strike -> (ivol, divol/dstrike)
Specifying the vol skew (i.e. the derivative) allows us to build a spline from a smaller set of strikes.
- Parameters:
spot (float)
rf_rate (float)
dividend_yield (float)
strikes (List[float] | Tuple[float, ...] | PVector[float])
vols (List[float] | Tuple[float, ...] | PVector[float])
dvols (List[float] | Tuple[float, ...] | PVector[float])
_id (ObjectIdField)
- atmf_ivol()¶
- Return type:
float
- atmf_skew(space='strike')¶
output is: - dIVol/dStrike[strike=forward] (if space = ‘strike’) - dIVol/dMoneyness[moneyness=0] (if space = ‘moneyness’)
- Parameters:
space (str)
- Return type:
float
- get_call_iprices(strikes=None, discounted=True)¶
This function is usefull to check the smile curve does not have butterfly arbitrage. See function “has_vol_arbitrages” for more details.
When we transform data using the isotonic regression we only get the overall trend/shape of the function. To fully specify the function we need to chose a value for a given point or an overall/mean value. Picking an arbitrary price level may lead to option prices below the intrinsic price. An alternative is to chose a level of the time-value curce i.e.
TimeValue = Price - IntrinsicValue
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
discounted (bool)
- Return type:
List[float | None]
- get_call_iprices_()¶
- Return type:
List[float | None]
- get_call_prices(strikes=None, discounted=True)¶
This function is usefull to check the smile curve does not have butterfly arbitrage. See function “has_vol_arbitrages” for more details.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
discounted (bool)
- Return type:
List[float | None]
- get_call_prices_()¶
- Return type:
List[float | None]
- get_call_prices_with_derivatives(strikes, discounted)¶
- Returns both following lists:
[CallPrice(strike) for strike in strikes]
[dCallPrice(strike)/dStrike for strike in strikes]
This utility is usefull when interpolating vol slices between 2 different expiration dates. We will be using the formula suggested by Gatheral and Jacquier in: - Arbitrage-free SVI volatility surfaces, Jim Gatheral and Antoine Jacquier, March 2013 - https://arxiv.org/pdf/1204.0646 The relevant formula from section 5.3 is:
C_t / K_t = α_t * (C_1 / K_1) + (1 - α_t) * (C_2 / K_2)
- where:
C_t: Value of C at time t
K_t: Value of K at time t
α_t: Weighting factor at time t
C_1, C_2: Constants
K_1, K_2: Constants
A key part of the interpolation is to also fit the skew dVol/dK. This requires dC/dK which can also be obtained as a weighted average of dC_1/dK and dC_2/dK.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
discounted (bool)
- Return type:
Tuple[List[float], List[float]]
- get_discount_factor()¶
- Return type:
float
- get_forward()¶
- Return type:
float
- get_pvalue(strike)¶
- Parameters:
strike (float)
- Return type:
float
- get_pvalues(strikes=None)¶
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
- Return type:
List[float]
- get_vol(strike)¶
- Parameters:
strike (float)
- Return type:
Tuple[float, float]
- get_vols(strikes=None)¶
This function returns the ivol and the derivative d_ivol/d_strike for each strike in the list.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
- Return type:
Tuple[List[float], List[float]]
- get_zscore(strike)¶
- Parameters:
strike (float)
- Return type:
float
- get_zscores(strikes=None)¶
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float] | None)
- Return type:
List[float]
- has_vol_arbitrages()¶
Check the if smile curve has butterfly arbitrages. The conditions are:
- with function :
C : k -> bs_call(k, sigma(k))
that function “C” should be convex
that function C should be non-increasing
- Return type:
bool
- lk_interp()¶
Returns a function that interpolates log(strike) -> ivol using cubic Hermite splines. This function uses both the values of the volatilities and their skews (dvol/dstrike).
Since the interpolation is based on log(strike), the dvols must be transformed to dvol/dlog(strike) using the chain rule: dvol/dlog(strike) = dvol/dstrike * strike.
- Return type:
Callable[[float], float]
- min_ivol()¶
- Return type:
float
- min_ivol_moneyness()¶
- Return type:
float
- min_ivol_strike()¶
- Return type:
float
- moneyness_bounds()¶
- Return type:
Tuple[float, float]
- p_interp(solver='Brent')¶
Returns a function “p_value -> (strike, ivol)”
Note that the interpolation is linear in the log(strike) space.
- Parameters:
solver (str)
- Return type:
Callable[[float], Tuple[float, float]]
- strike_bounds()¶
- Return type:
Tuple[float, float]
- total_variance()¶
- Return type:
float
- property as_of_date: date¶
- property dividend_yield: float¶
Dividend Yield between as_of_date and expiration_date
- property dvols: PVector[float]¶
- property exercise_style: str¶
- property expiration_date: date¶
- property last_updated¶
- property rf_rate: float¶
Risk Free Rate between as_of_date and expiration_date
- property spot: float¶
Spot price of the option underlying
- property strikes: PVector[float]¶
A list of strike prices for which the volatility is mapped
- property ticker: str¶
- property vols: PVector[float]¶
A list of volatility aligned with the strike prices list
- class SVIVolSlice(forward, svi, *, _id=<factory>)¶
Bases:
VolSlice- Parameters:
forward (float)
svi (SVIParameters | Dict[str, float])
_id (ObjectIdField)
- atmf_ivol()¶
- Return type:
float
- atmf_skew(space='strike')¶
output is: - dIVol/dStrike[strike=forward] (if space = ‘strike’) - dIVol/dMoneyness[moneyness=0] (if space = ‘moneyness’)
- Parameters:
space (str)
- Return type:
float
- get_call_prices(strikes, discounted)¶
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
discounted (bool)
- Return type:
List[float | None]
- get_call_prices_with_derivatives(strikes, discounted)¶
- Returns both following lists:
[CallPrice(strike) for strike in strikes]
[dCallPrice(strike)/dStrike for strike in strikes]
This utility is usefull when interpolating vol slices between 2 different expiration dates. We will be using the formula suggested by Gatheral and Jacquier in: - Arbitrage-free SVI volatility surfaces, Jim Gatheral and Antoine Jacquier, March 2013 - https://arxiv.org/pdf/1204.0646 The relevant formula from section 5.3 is:
C_t / K_t = α_t * (C_1 / K_1) + (1 - α_t) * (C_2 / K_2)
- where:
C_t: Value of C at time t
K_t: Value of K at time t
α_t: Weighting factor at time t
C_1, C_2: Constants
K_1, K_2: Constants
A key part of the interpolation is to also fit the skew dVol/dK. This requires dC/dK which can also be obtained as a weighted average of dC_1/dK and dC_2/dK.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
discounted (bool)
- Return type:
Tuple[List[float], List[float]]
- get_discount_factor()¶
- Return type:
float
- get_forward()¶
- Return type:
float
- get_pvalue(strike)¶
- Parameters:
strike (float)
- Return type:
float
- get_pvalues(strikes)¶
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
- Return type:
List[float]
- get_vars(strikes)¶
This function returns the ivar and the derivative d_ivar/d_moneyness for each strike in the list.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
- Return type:
Tuple[List[float], List[float]]
- get_vol(strike)¶
- Parameters:
strike (float)
- Return type:
Tuple[float, float]
- get_vols(strikes)¶
This function returns the ivol and the derivative d_ivol/d_strike for each strike in the list.
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
- Return type:
Tuple[List[float], List[float]]
- get_zscore(strike)¶
- Parameters:
strike (float)
- Return type:
float
- get_zscores(strikes)¶
- Parameters:
strikes (List[float] | Tuple[float, ...] | PVector[float])
- Return type:
List[float]
- has_vol_arbitrages()¶
As the strikes are sorted in ascending order the z-scores should also be sorted. Unless there is a vol arbitrage where a spike in vol causes a z-score value to be out of order.
- Return type:
bool
- min_ivol()¶
- Return type:
float
- min_ivol_moneyness()¶
- Return type:
float
- min_ivol_strike()¶
- Return type:
float
- moneyness_bounds()¶
- Return type:
Tuple[float, float]
- p_interp(solver='Brent')¶
Returns a function “p_value -> (strike, ivol)”
Note that the interpolation is linear in the log(strike) space.
- Parameters:
solver (str)
- Return type:
Callable[[float], Tuple[float, float]]
- strike_bounds()¶
- Return type:
Tuple[float, float]
- total_variance()¶
- Return type:
float
- property as_of_date: date¶
- property exercise_style: str¶
- property expiration_date: date¶
- property forward: float¶
- property last_updated¶
- property svi: SVIParameters¶
- property ticker: str¶
- class SVIParameters(a, b, rho, m, sigma)¶
Bases:
objectSo called “Raw” SVI parameters. The SVI model admits several parameterization.
Reference paper: - Arbitrage-free SVI volatility surfaces, Jim Gatheral and Antoine Jacquier, March 2013 - https://arxiv.org/pdf/1204.0646
- Parameters:
a (float)
b (float)
rho (float)
m (float)
sigma (float)
- atm_variance()¶
When strike=forward (the ATM Foward) we have mn=0
- Return type:
float
- convert_to_jump_svi(t)¶
Convert Raw SVI parameters to “Jump Wings” SVI parameters.
Equations can be found in this reference paper: - Arbitrage-free SVI volatility surfaces, Jim Gatheral and Antoine Jacquier, March 2013 - https://arxiv.org/pdf/1204.0646
- Parameters:
t (float)
- Return type:
JumpSVIParameters
- convert_to_natural_svi()¶
Convert Raw SVI parameters to Natural SVI parameters.
Equations can be found in this reference paper: - Arbitrage-free SVI volatility surfaces, Jim Gatheral and Antoine Jacquier, March 2013 - https://arxiv.org/pdf/1204.0646
- Return type:
NaturalSVIParameters
- is_valid()¶
- Return type:
bool
- is_valid_domain()¶
- Return type:
bool
- is_variance_positive()¶
- Return type:
bool
- min_variance()¶
- See reference slides here:
https://mfe.baruch.cuny.edu/wp-content/uploads/2013/01/OsakaSVI2012.pdf
- Return type:
float
- min_variance_moneyness()¶
The value for moneyness that minimize : mn -> svi_func(mn)
With change of variable y = (mn-m)/sigma it is easy to show that the minimum is reached for:
y = -rho / sqrt(1 - rho^2)
- Return type:
float
- svi_d2func()¶
- Return type:
Callable[[float | ndarray], float | ndarray]
- svi_dfunc()¶
- Return type:
Callable[[float | ndarray], float | ndarray]
- svi_func()¶
- Return type:
Callable[[float | ndarray], float | ndarray]
- vertex_variance()¶
In the SVI model the parameter “m” is called the vertex. When “k = m” some terms cancel out and we are left with:
variance = self.a + self.b * self.sigma
- Return type:
float
- a: float¶
- b: float¶
- m: float¶
- rho: float¶
- sigma: float¶