stochvolmodels 1.0.12__tar.gz → 1.0.14__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 (31) hide show
  1. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/PKG-INFO +32 -27
  2. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/README.md +31 -27
  3. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/pyproject.toml +1 -1
  4. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/__init__.py +5 -0
  5. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/data/test_option_chain.py +2 -2
  6. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/gmm_pricer.py +1 -0
  7. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/heston_pricer.py +50 -11
  8. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/logsv_pricer.py +23 -4
  9. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/LICENSE.txt +0 -0
  10. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/data/__init__.py +0 -0
  11. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/data/fetch_option_chain.py +0 -0
  12. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/data/option_chain.py +0 -0
  13. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/__init__.py +0 -0
  14. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/analytic/__init__.py +0 -0
  15. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/analytic/bachelier.py +0 -0
  16. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/analytic/bsm.py +0 -0
  17. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/analytic/tdist.py +0 -0
  18. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/hawkes_jd_pricer.py +0 -0
  19. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/logsv/__init__.py +0 -0
  20. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/logsv/affine_expansion.py +0 -0
  21. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/logsv/vol_moments_ode.py +0 -0
  22. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/pricers/model_pricer.py +0 -0
  23. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/tests/__init__.py +0 -0
  24. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/tests/bsm_mgf_pricer.py +0 -0
  25. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/tests/qv_pricer.py +0 -0
  26. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/utils/__init__.py +0 -0
  27. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/utils/config.py +0 -0
  28. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/utils/funcs.py +0 -0
  29. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/utils/mc_payoffs.py +0 -0
  30. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/utils/mgf_pricer.py +0 -0
  31. {stochvolmodels-1.0.12 → stochvolmodels-1.0.14}/stochvolmodels/utils/plots.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stochvolmodels
3
- Version: 1.0.12
3
+ Version: 1.0.14
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
@@ -50,32 +50,6 @@ For the analytic implementation of stochastic volatility models, the package pro
50
50
  1) Interface for analytical pricing of vanilla options using Fourier transform with closed-form solution for moment generating function
51
51
  2) Interface for Monte-Carlo simulations of model dynamics
52
52
 
53
- ## Supporting Illustrations for Public Papers
54
-
55
- As illustrations of different analytics, this packadge includes module ```my_papers```
56
- with codes for computations and visualisations featured in several papers
57
- for
58
-
59
- 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
60
- ```python
61
- stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
62
- ```
63
-
64
-
65
- 2) "What is a robust stochastic volatility model" by Sepp A and Rakhmonov P,
66
- SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
67
- ```python
68
- stochvolmodels/my_papers/volatility_models
69
- ```
70
-
71
-
72
- 3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Sepp A and Lucic V,
73
- SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4606748
74
- ```python
75
- stochvolmodels/my_papers/inverse_options
76
- ```
77
-
78
-
79
53
 
80
54
  ## Installation
81
55
  ```python
@@ -92,6 +66,8 @@ pip install stochvolmodels
92
66
  3. [Comparison of model prices vs MC](#subparagraph3)
93
67
  4. [Analysis and figures for the paper](#subparagraph4)
94
68
  3. [Running Heston SV pricer](#heston)
69
+ 4. [Supporting Illustrations for Public Papers](#papers)
70
+
95
71
 
96
72
  Running model calibration to sample Bitcoin options data
97
73
 
@@ -256,3 +232,32 @@ pricer.plot_model_slices_in_params(option_slice=option_slice, params_dict=params
256
232
 
257
233
  plt.show()
258
234
  ```
235
+
236
+
237
+ ## Supporting Illustrations for Public Papers <a name="papers"></a>
238
+
239
+ As illustrations of different analytics, this packadge includes module ```my_papers```
240
+ with codes for computations and visualisations featured in several papers
241
+ for
242
+
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
244
+ ```python
245
+ stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
246
+ ```
247
+
248
+
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
251
+ ```python
252
+ stochvolmodels/my_papers/volatility_models
253
+ ```
254
+
255
+
256
+ 3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Sepp A and Lucic V,
257
+ SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4606748
258
+ ```python
259
+ stochvolmodels/my_papers/inverse_options
260
+ ```
261
+
262
+
263
+
@@ -11,32 +11,6 @@ For the analytic implementation of stochastic volatility models, the package pro
11
11
  1) Interface for analytical pricing of vanilla options using Fourier transform with closed-form solution for moment generating function
12
12
  2) Interface for Monte-Carlo simulations of model dynamics
13
13
 
14
- ## Supporting Illustrations for Public Papers
15
-
16
- As illustrations of different analytics, this packadge includes module ```my_papers```
17
- with codes for computations and visualisations featured in several papers
18
- for
19
-
20
- 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
21
- ```python
22
- stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
23
- ```
24
-
25
-
26
- 2) "What is a robust stochastic volatility model" by Sepp A and Rakhmonov P,
27
- SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
28
- ```python
29
- stochvolmodels/my_papers/volatility_models
30
- ```
31
-
32
-
33
- 3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Sepp A and Lucic V,
34
- SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4606748
35
- ```python
36
- stochvolmodels/my_papers/inverse_options
37
- ```
38
-
39
-
40
14
 
41
15
  ## Installation
42
16
  ```python
@@ -53,6 +27,8 @@ pip install stochvolmodels
53
27
  3. [Comparison of model prices vs MC](#subparagraph3)
54
28
  4. [Analysis and figures for the paper](#subparagraph4)
55
29
  3. [Running Heston SV pricer](#heston)
30
+ 4. [Supporting Illustrations for Public Papers](#papers)
31
+
56
32
 
57
33
  Running model calibration to sample Bitcoin options data
58
34
 
@@ -216,4 +192,32 @@ pricer = HestonPricer()
216
192
  pricer.plot_model_slices_in_params(option_slice=option_slice, params_dict=params_dict)
217
193
 
218
194
  plt.show()
219
- ```
195
+ ```
196
+
197
+
198
+ ## Supporting Illustrations for Public Papers <a name="papers"></a>
199
+
200
+ As illustrations of different analytics, this packadge includes module ```my_papers```
201
+ with codes for computations and visualisations featured in several papers
202
+ for
203
+
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
205
+ ```python
206
+ stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
207
+ ```
208
+
209
+
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
212
+ ```python
213
+ stochvolmodels/my_papers/volatility_models
214
+ ```
215
+
216
+
217
+ 3) "Valuation and Hedging of Cryptocurrency Inverse Options" by Sepp A and Lucic V,
218
+ SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4606748
219
+ ```python
220
+ stochvolmodels/my_papers/inverse_options
221
+ ```
222
+
223
+
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "stochvolmodels"
3
- version = "1.0.12"
3
+ version = "1.0.14"
4
4
  description = "Implementation of stochastic volatility models for option pricing"
5
5
  license = "LICENSE.txt"
6
6
  authors = ["Artur Sepp <artursepp@gmail.com>"]
@@ -114,10 +114,12 @@ from stochvolmodels.pricers.gmm_pricer import (
114
114
 
115
115
  from stochvolmodels.data.option_chain import OptionChain, OptionSlice
116
116
 
117
+ """
117
118
  from stochvolmodels.data.fetch_option_chain import (generate_vol_chain_np,
118
119
  load_option_chain,
119
120
  sample_option_chain_at_times,
120
121
  load_price_data)
122
+ """
121
123
 
122
124
  from stochvolmodels.data.test_option_chain import (
123
125
  get_btc_test_chain_data,
@@ -148,3 +150,6 @@ from stochvolmodels.utils.plots import (
148
150
  set_y_limits,
149
151
  vol_slice_fit
150
152
  )
153
+
154
+
155
+ from stochvolmodels.pricers.logsv.vol_moments_ode import compute_analytic_qvar
@@ -852,10 +852,10 @@ def get_qv_options_test_chain_data(num_strikes: int = 21) -> OptionChain:
852
852
  forwards = array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
853
853
  discfactors = array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
854
854
  strikes_ttm = np.linspace(0.75, 1.5, num_strikes)
855
- strikes_ttms = (strikes_ttm, strikes_ttm, strikes_ttm, strikes_ttm)
855
+ strikes_ttms = (strikes_ttm, strikes_ttm, strikes_ttm, strikes_ttm, strikes_ttm, strikes_ttm)
856
856
 
857
857
  optiontypes_ttm = np.full(strikes_ttm.shape, 'C')
858
- optiontypes_ttms = (optiontypes_ttm, optiontypes_ttm, optiontypes_ttm, optiontypes_ttm)
858
+ optiontypes_ttms = (optiontypes_ttm, optiontypes_ttm, optiontypes_ttm, optiontypes_ttm, optiontypes_ttm, optiontypes_ttm)
859
859
 
860
860
  data = OptionChain(ids=ids,
861
861
  ttms=ttms,
@@ -191,6 +191,7 @@ def compute_gmm_vanilla_price(gmm_weights: np.ndarray,
191
191
  price = 0.0
192
192
  for gmm_weight, gmm_mu, gmm_vol in zip(gmm_weights, gmm_mus, gmm_vols):
193
193
  forward_i = forward*np.exp((gmm_mu+0.5*gmm_vol*gmm_vol)*ttm)
194
+ # forward is vol-adjusted
194
195
  price_i = bsm.compute_bsm_vanilla_price(forward=forward_i,
195
196
  strike=strike,
196
197
  ttm=ttm,
@@ -13,10 +13,10 @@ from enum import Enum
13
13
 
14
14
  # stochvolmodels
15
15
  from stochvolmodels.utils.funcs import to_flat_np_array, set_time_grid, timer
16
- from stochvolmodels.utils.mgf_pricer import get_transform_var_grid, vanilla_slice_pricer_with_mgf_grid
17
16
  from stochvolmodels.utils.config import VariableType
18
17
  from stochvolmodels.utils.mc_payoffs import compute_mc_vars_payoff
19
18
  from stochvolmodels.pricers.model_pricer import ModelParams, ModelPricer
19
+ import stochvolmodels.utils.mgf_pricer as mgfp
20
20
 
21
21
  # data
22
22
  from stochvolmodels.data.option_chain import OptionChain
@@ -192,11 +192,14 @@ def heston_chain_pricer(v0: float,
192
192
  strikes_ttms: Tuple[np.ndarray, ...],
193
193
  optiontypes_ttms: Tuple[np.ndarray, ...],
194
194
  discfactors: np.ndarray,
195
+ variable_type: VariableType = VariableType.LOG_RETURN,
195
196
  vol_scaler: float = None # run calibration on same vol_scaler
196
197
  ) -> List[np.ndarray]:
197
198
 
198
199
  # starting values
199
- phi_grid, psi_grid, theta_grid = get_transform_var_grid(vol_scaler=vol_scaler or np.sqrt(v0*ttms[-1]))
200
+ if vol_scaler is None:
201
+ vol_scaler = np.minimum(0.3, np.sqrt(v0*ttms[0]))
202
+ phi_grid, psi_grid, theta_grid = mgfp.get_transform_var_grid(vol_scaler=vol_scaler)
200
203
  a_t0, b_t0 = np.zeros(phi_grid.shape[0], dtype=np.complex128), np.zeros(phi_grid.shape[0], dtype=np.complex128)
201
204
  ttm0 = 0.0
202
205
 
@@ -213,13 +216,26 @@ def heston_chain_pricer(v0: float,
213
216
  psi_grid=psi_grid,
214
217
  a_t0=a_t0,
215
218
  b_t0=b_t0)
216
-
217
- option_prices = vanilla_slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
218
- phi_grid=phi_grid,
219
- forward=forward,
220
- discfactor=discfactor,
221
- strikes=strikes_ttm,
222
- optiontypes=optiontypes_ttm)
219
+
220
+ if variable_type == VariableType.LOG_RETURN:
221
+ option_prices = mgfp.vanilla_slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
222
+ phi_grid=phi_grid,
223
+ forward=forward,
224
+ strikes=strikes_ttm,
225
+ optiontypes=optiontypes_ttm,
226
+ discfactor=discfactor)
227
+
228
+ elif variable_type == VariableType.Q_VAR:
229
+ option_prices = mgfp.slice_qvar_pricer_with_a_grid(log_mgf_grid=log_mgf_grid,
230
+ psi_grid=psi_grid,
231
+ ttm=ttm,
232
+ forward=forward,
233
+ strikes=strikes_ttm,
234
+ optiontypes=optiontypes_ttm,
235
+ discfactor=discfactor)
236
+ else:
237
+ raise NotImplementedError(f"variable_type={variable_type}")
238
+
223
239
  model_prices_ttms.append(option_prices)
224
240
  ttm0 = ttm
225
241
 
@@ -330,10 +346,12 @@ class UnitTests(Enum):
330
346
  SLICE_PRICER = 2
331
347
  CALIBRATOR = 3
332
348
  MC_COMPARISION = 4
333
-
349
+ MC_COMPARISION_QVAR = 5
334
350
 
335
351
  def run_unit_test(unit_test: UnitTests):
336
352
 
353
+ import stochvolmodels.data.test_option_chain as chains
354
+
337
355
  if unit_test == UnitTests.CHAIN_PRICER:
338
356
  params = HestonParams(v0=0.85**2,
339
357
  theta=1.4**2,
@@ -392,12 +410,33 @@ def run_unit_test(unit_test: UnitTests):
392
410
  heston_pricer.plot_model_ivols_vs_mc(option_chain=option_chain,
393
411
  params=BTC_HESTON_PARAMS)
394
412
 
413
+ elif unit_test == UnitTests.MC_COMPARISION_QVAR:
414
+ from stochvolmodels.pricers.logsv.vol_moments_ode import compute_analytic_qvar
415
+ from stochvolmodels.pricers.logsv_pricer import LogSvParams
416
+ heston_pricer = HestonPricer()
417
+ ttms = {'1m': 1.0/12.0, '6m': 0.5}
418
+ option_chain = chains.get_qv_options_test_chain_data()
419
+ option_chain = OptionChain.get_slices_as_chain(option_chain, ids=list(ttms.keys()))
420
+ LOGSV_BTC_PARAMS = LogSvParams(sigma0=0.8376, theta=1.0413, kappa1=3.1844, kappa2=3.058, beta=0.1514,
421
+ volvol=1.8458)
422
+
423
+ forwards = np.array([compute_analytic_qvar(params=LOGSV_BTC_PARAMS, ttm=ttm, n_terms=4) for ttm in ttms.values()])
424
+ print(f"QV forwards = {forwards}")
425
+
426
+ option_chain.forwards = forwards # replace forwards to imply BSM vols
427
+ option_chain.strikes_ttms = List(forward * strikes_ttm for forward, strikes_ttm in zip(option_chain.forwards, option_chain.strikes_ttms))
428
+
429
+ fig = heston_pricer.plot_model_ivols_vs_mc(option_chain=option_chain,
430
+ params=BTC_HESTON_PARAMS,
431
+ variable_type=VariableType.Q_VAR,
432
+ nb_path=200000)
433
+
395
434
  plt.show()
396
435
 
397
436
 
398
437
  if __name__ == '__main__':
399
438
 
400
- unit_test = UnitTests.MC_COMPARISION
439
+ unit_test = UnitTests.CALIBRATOR
401
440
 
402
441
  is_run_all_tests = False
403
442
  if is_run_all_tests:
@@ -770,13 +770,16 @@ class UnitTests(Enum):
770
770
  SLICE_PRICER = 2
771
771
  CALIBRATOR = 3
772
772
  MC_COMPARISION = 4
773
- VOL_PATHS = 5
774
- TERMINAL_VALUES = 6
775
- MMA_INVERSE_MEASURE_VS_MC = 7
773
+ MC_COMPARISION_QVAR = 5
774
+ VOL_PATHS = 6
775
+ TERMINAL_VALUES = 7
776
+ MMA_INVERSE_MEASURE_VS_MC = 8
776
777
 
777
778
 
778
779
  def run_unit_test(unit_test: UnitTests):
779
780
 
781
+ import stochvolmodels.data.test_option_chain as chains
782
+
780
783
  if unit_test == UnitTests.CHAIN_PRICER:
781
784
  option_chain = get_btc_test_chain_data()
782
785
  logsv_pricer = LogSVPricer()
@@ -822,6 +825,22 @@ def run_unit_test(unit_test: UnitTests):
822
825
  logsv_pricer.plot_model_ivols_vs_mc(option_chain=option_chain,
823
826
  params=LOGSV_BTC_PARAMS)
824
827
 
828
+ elif unit_test == UnitTests.MC_COMPARISION_QVAR:
829
+ from stochvolmodels.pricers.logsv.vol_moments_ode import compute_analytic_qvar
830
+ logsv_pricer = LogSVPricer()
831
+ ttms = {'1m': 1.0/12.0, '6m': 0.5}
832
+ option_chain = chains.get_qv_options_test_chain_data()
833
+ option_chain = OptionChain.get_slices_as_chain(option_chain, ids=list(ttms.keys()))
834
+ forwards = np.array([compute_analytic_qvar(params=LOGSV_BTC_PARAMS, ttm=ttm, n_terms=4) for ttm in ttms.values()])
835
+ print(f"QV forwards = {forwards}")
836
+
837
+ option_chain.forwards = forwards # replace forwards to imply BSM vols
838
+ option_chain.strikes_ttms = List(forward * strikes_ttm for forward, strikes_ttm in zip(option_chain.forwards, option_chain.strikes_ttms))
839
+
840
+ fig = logsv_pricer.plot_model_ivols_vs_mc(option_chain=option_chain,
841
+ params=LOGSV_BTC_PARAMS,
842
+ variable_type=VariableType.Q_VAR)
843
+
825
844
  elif unit_test == UnitTests.VOL_PATHS:
826
845
  logsv_pricer = LogSVPricer()
827
846
  nb_path = 10
@@ -859,7 +878,7 @@ def run_unit_test(unit_test: UnitTests):
859
878
 
860
879
  if __name__ == '__main__':
861
880
 
862
- unit_test = UnitTests.VOL_PATHS
881
+ unit_test = UnitTests.MC_COMPARISION_QVAR
863
882
 
864
883
  is_run_all_tests = False
865
884
  if is_run_all_tests: