stochvolmodels 1.0.17__tar.gz → 1.0.19__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/PKG-INFO +34 -10
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/README.md +33 -9
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/pyproject.toml +4 -2
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/__init__.py +1 -7
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/data/option_chain.py +1 -1
- stochvolmodels-1.0.19/stochvolmodels/examples/run_gmm_fit.py +41 -0
- stochvolmodels-1.0.19/stochvolmodels/examples/run_heston.py +18 -0
- stochvolmodels-1.0.19/stochvolmodels/examples/run_heston_sv_pricer.py +72 -0
- stochvolmodels-1.0.19/stochvolmodels/examples/run_lognormal_sv_pricer.py +122 -0
- stochvolmodels-1.0.19/stochvolmodels/examples/run_pricing_options_on_qvar.py +51 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/il_hedging/README.md +8 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/il_hedging/logsv_figures.py +61 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/il_hedging/run_logsv_for_il_payoff.py +150 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/inverse_options/README.md +10 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/inverse_options/compare_net_delta.py +168 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/README.md +13 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/article_figures.py +325 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/calibrations.py +190 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/compare_admis_reg.py +128 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/model_fit_to_options_timeseries.py +252 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/moments_vol_qvar.py +239 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/ode_sol_in_time.py +308 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/steady_state_pdf.py +251 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift/vol_drift.py +82 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/risk_premia/check_kernel.py +20 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/risk_premia/gmm_slides.py +501 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/risk_premia/q_kernel.py +53 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/t_distribution/__init__.py +0 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/t_distribution/illustrations.py +197 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/t_distribution/market_data_fit.py +66 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/t_distribution/mc_pricer_with_kernel.py +97 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/volatility_models/README.md +10 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/volatility_models/__init__.py +0 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/volatility_models/article_figures.py +216 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/volatility_models/autocorr_fit.py +235 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/volatility_models/load_data.py +64 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/volatility_models/ss_distribution_fit.py +327 -0
- stochvolmodels-1.0.19/stochvolmodels/my_papers/volatility_models/vol_beta.py +60 -0
- stochvolmodels-1.0.19/stochvolmodels/pricers/__init__.py +0 -0
- stochvolmodels-1.0.19/stochvolmodels/pricers/analytic/__init__.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/analytic/tdist.py +2 -1
- stochvolmodels-1.0.19/stochvolmodels/pricers/logsv/__init__.py +0 -0
- stochvolmodels-1.0.19/stochvolmodels/tests/__init__.py +0 -0
- stochvolmodels-1.0.19/stochvolmodels/utils/__init__.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/utils/plots.py +5 -5
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/LICENSE.txt +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/data/__init__.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/data/fetch_option_chain.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/data/test_option_chain.py +0 -0
- {stochvolmodels-1.0.17/stochvolmodels/pricers → stochvolmodels-1.0.19/stochvolmodels/my_papers}/__init__.py +0 -0
- {stochvolmodels-1.0.17/stochvolmodels/pricers/analytic → stochvolmodels-1.0.19/stochvolmodels/my_papers/il_hedging}/__init__.py +0 -0
- {stochvolmodels-1.0.17/stochvolmodels/pricers/logsv → stochvolmodels-1.0.19/stochvolmodels/my_papers/inverse_options}/__init__.py +0 -0
- {stochvolmodels-1.0.17/stochvolmodels/tests → stochvolmodels-1.0.19/stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift}/__init__.py +0 -0
- {stochvolmodels-1.0.17/stochvolmodels/utils → stochvolmodels-1.0.19/stochvolmodels/my_papers/risk_premia}/__init__.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/analytic/bachelier.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/analytic/bsm.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/gmm_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/hawkes_jd_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/heston_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/logsv/affine_expansion.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/logsv/vol_moments_ode.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/logsv_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/model_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/pricers/tdist_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/tests/bsm_mgf_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/tests/qv_pricer.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/utils/config.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/utils/funcs.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/utils/mc_payoffs.py +0 -0
- {stochvolmodels-1.0.17 → stochvolmodels-1.0.19}/stochvolmodels/utils/mgf_pricer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stochvolmodels
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.19
|
|
4
4
|
Summary: Implementation of stochastic volatility models for option pricing
|
|
5
5
|
Home-page: https://github.com/ArturSepp/StochVolModels
|
|
6
6
|
License: LICENSE.txt
|
|
@@ -41,20 +41,37 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
|
|
42
42
|
Implementation of pricing analytics and Monte Carlo simulations for modeling of options and implied volatilities.
|
|
43
43
|
|
|
44
|
-
The
|
|
44
|
+
The StochVol package provides:
|
|
45
45
|
1) Analytics for Black-Scholes and Normal vols
|
|
46
|
-
2) Interfaces and implementation for stochastic volatility models
|
|
46
|
+
2) Interfaces and implementation for stochastic volatility models,
|
|
47
|
+
including log-normal SV model and Heston SV model
|
|
48
|
+
using analytical method with Fourier transform and Monte Carlo simulations
|
|
47
49
|
3) Visualization of model implied volatilities
|
|
48
50
|
|
|
49
51
|
For the analytic implementation of stochastic volatility models, the package provides interfaces for a generic volatility model with the following features.
|
|
50
|
-
1) Interface for analytical pricing of vanilla options
|
|
52
|
+
1) Interface for analytical pricing of vanilla options
|
|
53
|
+
using Fourier transform with closed-form solution for moment generating function
|
|
51
54
|
2) Interface for Monte-Carlo simulations of model dynamics
|
|
52
55
|
|
|
53
56
|
|
|
57
|
+
[Illustrations](#papers) of using package analytics for research
|
|
58
|
+
work is provided in top-level package ```my_papers```
|
|
59
|
+
which contains computations and visualisations for several papers
|
|
60
|
+
|
|
61
|
+
|
|
54
62
|
## Installation
|
|
63
|
+
Install using
|
|
55
64
|
```python
|
|
56
65
|
pip install stochvolmodels
|
|
57
66
|
```
|
|
67
|
+
Upgrade using
|
|
68
|
+
```python
|
|
69
|
+
pip install --upgrade stochvolmodels
|
|
70
|
+
```
|
|
71
|
+
Close using
|
|
72
|
+
```python
|
|
73
|
+
git clone https://github.com/ArturSepp/StochVolModels.git
|
|
74
|
+
```
|
|
58
75
|
|
|
59
76
|
# Table of contents
|
|
60
77
|
1. [Model Interface](#introduction)
|
|
@@ -83,7 +100,7 @@ The model interface is in stochvolmodels/pricers/model_pricer.py
|
|
|
83
100
|
|
|
84
101
|
The analytics for the log-normal stochastic volatility model is based on the paper
|
|
85
102
|
|
|
86
|
-
[Log-normal Stochastic Volatility Model with Quadratic Drift](https://
|
|
103
|
+
[Log-normal Stochastic Volatility Model with Quadratic Drift](https://www.worldscientific.com/doi/10.1142/S0219024924500031) by Artur Sepp and Parviz Rakhmonov
|
|
87
104
|
|
|
88
105
|
|
|
89
106
|
The dynamics of the log-normal stochastic volatility model:
|
|
@@ -240,24 +257,31 @@ As illustrations of different analytics, this packadge includes module ```my_pap
|
|
|
240
257
|
with codes for computations and visualisations featured in several papers
|
|
241
258
|
for
|
|
242
259
|
|
|
243
|
-
1) "Log-normal Stochastic Volatility Model with Quadratic Drift" by Sepp
|
|
260
|
+
1) "Log-normal Stochastic Volatility Model with Quadratic Drift" by Artur Sepp
|
|
261
|
+
and Parviz Rakhmonov: https://www.worldscientific.com/doi/10.1142/S0219024924500031
|
|
244
262
|
```python
|
|
245
263
|
stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
|
|
246
264
|
```
|
|
247
265
|
|
|
248
266
|
|
|
249
|
-
2) "What is a robust stochastic volatility model" by Sepp
|
|
250
|
-
|
|
267
|
+
2) "What is a robust stochastic volatility model" by Artur Sepp and Parviz Rakhmonov, SSRN:
|
|
268
|
+
https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
|
|
251
269
|
```python
|
|
252
270
|
stochvolmodels/my_papers/volatility_models
|
|
253
271
|
```
|
|
254
272
|
|
|
255
273
|
|
|
256
|
-
3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Sepp
|
|
274
|
+
3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Artur Sepp
|
|
275
|
+
and Vladimir Lucic,
|
|
257
276
|
SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4606748
|
|
258
277
|
```python
|
|
259
278
|
stochvolmodels/my_papers/inverse_options
|
|
260
279
|
```
|
|
261
280
|
|
|
262
|
-
|
|
281
|
+
4) "Unified Approach for Hedging Impermanent Loss of Liquidity Provision" by
|
|
282
|
+
Artur Sepp, Alexander Lipton and Vladimir Lucic,
|
|
283
|
+
SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4887298
|
|
284
|
+
```python
|
|
285
|
+
stochvolmodels/my_papers/il_hedging
|
|
286
|
+
```
|
|
263
287
|
|
|
@@ -2,20 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
Implementation of pricing analytics and Monte Carlo simulations for modeling of options and implied volatilities.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The StochVol package provides:
|
|
6
6
|
1) Analytics for Black-Scholes and Normal vols
|
|
7
|
-
2) Interfaces and implementation for stochastic volatility models
|
|
7
|
+
2) Interfaces and implementation for stochastic volatility models,
|
|
8
|
+
including log-normal SV model and Heston SV model
|
|
9
|
+
using analytical method with Fourier transform and Monte Carlo simulations
|
|
8
10
|
3) Visualization of model implied volatilities
|
|
9
11
|
|
|
10
12
|
For the analytic implementation of stochastic volatility models, the package provides interfaces for a generic volatility model with the following features.
|
|
11
|
-
1) Interface for analytical pricing of vanilla options
|
|
13
|
+
1) Interface for analytical pricing of vanilla options
|
|
14
|
+
using Fourier transform with closed-form solution for moment generating function
|
|
12
15
|
2) Interface for Monte-Carlo simulations of model dynamics
|
|
13
16
|
|
|
14
17
|
|
|
18
|
+
[Illustrations](#papers) of using package analytics for research
|
|
19
|
+
work is provided in top-level package ```my_papers```
|
|
20
|
+
which contains computations and visualisations for several papers
|
|
21
|
+
|
|
22
|
+
|
|
15
23
|
## Installation
|
|
24
|
+
Install using
|
|
16
25
|
```python
|
|
17
26
|
pip install stochvolmodels
|
|
18
27
|
```
|
|
28
|
+
Upgrade using
|
|
29
|
+
```python
|
|
30
|
+
pip install --upgrade stochvolmodels
|
|
31
|
+
```
|
|
32
|
+
Close using
|
|
33
|
+
```python
|
|
34
|
+
git clone https://github.com/ArturSepp/StochVolModels.git
|
|
35
|
+
```
|
|
19
36
|
|
|
20
37
|
# Table of contents
|
|
21
38
|
1. [Model Interface](#introduction)
|
|
@@ -44,7 +61,7 @@ The model interface is in stochvolmodels/pricers/model_pricer.py
|
|
|
44
61
|
|
|
45
62
|
The analytics for the log-normal stochastic volatility model is based on the paper
|
|
46
63
|
|
|
47
|
-
[Log-normal Stochastic Volatility Model with Quadratic Drift](https://
|
|
64
|
+
[Log-normal Stochastic Volatility Model with Quadratic Drift](https://www.worldscientific.com/doi/10.1142/S0219024924500031) by Artur Sepp and Parviz Rakhmonov
|
|
48
65
|
|
|
49
66
|
|
|
50
67
|
The dynamics of the log-normal stochastic volatility model:
|
|
@@ -201,23 +218,30 @@ As illustrations of different analytics, this packadge includes module ```my_pap
|
|
|
201
218
|
with codes for computations and visualisations featured in several papers
|
|
202
219
|
for
|
|
203
220
|
|
|
204
|
-
1) "Log-normal Stochastic Volatility Model with Quadratic Drift" by Sepp
|
|
221
|
+
1) "Log-normal Stochastic Volatility Model with Quadratic Drift" by Artur Sepp
|
|
222
|
+
and Parviz Rakhmonov: https://www.worldscientific.com/doi/10.1142/S0219024924500031
|
|
205
223
|
```python
|
|
206
224
|
stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
|
|
207
225
|
```
|
|
208
226
|
|
|
209
227
|
|
|
210
|
-
2) "What is a robust stochastic volatility model" by Sepp
|
|
211
|
-
|
|
228
|
+
2) "What is a robust stochastic volatility model" by Artur Sepp and Parviz Rakhmonov, SSRN:
|
|
229
|
+
https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
|
|
212
230
|
```python
|
|
213
231
|
stochvolmodels/my_papers/volatility_models
|
|
214
232
|
```
|
|
215
233
|
|
|
216
234
|
|
|
217
|
-
3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Sepp
|
|
235
|
+
3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Artur Sepp
|
|
236
|
+
and Vladimir Lucic,
|
|
218
237
|
SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4606748
|
|
219
238
|
```python
|
|
220
239
|
stochvolmodels/my_papers/inverse_options
|
|
221
240
|
```
|
|
222
241
|
|
|
223
|
-
|
|
242
|
+
4) "Unified Approach for Hedging Impermanent Loss of Liquidity Provision" by
|
|
243
|
+
Artur Sepp, Alexander Lipton and Vladimir Lucic,
|
|
244
|
+
SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4887298
|
|
245
|
+
```python
|
|
246
|
+
stochvolmodels/my_papers/il_hedging
|
|
247
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "stochvolmodels"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.19"
|
|
4
4
|
description = "Implementation of stochastic volatility models for option pricing"
|
|
5
5
|
license = "LICENSE.txt"
|
|
6
6
|
authors = ["Artur Sepp <artursepp@gmail.com>"]
|
|
@@ -23,7 +23,9 @@ classifiers=[
|
|
|
23
23
|
"Programming Language :: Python :: 3 :: Only",
|
|
24
24
|
"Topic :: Office/Business :: Financial :: Investment",
|
|
25
25
|
]
|
|
26
|
-
packages = [ {include = "stochvolmodels"}
|
|
26
|
+
packages = [ {include = "stochvolmodels"}]
|
|
27
|
+
|
|
28
|
+
exclude = ["stochvolmodel/my_papers/"]
|
|
27
29
|
|
|
28
30
|
[tool.poetry.urls]
|
|
29
31
|
"Issues" = "https://github.com/ArturSepp/StochVolModels/issues"
|
|
@@ -123,12 +123,6 @@ from stochvolmodels.pricers.tdist_pricer import (
|
|
|
123
123
|
|
|
124
124
|
from stochvolmodels.data.option_chain import OptionChain, OptionSlice
|
|
125
125
|
|
|
126
|
-
"""
|
|
127
|
-
from stochvolmodels.data.fetch_option_chain import (generate_vol_chain_np,
|
|
128
|
-
load_option_chain,
|
|
129
|
-
sample_option_chain_at_times,
|
|
130
|
-
load_price_data)
|
|
131
|
-
"""
|
|
132
126
|
|
|
133
127
|
from stochvolmodels.data.test_option_chain import (
|
|
134
128
|
get_btc_test_chain_data,
|
|
@@ -146,7 +140,7 @@ from stochvolmodels.utils.plots import (
|
|
|
146
140
|
create_dummy_line,
|
|
147
141
|
fig_list_to_pdf,
|
|
148
142
|
fig_to_pdf,
|
|
149
|
-
|
|
143
|
+
set_legend_colors,
|
|
150
144
|
get_n_sns_colors,
|
|
151
145
|
map_deltas_to_str,
|
|
152
146
|
model_param_ts,
|
|
@@ -246,7 +246,7 @@ class OptionChain:
|
|
|
246
246
|
bid_prices=None if option_chain.bid_prices is None else List([option_chain.bid_prices[idx]]),
|
|
247
247
|
ask_prices=None if option_chain.ask_prices is None else List([option_chain.ask_prices[idx]]))
|
|
248
248
|
else:
|
|
249
|
-
indices = np.
|
|
249
|
+
indices = np.isin(option_chain.ids, ids).nonzero()[0]
|
|
250
250
|
option_chain = cls(ids=ids,
|
|
251
251
|
ttms=option_chain.ttms[indices],
|
|
252
252
|
ticker=option_chain.ticker,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
example of fitting GMM
|
|
3
|
+
see StochVolModels/examples/run_gmm_fit.py
|
|
4
|
+
"""
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import seaborn as sns
|
|
7
|
+
import qis as qis
|
|
8
|
+
from stochvolmodels import (get_btc_test_chain_data,
|
|
9
|
+
get_spy_test_chain_data,
|
|
10
|
+
OptionChain, GmmPricer,
|
|
11
|
+
plot_gmm_pdfs)
|
|
12
|
+
|
|
13
|
+
# get test option chain data
|
|
14
|
+
# option_chain = get_btc_test_chain_data()
|
|
15
|
+
option_chain = get_spy_test_chain_data()
|
|
16
|
+
|
|
17
|
+
# run GMM fit
|
|
18
|
+
gmm_pricer = GmmPricer()
|
|
19
|
+
fit_params = gmm_pricer.calibrate_model_params_to_chain(option_chain=option_chain, n_mixtures=4)
|
|
20
|
+
|
|
21
|
+
# illustrate fitted parameters and model fit to market bid-ask
|
|
22
|
+
# plot two ids
|
|
23
|
+
ids = ['2m', '6m']
|
|
24
|
+
n = len(ids)
|
|
25
|
+
with sns.axes_style('darkgrid'):
|
|
26
|
+
fig, axs = plt.subplots(n, 2, figsize=(14, 12), tight_layout=True)
|
|
27
|
+
# axs = qis.to_flat_list(axs)
|
|
28
|
+
current_ax = 0
|
|
29
|
+
|
|
30
|
+
for key, params in fit_params.items():
|
|
31
|
+
print(f"{key}: {params}")
|
|
32
|
+
if key in ids:
|
|
33
|
+
option_chain0 = OptionChain.get_slices_as_chain(option_chain, ids=[key])
|
|
34
|
+
# gmm_pricer.plot_model_ivols_vs_bid_ask(option_chain=option_chain0, params=params, axs=[axs[idx]])
|
|
35
|
+
plot_gmm_pdfs(params=params, option_chain0=option_chain0, axs=axs[current_ax, :])
|
|
36
|
+
qis.set_title(ax=axs[current_ax, 0], title=f"{key}-slice: (A) State PDF and Aggregate Risk-Neutral PDF")
|
|
37
|
+
qis.set_title(ax=axs[current_ax, 1], title=f"{key}-slice: Model to Market Bid/Ask vols")
|
|
38
|
+
current_ax += 1
|
|
39
|
+
|
|
40
|
+
qis.set_suptitle(fig, title='Fit of 4-state GMM to SPY implied vols @ 15_Jul_2022_10_23_09')
|
|
41
|
+
plt.show()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
from stochvolmodels import HestonPricer, HestonParams, OptionChain
|
|
4
|
+
|
|
5
|
+
# define parameters for bootstrap
|
|
6
|
+
params_dict = {'rho=0.0': HestonParams(v0=0.2**2, theta=0.2**2, kappa=4.0, volvol=0.75, rho=0.0),
|
|
7
|
+
'rho=-0.4': HestonParams(v0=0.2**2, theta=0.2**2, kappa=4.0, volvol=0.75, rho=-0.4),
|
|
8
|
+
'rho=-0.8': HestonParams(v0=0.2**2, theta=0.2**2, kappa=4.0, volvol=0.75, rho=-0.8)}
|
|
9
|
+
|
|
10
|
+
# get uniform slice
|
|
11
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.25]), ids=np.array(['3m']), strikes=np.linspace(0.8, 1.15, 20))
|
|
12
|
+
option_slice = option_chain.get_slice(id='3m')
|
|
13
|
+
|
|
14
|
+
# run pricer
|
|
15
|
+
pricer = HestonPricer()
|
|
16
|
+
pricer.plot_model_slices_in_params(option_slice=option_slice, params_dict=params_dict)
|
|
17
|
+
|
|
18
|
+
plt.show()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
import stochvolmodels as sv
|
|
7
|
+
from stochvolmodels import HestonPricer, HestonParams, OptionChain, BTC_HESTON_PARAMS
|
|
8
|
+
|
|
9
|
+
pricer = HestonPricer()
|
|
10
|
+
|
|
11
|
+
# define model params
|
|
12
|
+
params = HestonParams(v0=1.0, theta=1.0, kappa=5.0, volvol=1.0, rho=-0.5)
|
|
13
|
+
|
|
14
|
+
# 1. one price
|
|
15
|
+
model_price, vol = pricer.price_vanilla(params=params,
|
|
16
|
+
ttm=0.25,
|
|
17
|
+
forward=1.0,
|
|
18
|
+
strike=1.0,
|
|
19
|
+
optiontype='C')
|
|
20
|
+
print(f"price={model_price:0.4f}, implied vol={vol: 0.2%}")
|
|
21
|
+
|
|
22
|
+
# 2. price slice
|
|
23
|
+
model_prices, vols = pricer.price_slice(params=params,
|
|
24
|
+
ttm=0.25,
|
|
25
|
+
forward=1.0,
|
|
26
|
+
strikes=np.array([0.9, 1.0, 1.1]),
|
|
27
|
+
optiontypes=np.array(['P', 'C', 'C']))
|
|
28
|
+
print([f"{p:0.4f}, implied vol={v: 0.2%}" for p, v in zip(model_prices, vols)])
|
|
29
|
+
|
|
30
|
+
# 3. prices for option chain with uniform strikes
|
|
31
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.083, 0.25]),
|
|
32
|
+
ids=np.array(['1m', '3m']),
|
|
33
|
+
strikes=np.linspace(0.9, 1.1, 3))
|
|
34
|
+
model_prices, vols = pricer.compute_chain_prices_with_vols(option_chain=option_chain, params=params)
|
|
35
|
+
print(model_prices)
|
|
36
|
+
print(vols)
|
|
37
|
+
|
|
38
|
+
# define uniform option chain
|
|
39
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.083, 0.25]),
|
|
40
|
+
ids=np.array(['1m', '3m']),
|
|
41
|
+
strikes=np.linspace(0.5, 1.5, 21))
|
|
42
|
+
pricer.plot_model_ivols(option_chain=option_chain,
|
|
43
|
+
params=params)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# define uniform option chain
|
|
47
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.083, 0.25]),
|
|
48
|
+
ids=np.array(['1m', '3m']),
|
|
49
|
+
strikes=np.linspace(0.5, 1.5, 21))
|
|
50
|
+
|
|
51
|
+
# define parameters for bootstrap
|
|
52
|
+
params_dict = {'kappa=5': HestonParams(v0=1.0, theta=1.0, kappa=5.0, volvol=1.0, rho=-0.5),
|
|
53
|
+
'kappa=10': HestonParams(v0=1.0, theta=1.0, kappa=10.0, volvol=1.0, rho=-0.5)}
|
|
54
|
+
option_slice = option_chain.get_slice(id='1m')
|
|
55
|
+
pricer.plot_model_slices_in_params(option_slice=option_slice,
|
|
56
|
+
params_dict=params_dict)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
btc_option_chain = sv.get_btc_test_chain_data()
|
|
60
|
+
btc_calibrated_params = BTC_HESTON_PARAMS
|
|
61
|
+
pricer.plot_model_ivols_vs_bid_ask(option_chain=btc_option_chain,
|
|
62
|
+
params=btc_calibrated_params)
|
|
63
|
+
|
|
64
|
+
btc_option_chain = sv.get_btc_test_chain_data()
|
|
65
|
+
params0 = HestonParams(v0=0.8, theta=1.0, kappa=5.0, volvol=1.0, rho=-0.5)
|
|
66
|
+
btc_calibrated_params = pricer.calibrate_model_params_to_chain(option_chain=btc_option_chain,
|
|
67
|
+
params0=params0,
|
|
68
|
+
constraints_type=sv.ConstraintsType.INVERSE_MARTINGALE)
|
|
69
|
+
print(btc_calibrated_params)
|
|
70
|
+
pricer.plot_model_ivols_vs_bid_ask(option_chain=btc_option_chain,
|
|
71
|
+
params=btc_calibrated_params)
|
|
72
|
+
plt.show()
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""
|
|
2
|
+
run few unit test to illustrate implementation of log-normal sv model analytics
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
from enum import Enum
|
|
8
|
+
|
|
9
|
+
import stochvolmodels as sv
|
|
10
|
+
from stochvolmodels import LogSVPricer, LogSvParams, OptionChain, LogsvModelCalibrationType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class UnitTests(Enum):
|
|
14
|
+
COMPUTE_MODEL_PRICES = 1
|
|
15
|
+
PLOT_MODEL_IMPLIED_VOLS = 2
|
|
16
|
+
PLOT_MODEL_VOLS_IN_PARAMS = 3
|
|
17
|
+
COMPARE_MODEL_VOLS_TO_MC = 4
|
|
18
|
+
PLOT_FIT_TO_BITCOIN_OPTION_CHAIN = 5
|
|
19
|
+
CALIBRATE_MODEL_TO_BTC_OPTIONS = 6
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run_unit_test(unit_test: UnitTests):
|
|
23
|
+
|
|
24
|
+
# instance of pricer
|
|
25
|
+
logsv_pricer = LogSVPricer()
|
|
26
|
+
|
|
27
|
+
# define model params
|
|
28
|
+
params = LogSvParams(sigma0=1.0, theta=1.0, kappa1=5.0, kappa2=5.0, beta=0.2, volvol=2.0)
|
|
29
|
+
|
|
30
|
+
if unit_test == UnitTests.COMPUTE_MODEL_PRICES:
|
|
31
|
+
# 1. one price
|
|
32
|
+
model_price, vol = logsv_pricer.price_vanilla(params=params,
|
|
33
|
+
ttm=0.25,
|
|
34
|
+
forward=1.0,
|
|
35
|
+
strike=1.0,
|
|
36
|
+
optiontype='C')
|
|
37
|
+
print(f"price={model_price:0.4f}, implied vol={vol: 0.2%}")
|
|
38
|
+
|
|
39
|
+
# 2. prices for slices
|
|
40
|
+
model_prices, vols = logsv_pricer.price_slice(params=params,
|
|
41
|
+
ttm=0.25,
|
|
42
|
+
forward=1.0,
|
|
43
|
+
strikes=np.array([0.9, 1.0, 1.1]),
|
|
44
|
+
optiontypes=np.array(['P', 'C', 'C']))
|
|
45
|
+
print([f"{p:0.4f}, implied vol={v: 0.2%}" for p, v in zip(model_prices, vols)])
|
|
46
|
+
|
|
47
|
+
# 3. prices for option chain with uniform strikes
|
|
48
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.083, 0.25]),
|
|
49
|
+
ids=np.array(['1m', '3m']),
|
|
50
|
+
strikes=np.linspace(0.9, 1.1, 3))
|
|
51
|
+
model_prices, vols = logsv_pricer.compute_chain_prices_with_vols(option_chain=option_chain, params=params)
|
|
52
|
+
print(model_prices)
|
|
53
|
+
print(vols)
|
|
54
|
+
|
|
55
|
+
elif unit_test == UnitTests.PLOT_MODEL_IMPLIED_VOLS:
|
|
56
|
+
# define uniform option chain
|
|
57
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.083, 0.25]),
|
|
58
|
+
ids=np.array(['1m', '3m']),
|
|
59
|
+
strikes=np.linspace(0.5, 1.5, 21))
|
|
60
|
+
logsv_pricer.plot_model_ivols(option_chain=option_chain,
|
|
61
|
+
params=params)
|
|
62
|
+
|
|
63
|
+
elif unit_test == UnitTests.PLOT_MODEL_VOLS_IN_PARAMS:
|
|
64
|
+
|
|
65
|
+
# define uniform option chain
|
|
66
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([0.083, 0.25]),
|
|
67
|
+
ids=np.array(['1m', '3m']),
|
|
68
|
+
strikes=np.linspace(0.5, 1.5, 21))
|
|
69
|
+
|
|
70
|
+
# define parameters for bootstrap
|
|
71
|
+
params_dict = {'kappa2=5': LogSvParams(sigma0=1.0, theta=1.0, kappa1=5.0, kappa2=5.0, beta=0.2, volvol=2.0),
|
|
72
|
+
'kappa2=10': LogSvParams(sigma0=1.0, theta=1.0, kappa1=5.0, kappa2=10.0, beta=0.2, volvol=2.0)}
|
|
73
|
+
|
|
74
|
+
# get slice for illustration
|
|
75
|
+
option_slice = option_chain.get_slice(id='1m')
|
|
76
|
+
logsv_pricer.plot_model_slices_in_params(option_slice=option_slice,
|
|
77
|
+
params_dict=params_dict)
|
|
78
|
+
|
|
79
|
+
elif unit_test == UnitTests.COMPARE_MODEL_VOLS_TO_MC:
|
|
80
|
+
btc_option_chain = sv.get_btc_test_chain_data()
|
|
81
|
+
uniform_chain_data = OptionChain.to_uniform_strikes(obj=btc_option_chain, num_strikes=31)
|
|
82
|
+
btc_calibrated_params = LogSvParams(sigma0=0.8327, theta=1.0139, kappa1=4.8609, kappa2=4.7940, beta=0.1988, volvol=2.3694)
|
|
83
|
+
|
|
84
|
+
logsv_pricer.plot_model_ivols_vs_mc(option_chain=uniform_chain_data,
|
|
85
|
+
params=btc_calibrated_params,
|
|
86
|
+
nb_path=100000)
|
|
87
|
+
|
|
88
|
+
logsv_pricer.plot_comp_mma_inverse_options_with_mc(option_chain=uniform_chain_data,
|
|
89
|
+
params=btc_calibrated_params,
|
|
90
|
+
nb_path=100000)
|
|
91
|
+
|
|
92
|
+
elif unit_test == UnitTests.PLOT_FIT_TO_BITCOIN_OPTION_CHAIN:
|
|
93
|
+
|
|
94
|
+
btc_option_chain = sv.get_btc_test_chain_data()
|
|
95
|
+
btc_calibrated_params = LogSvParams(sigma0=0.8327, theta=1.0139, kappa1=4.8609, kappa2=4.7940, beta=0.1988, volvol=2.3694)
|
|
96
|
+
logsv_pricer.plot_model_ivols_vs_bid_ask(option_chain=btc_option_chain,
|
|
97
|
+
params=btc_calibrated_params)
|
|
98
|
+
|
|
99
|
+
elif unit_test == UnitTests.CALIBRATE_MODEL_TO_BTC_OPTIONS:
|
|
100
|
+
btc_option_chain = sv.get_btc_test_chain_data()
|
|
101
|
+
params0 = LogSvParams(sigma0=0.8, theta=1.0, kappa1=2.21, kappa2=2.18, beta=0.15, volvol=2.0)
|
|
102
|
+
btc_calibrated_params = logsv_pricer.calibrate_model_params_to_chain(option_chain=btc_option_chain,
|
|
103
|
+
params0=params0,
|
|
104
|
+
model_calibration_type=LogsvModelCalibrationType.PARAMS4,
|
|
105
|
+
|
|
106
|
+
constraints_type=sv.ConstraintsType.INVERSE_MARTINGALE)
|
|
107
|
+
print(btc_calibrated_params)
|
|
108
|
+
logsv_pricer.plot_model_ivols_vs_bid_ask(option_chain=btc_option_chain,
|
|
109
|
+
params=btc_calibrated_params)
|
|
110
|
+
plt.show()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
if __name__ == '__main__':
|
|
114
|
+
|
|
115
|
+
unit_test = UnitTests.COMPARE_MODEL_VOLS_TO_MC
|
|
116
|
+
|
|
117
|
+
is_run_all_tests = False
|
|
118
|
+
if is_run_all_tests:
|
|
119
|
+
for unit_test in UnitTests:
|
|
120
|
+
run_unit_test(unit_test=unit_test)
|
|
121
|
+
else:
|
|
122
|
+
run_unit_test(unit_test=unit_test)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
run valuation for options on quadratic variance
|
|
3
|
+
"""
|
|
4
|
+
import numpy as np
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import qis as qis
|
|
7
|
+
import stochvolmodels.data.test_option_chain as chains
|
|
8
|
+
from numba.typed import List
|
|
9
|
+
from stochvolmodels import (LogSVPricer, LogSvParams, compute_analytic_qvar, OptionChain,
|
|
10
|
+
VariableType, HestonPricer, HestonParams)
|
|
11
|
+
|
|
12
|
+
# these params are calibrated to the same BTC option chain
|
|
13
|
+
# v0=theta=1 to have flat vol term structure
|
|
14
|
+
LOGSV_BTC_PARAMS = LogSvParams(sigma0=1.0, theta=1.0, kappa1=3.1844, kappa2=3.058, beta=0.1514, volvol=1.8458)
|
|
15
|
+
BTC_HESTON_PARAMS = HestonParams(v0=1.0, theta=1.0, kappa=7.4565, rho=0.0919, volvol=4.0907)
|
|
16
|
+
|
|
17
|
+
ttms = {'1w': 1.0 / 52.0, '1m': 1.0 / 12.0, '3m': 0.25, '6m': 0.5}
|
|
18
|
+
|
|
19
|
+
# get test strikes for qv
|
|
20
|
+
option_chain = chains.get_qv_options_test_chain_data()
|
|
21
|
+
option_chain = OptionChain.get_slices_as_chain(option_chain, ids=list(ttms.keys()))
|
|
22
|
+
|
|
23
|
+
# compute forwards using QV model
|
|
24
|
+
forwards = np.array([compute_analytic_qvar(params=LOGSV_BTC_PARAMS, ttm=ttm, n_terms=4) for ttm in ttms.values()])
|
|
25
|
+
print(f"QV forwards = {forwards}")
|
|
26
|
+
# replace forwards to imply BSM vols
|
|
27
|
+
option_chain.forwards = forwards
|
|
28
|
+
# adjust strikes
|
|
29
|
+
option_chain.strikes_ttms = List(forward * strikes_ttm for forward, strikes_ttm in
|
|
30
|
+
zip(option_chain.forwards, option_chain.strikes_ttms))
|
|
31
|
+
|
|
32
|
+
nb_path = 200000
|
|
33
|
+
|
|
34
|
+
# run log sv pricer
|
|
35
|
+
logsv_pricer = LogSVPricer()
|
|
36
|
+
fig1 = logsv_pricer.plot_model_ivols_vs_mc(option_chain=option_chain,
|
|
37
|
+
params=LOGSV_BTC_PARAMS,
|
|
38
|
+
variable_type=VariableType.Q_VAR,
|
|
39
|
+
nb_path=nb_path)
|
|
40
|
+
qis.set_suptitle(fig1, title='Implied variance skew by Log-Normal SV model')
|
|
41
|
+
|
|
42
|
+
# run Heston prices
|
|
43
|
+
heston_pricer = HestonPricer()
|
|
44
|
+
fig2 = heston_pricer.plot_model_ivols_vs_mc(option_chain=option_chain,
|
|
45
|
+
params=BTC_HESTON_PARAMS,
|
|
46
|
+
variable_type=VariableType.Q_VAR,
|
|
47
|
+
nb_path=nb_path)
|
|
48
|
+
qis.set_suptitle(fig2, title='Implied variance skew by Heston SV model')
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
plt.show()
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
This module contains analysis for paper
|
|
2
|
+
[Unified Approach for Hedging Impermanent Loss of Liquidity Provision](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4887298)
|
|
3
|
+
by Artur Sepp, Alexander Lipton, and Vladimir Lucic
|
|
4
|
+
|
|
5
|
+
All figures in the paper are produced by unittests in
|
|
6
|
+
https://github.com/ArturSepp/StochVolModels/blob/main/my_papers/il_hedging/run_logsv_for_il_payoff.py
|
|
7
|
+
|
|
8
|
+
See the description of data and analysis in the paper.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
run few unit test to illustrate implementation of log-normal sv model analytics
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
import seaborn as sns
|
|
8
|
+
from enum import Enum
|
|
9
|
+
|
|
10
|
+
from stochvolmodels import LogSVPricer, LogSvParams, OptionChain
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def plot_skews():
|
|
14
|
+
logsv_pricer = LogSVPricer()
|
|
15
|
+
option_chain = OptionChain.get_uniform_chain(ttms=np.array([14.0/365.0]),
|
|
16
|
+
ids=np.array(['2w']),
|
|
17
|
+
strikes=np.linspace(0.6, 1.4, 21))
|
|
18
|
+
|
|
19
|
+
# define parameters for bootstrap
|
|
20
|
+
sigma0 = 0.5
|
|
21
|
+
params_dict = {'beta=-1': LogSvParams(sigma0=sigma0, theta=sigma0, kappa1=5.0, kappa2=5.0, beta=-1, volvol=1.0),
|
|
22
|
+
'beta=0': LogSvParams(sigma0=sigma0, theta=sigma0, kappa1=5.0, kappa2=5.0, beta=0.0, volvol=1.4),
|
|
23
|
+
'beta=1': LogSvParams(sigma0=sigma0, theta=sigma0, kappa1=5.0, kappa2=5.0, beta=1.0, volvol=1.0)}
|
|
24
|
+
|
|
25
|
+
params_dict = {
|
|
26
|
+
'volvol=1.0': LogSvParams(sigma0=sigma0, theta=sigma0, kappa1=2.21, kappa2=2.18, beta=0.0, volvol=1.0),
|
|
27
|
+
'volvol=2.0': LogSvParams(sigma0=sigma0 - 0.005, theta=sigma0 - 0.005, kappa1=2.21, kappa2=2.18, beta=0.0,
|
|
28
|
+
volvol=2.0),
|
|
29
|
+
'volvol=3.0': LogSvParams(sigma0=sigma0 - 0.01, theta=sigma0 - 0.01, kappa1=2.21, kappa2=2.18, beta=0.0,
|
|
30
|
+
volvol=3.0)}
|
|
31
|
+
|
|
32
|
+
# get slice for illustration
|
|
33
|
+
option_slice = option_chain.get_slice(id='2w')
|
|
34
|
+
logsv_pricer.plot_model_slices_in_params(option_slice=option_slice,
|
|
35
|
+
params_dict=params_dict)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class UnitTests(Enum):
|
|
39
|
+
PLOT_SKEWS = 1
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def run_unit_test(unit_test: UnitTests):
|
|
43
|
+
|
|
44
|
+
if unit_test == UnitTests.PLOT_SKEWS:
|
|
45
|
+
with sns.axes_style("darkgrid"):
|
|
46
|
+
fig, axs = plt.subplots(3, 1, figsize=(10, 7))
|
|
47
|
+
plot_skews()
|
|
48
|
+
|
|
49
|
+
plt.show()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == '__main__':
|
|
53
|
+
|
|
54
|
+
unit_test = UnitTests.PLOT_SKEWS
|
|
55
|
+
|
|
56
|
+
is_run_all_tests = False
|
|
57
|
+
if is_run_all_tests:
|
|
58
|
+
for unit_test in UnitTests:
|
|
59
|
+
run_unit_test(unit_test=unit_test)
|
|
60
|
+
else:
|
|
61
|
+
run_unit_test(unit_test=unit_test)
|