StochVolModels
StochVolModels copied to clipboard
Implement pricing analytics and Monte Carlo simulations for stochastic volatility models including log-normal SV model, Heston
StochVolModels
Implementation of pricing analytics and Monte Carlo simulations for modeling of options and implied volatilities.
The StochVolPackage provides:
- Analytics for Black-Scholes and Normal vols
- Interfaces and implementation for stochastic volatility models including log-normal SV model and Heston SV model
- Visualization of model implied volatilities
For the analytic implementation of stochastic volatility models, the package provides interfaces for a generic volatility model with the following features.
- Interface for analytical pricing of vanilla options using Fourier transform with closed-form solution for moment generating function
- Interface for Monte-Carlo simulations of model dynamics
Installation
pip install stochvolmodels
Table of contents
-
Model Interface
- Log-normal stochastic volatility model
- Heston stochastic volatility model
-
Running log-normal SV pricer
- Computing model prices and vols
- Running model calibration to sample Bitcoin options data
- Comparison of model prices vs MC
- Analysis and figures for the paper
- Running Heston SV pricer
- Supporting Illustrations for Public Papers
Running model calibration to sample Bitcoin options data
Implemented Stochastic Volatility models
The package provides interfaces for a generic volatility model with the following features.
- Interface for analytical pricing of vanilla options using Fourier transform with closed-form solution for moment generating function
- Interface for Monte-Carlo simulations of model dynamics
- Interface for visualization of model implied volatilities
The model interface is in stochvolmodels/pricers/model_pricer.py
Log-normal stochastic volatility model
The analytics for the log-normal stochastic volatility model is based on the paper
Log-normal Stochastic Volatility Model with Quadratic Drift by Artur Sepp and Parviz Rakhmonov
The dynamics of the log-normal stochastic volatility model:
$$dS_{t}=r(t)S_{t}dt+\sigma_{t}S_{t}dW^{(0)}_{t}$$
$$d\sigma_{t}=\left(\kappa_{1} + \kappa_{2}\sigma_{t} \right)(\theta - \sigma_{t})dt+ \beta \sigma_{t}dW^{(0)}{t} + \varepsilon \sigma{t} dW^{(1)}_{t}$$
$$dI_{t}=\sigma^{2}_{t}dt$$
where $r(t)$ is the deterministic risk-free rate; $W^{(0)}_{t}$ and $W^{(1)}_t$ are uncorrelated Brownian motions, $\beta\in\mathbb{R}$ is the volatility beta which measures the sensitivity of the volatility to changes in the spot price, and $\varepsilon>0$ is the volatility of residual volatility. We denote by $\vartheta^{2}$, $\vartheta^{2}=\beta^{2}+\varepsilon^{2}$, the total instantaneous variance of the volatility process.
Implementation of Lognormal SV model is contained in
stochvolmodels/pricers/logsv_pricer.py
Heston stochastic volatility model
The dynamics of Heston stochastic volatility model:
$$dS_{t}=r(t)S_{t}dt+\sqrt{V_{t}}S_{t}dW^{(S)}_{t}$$
$$dV_{t}=\kappa (\theta - V_{t})dt+ \vartheta \sqrt{V_{t}}dW^{(V)}_{t}$$
where $W^{(S)}$ and $W^{(V)}$ are correlated Brownian motions with correlation parameter $\rho$
Implementation of Heston SV model is contained in
stochvolmodels/pricers/heston_pricer.py
Running log-normal SV pricer
Basic features are implemented in
examples/run_lognormal_sv_pricer.py
Imports:
import stochvolmodels as sv
from stochvolmodels import LogSVPricer, LogSvParams, OptionChain
Computing model prices and vols
# instance of pricer
logsv_pricer = LogSVPricer()
# define model params
params = LogSvParams(sigma0=1.0, theta=1.0, kappa1=5.0, kappa2=5.0, beta=0.2, volvol=2.0)
# 1. compute ne price
model_price, vol = logsv_pricer.price_vanilla(params=params,
ttm=0.25,
forward=1.0,
strike=1.0,
optiontype='C')
print(f"price={model_price:0.4f}, implied vol={vol: 0.2%}")
# 2. prices for slices
model_prices, vols = logsv_pricer.price_slice(params=params,
ttm=0.25,
forward=1.0,
strikes=np.array([0.9, 1.0, 1.1]),
optiontypes=np.array(['P', 'C', 'C']))
print([f"{p:0.4f}, implied vol={v: 0.2%}" for p, v in zip(model_prices, vols)])
# 3. prices for option chain with uniform strikes
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.083, 0.25]),
ids=np.array(['1m', '3m']),
strikes=np.linspace(0.9, 1.1, 3))
model_prices, vols = logsv_pricer.compute_chain_prices_with_vols(option_chain=option_chain, params=params)
print(model_prices)
print(vols)
Running model calibration to sample Bitcoin options data
btc_option_chain = chains.get_btc_test_chain_data()
params0 = LogSvParams(sigma0=0.8, theta=1.0, kappa1=5.0, kappa2=None, beta=0.15, volvol=2.0)
btc_calibrated_params = logsv_pricer.calibrate_model_params_to_chain(option_chain=btc_option_chain,
params0=params0,
constraints_type=ConstraintsType.INVERSE_MARTINGALE)
print(btc_calibrated_params)
logsv_pricer.plot_model_ivols_vs_bid_ask(option_chain=btc_option_chain,
params=btc_calibrated_params)
Comparison of model prices vs MC
btc_option_chain = chains.get_btc_test_chain_data()
uniform_chain_data = OptionChain.to_uniform_strikes(obj=btc_option_chain, num_strikes=31)
btc_calibrated_params = LogSvParams(sigma0=0.8327, theta=1.0139, kappa1=4.8609, kappa2=4.7940, beta=0.1988, volvol=2.3694)
logsv_pricer.plot_comp_mma_inverse_options_with_mc(option_chain=uniform_chain_data,
params=btc_calibrated_params,
nb_path=400000)
Analysis and figures for the paper
All figures shown in the paper can be reproduced using py scripts in
examples/plots_for_paper
Running Heston SV pricer
Examples are implemented here
examples/run_heston_sv_pricer.py
examples/run_heston.py
Content of run_heston.py
import numpy as np
import matplotlib.pyplot as plt
from stochvolmodels import HestonPricer, HestonParams, OptionChain
# define parameters for bootstrap
params_dict = {'rho=0.0': HestonParams(v0=0.2**2, theta=0.2**2, kappa=4.0, volvol=0.75, rho=0.0),
'rho=-0.4': HestonParams(v0=0.2**2, theta=0.2**2, kappa=4.0, volvol=0.75, rho=-0.4),
'rho=-0.8': HestonParams(v0=0.2**2, theta=0.2**2, kappa=4.0, volvol=0.75, rho=-0.8)}
# get uniform slice
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.25]), ids=np.array(['3m']), strikes=np.linspace(0.8, 1.15, 20))
option_slice = option_chain.get_slice(id='3m')
# run pricer
pricer = HestonPricer()
pricer.plot_model_slices_in_params(option_slice=option_slice, params_dict=params_dict)
plt.show()
Supporting Illustrations for Public Papers
As illustrations of different analytics, this packadge includes module my_papers
with codes for computations and visualisations featured in several papers
for
- "Log-normal Stochastic Volatility Model with Quadratic Drift" by Sepp A and Rakhmonov P, SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2522425
stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
- "What is a robust stochastic volatility model" by Sepp A and Rakhmonov P, https://www.worldscientific.com/doi/10.1142/S0219024924500031
stochvolmodels/my_papers/volatility_models
- "Valuation and Hedging of Cryptocurrency Inverse Options" by Sepp A and Lucic V, SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4606748
stochvolmodels/my_papers/inverse_options