stochvolmodels 1.0.17__tar.gz → 1.0.18__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.
Files changed (65) hide show
  1. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/PKG-INFO +34 -10
  2. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/README.md +33 -9
  3. stochvolmodels-1.0.18/examples/run_gmm_fit.py +41 -0
  4. stochvolmodels-1.0.18/examples/run_heston.py +18 -0
  5. stochvolmodels-1.0.18/examples/run_heston_sv_pricer.py +72 -0
  6. stochvolmodels-1.0.18/examples/run_lognormal_sv_pricer.py +122 -0
  7. stochvolmodels-1.0.18/examples/run_pricing_options_on_qvar.py +51 -0
  8. stochvolmodels-1.0.18/my_papers/il_hedging/README.md +10 -0
  9. stochvolmodels-1.0.18/my_papers/il_hedging/logsv_figures.py +61 -0
  10. stochvolmodels-1.0.18/my_papers/il_hedging/run_logsv_for_il_payoff.py +150 -0
  11. stochvolmodels-1.0.18/my_papers/inverse_options/README.md +10 -0
  12. stochvolmodels-1.0.18/my_papers/inverse_options/compare_net_delta.py +168 -0
  13. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/README.md +13 -0
  14. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/article_figures.py +321 -0
  15. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/calibrations.py +190 -0
  16. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/compare_admis_reg.py +128 -0
  17. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/model_fit_to_options_timeseries.py +249 -0
  18. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/moments_vol_qvar.py +239 -0
  19. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/ode_sol_in_time.py +308 -0
  20. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/steady_state_pdf.py +251 -0
  21. stochvolmodels-1.0.18/my_papers/logsv_model_wtih_quadratic_drift/vol_drift.py +82 -0
  22. stochvolmodels-1.0.18/my_papers/risk_premia/check_kernel.py +20 -0
  23. stochvolmodels-1.0.18/my_papers/risk_premia/gmm_slides.py +501 -0
  24. stochvolmodels-1.0.18/my_papers/risk_premia/q_kernel.py +53 -0
  25. stochvolmodels-1.0.18/my_papers/t_distribution/illustrations.py +197 -0
  26. stochvolmodels-1.0.18/my_papers/t_distribution/market_data_fit.py +66 -0
  27. stochvolmodels-1.0.18/my_papers/t_distribution/mc_pricer_with_kernel.py +97 -0
  28. stochvolmodels-1.0.18/my_papers/volatility_models/README.md +10 -0
  29. stochvolmodels-1.0.18/my_papers/volatility_models/article_figures.py +216 -0
  30. stochvolmodels-1.0.18/my_papers/volatility_models/autocorr_fit.py +235 -0
  31. stochvolmodels-1.0.18/my_papers/volatility_models/load_data.py +64 -0
  32. stochvolmodels-1.0.18/my_papers/volatility_models/ss_distribution_fit.py +327 -0
  33. stochvolmodels-1.0.18/my_papers/volatility_models/vol_beta.py +61 -0
  34. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/pyproject.toml +2 -2
  35. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/__init__.py +1 -1
  36. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/analytic/tdist.py +2 -1
  37. stochvolmodels-1.0.18/stochvolmodels/tests/__init__.py +0 -0
  38. stochvolmodels-1.0.18/stochvolmodels/utils/__init__.py +0 -0
  39. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/utils/plots.py +5 -5
  40. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/LICENSE.txt +0 -0
  41. {stochvolmodels-1.0.17/stochvolmodels/data → stochvolmodels-1.0.18/my_papers}/__init__.py +0 -0
  42. {stochvolmodels-1.0.17/stochvolmodels/pricers → stochvolmodels-1.0.18/my_papers/volatility_models}/__init__.py +0 -0
  43. {stochvolmodels-1.0.17/stochvolmodels/pricers/analytic → stochvolmodels-1.0.18/stochvolmodels/data}/__init__.py +0 -0
  44. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/data/fetch_option_chain.py +0 -0
  45. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/data/option_chain.py +0 -0
  46. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/data/test_option_chain.py +0 -0
  47. {stochvolmodels-1.0.17/stochvolmodels/pricers/logsv → stochvolmodels-1.0.18/stochvolmodels/pricers}/__init__.py +0 -0
  48. {stochvolmodels-1.0.17/stochvolmodels/tests → stochvolmodels-1.0.18/stochvolmodels/pricers/analytic}/__init__.py +0 -0
  49. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/analytic/bachelier.py +0 -0
  50. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/analytic/bsm.py +0 -0
  51. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/gmm_pricer.py +0 -0
  52. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/hawkes_jd_pricer.py +0 -0
  53. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/heston_pricer.py +0 -0
  54. {stochvolmodels-1.0.17/stochvolmodels/utils → stochvolmodels-1.0.18/stochvolmodels/pricers/logsv}/__init__.py +0 -0
  55. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/logsv/affine_expansion.py +0 -0
  56. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/logsv/vol_moments_ode.py +0 -0
  57. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/logsv_pricer.py +0 -0
  58. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/model_pricer.py +0 -0
  59. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/pricers/tdist_pricer.py +0 -0
  60. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/tests/bsm_mgf_pricer.py +0 -0
  61. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/tests/qv_pricer.py +0 -0
  62. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/utils/config.py +0 -0
  63. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/utils/funcs.py +0 -0
  64. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/stochvolmodels/utils/mc_payoffs.py +0 -0
  65. {stochvolmodels-1.0.17 → stochvolmodels-1.0.18}/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.17
3
+ Version: 1.0.18
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 StochVolPackage provides:
44
+ The StochVol package provides:
45
45
  1) Analytics for Black-Scholes and Normal vols
46
- 2) Interfaces and implementation for stochastic volatility models including log-normal SV model and Heston SV model
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 using Fourier transform with closed-form solution for moment generating function
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://papers.ssrn.com/sol3/papers.cfm?abstract_id=2522425) by Artur Sepp and Parviz Rakhmonov
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 A and Rakhmonov P, SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2522425
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 A and Rakhmonov P,
250
- SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
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 A and Lucic V,
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 StochVolPackage provides:
5
+ The StochVol package provides:
6
6
  1) Analytics for Black-Scholes and Normal vols
7
- 2) Interfaces and implementation for stochastic volatility models including log-normal SV model and Heston SV model
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 using Fourier transform with closed-form solution for moment generating function
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://papers.ssrn.com/sol3/papers.cfm?abstract_id=2522425) by Artur Sepp and Parviz Rakhmonov
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 A and Rakhmonov P, SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2522425
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 A and Rakhmonov P,
211
- SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
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 A and Lucic V,
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
+ ```
@@ -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,10 @@
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/logsv_figures.py
7
+
8
+ https://github.com/ArturSepp/StochVolModels/blob/main/my_papers/il_hedging/logsv_figures.py
9
+
10
+ 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)