stochvolmodels 1.0.15__tar.gz → 1.0.17__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 (32) hide show
  1. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/PKG-INFO +1 -1
  2. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/pyproject.toml +1 -1
  3. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/__init__.py +3 -3
  4. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/analytic/bsm.py +3 -0
  5. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/analytic/tdist.py +2 -1
  6. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/gmm_pricer.py +57 -3
  7. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/utils/funcs.py +3 -9
  8. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/LICENSE.txt +0 -0
  9. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/README.md +0 -0
  10. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/data/__init__.py +0 -0
  11. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/data/fetch_option_chain.py +0 -0
  12. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/data/option_chain.py +0 -0
  13. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/data/test_option_chain.py +0 -0
  14. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/__init__.py +0 -0
  15. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/analytic/__init__.py +0 -0
  16. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/analytic/bachelier.py +0 -0
  17. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/hawkes_jd_pricer.py +0 -0
  18. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/heston_pricer.py +0 -0
  19. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/logsv/__init__.py +0 -0
  20. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/logsv/affine_expansion.py +0 -0
  21. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/logsv/vol_moments_ode.py +0 -0
  22. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/logsv_pricer.py +0 -0
  23. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/model_pricer.py +0 -0
  24. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/pricers/tdist_pricer.py +0 -0
  25. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/tests/__init__.py +0 -0
  26. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/tests/bsm_mgf_pricer.py +0 -0
  27. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/tests/qv_pricer.py +0 -0
  28. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/utils/__init__.py +0 -0
  29. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/utils/config.py +0 -0
  30. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/utils/mc_payoffs.py +0 -0
  31. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/utils/mgf_pricer.py +0 -0
  32. {stochvolmodels-1.0.15 → stochvolmodels-1.0.17}/stochvolmodels/utils/plots.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stochvolmodels
3
- Version: 1.0.15
3
+ Version: 1.0.17
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
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "stochvolmodels"
3
- version = "1.0.15"
3
+ version = "1.0.17"
4
4
  description = "Implementation of stochastic volatility models for option pricing"
5
5
  license = "LICENSE.txt"
6
6
  authors = ["Artur Sepp <artursepp@gmail.com>"]
@@ -22,8 +22,7 @@ from stochvolmodels.utils.funcs import (
22
22
  to_flat_np_array,
23
23
  update_kwargs,
24
24
  ncdf,
25
- npdf,
26
- npdf1
25
+ npdf
27
26
  )
28
27
 
29
28
  from stochvolmodels.pricers.analytic.bsm import (
@@ -112,7 +111,8 @@ from stochvolmodels.pricers.logsv_pricer import (
112
111
 
113
112
  from stochvolmodels.pricers.gmm_pricer import (
114
113
  GmmParams,
115
- GmmPricer
114
+ GmmPricer,
115
+ plot_gmm_pdfs
116
116
  )
117
117
 
118
118
  from stochvolmodels.pricers.tdist_pricer import (
@@ -249,6 +249,8 @@ def compute_bsm_strike_from_delta(ttm: float,
249
249
  Vega
250
250
  ****************************
251
251
  """
252
+
253
+
252
254
  @njit
253
255
  def compute_bsm_vanilla_vega(ttm: float,
254
256
  forward: float,
@@ -308,6 +310,7 @@ Gamma
308
310
  ****************************
309
311
  """
310
312
 
313
+
311
314
  @njit
312
315
  def compute_bsm_vanilla_gamma(ttm: float,
313
316
  forward: float,
@@ -33,7 +33,8 @@ def cdf_tdist(x: Union[np.ndarray, float], mu: float, vol: float, nu: float, ttm
33
33
  return cdf
34
34
 
35
35
 
36
- def cum_mean_tdist(x: Union[np.ndarray, float], mu: float = 0, vol: float = 0.2, nu: float = 3.0, ttm: float = 0.25) -> Union[float, np.ndarray]:
36
+ def cum_mean_tdist(x: Union[np.ndarray, float], mu: float = 0, vol: float = 0.2, nu: float = 3.0, ttm: float = 0.25
37
+ ) -> Union[float, np.ndarray]:
37
38
  """
38
39
  cumulative expected value
39
40
  h = int^{x}_{-\infty} u f(u)du
@@ -4,14 +4,18 @@ implementation of gaussian mixture pricer and calibration
4
4
  import numpy as np
5
5
  import matplotlib.pyplot as plt
6
6
  from dataclasses import dataclass
7
+
8
+ import pandas as pd
9
+ import qis as qis
10
+ import seaborn as sns
7
11
  from scipy.optimize import minimize
8
12
  from numba import njit
9
13
  from numba.typed import List
10
14
  from typing import Tuple
11
15
  from enum import Enum
12
16
 
13
- from stochvolmodels.utils.funcs import to_flat_np_array, timer, npdf1
14
17
  import stochvolmodels.pricers.analytic.bsm as bsm
18
+ from stochvolmodels.utils.funcs import to_flat_np_array, timer, npdf
15
19
  from stochvolmodels.pricers.model_pricer import ModelParams, ModelPricer
16
20
  from stochvolmodels.utils.config import VariableType
17
21
  from stochvolmodels.data.option_chain import OptionChain
@@ -37,7 +41,7 @@ class GmmParams(ModelParams):
37
41
  state_pdfs = np.zeros((len(x), len(self.gmm_weights)))
38
42
  agg_pdf = np.zeros_like(x)
39
43
  for idx, (gmm_weight, mu, vol) in enumerate(zip(self.gmm_weights, self.gmm_mus, self.gmm_vols)):
40
- state_pdf = npdf1(x, mu=mu*self.ttm, vol=vol*np.sqrt(self.ttm))
44
+ state_pdf = npdf(x, mu=mu*self.ttm, vol=vol*np.sqrt(self.ttm))
41
45
  state_pdfs[:, idx] = state_pdf
42
46
  agg_pdf += gmm_weight*state_pdf
43
47
  return state_pdfs, agg_pdf
@@ -45,7 +49,7 @@ class GmmParams(ModelParams):
45
49
  def compute_pdf(self, x: np.ndarray):
46
50
  pdfs = np.zeros_like(x)
47
51
  for gmm_weight, mu, vol in zip(self.gmm_weights, self.gmm_mus, self.gmm_vols):
48
- pdfs = pdfs + gmm_weight*npdf1(x, mu=mu*self.ttm, vol=vol*np.sqrt(self.ttm))
52
+ pdfs = pdfs + gmm_weight*npdf(x, mu=mu*self.ttm, vol=vol*np.sqrt(self.ttm))
49
53
  return pdfs
50
54
 
51
55
 
@@ -259,6 +263,56 @@ def gmm_vanilla_chain_pricer(gmm_weights: np.ndarray,
259
263
  return model_prices_ttms
260
264
 
261
265
 
266
+ def plot_gmm_pdfs(params: GmmParams,
267
+ option_chain0: OptionChain,
268
+ nstdev: float = 10.0,
269
+ titles: List[str] = None,
270
+ axs: List[plt.Subplot] = None
271
+ ) -> plt.Figure:
272
+ """
273
+ plot gmm pdf and model fit
274
+ """
275
+ stdev = nstdev * params.get_get_avg_vol() * np.sqrt(params.ttm)
276
+ x = np.linspace(-stdev, stdev, 3000)
277
+ state_pdfs, agg_pdf = params.compute_state_pdfs(x=x)
278
+
279
+ columns = []
280
+ for idx in range(len(params.gmm_weights)):
281
+ columns.append(
282
+ f"state-{idx + 1}: mean={params.gmm_mus[idx]:0.2f}, vol={params.gmm_vols[idx]:0.2f}, weight={params.gmm_weights[idx]:0.2f}")
283
+
284
+ state_pdfs = pd.DataFrame(state_pdfs, index=x, columns=columns)
285
+ agg_pdf = pd.Series(agg_pdf, index=x, name='Aggregate PDF')
286
+ df = pd.concat([agg_pdf, state_pdfs], axis=1)
287
+
288
+ kwargs = dict(fontsize=14, framealpha=0.80)
289
+
290
+ if axs is None:
291
+ with sns.axes_style("darkgrid"):
292
+ fig, axs = plt.subplots(1, 2, figsize=(16, 4.5))
293
+ else:
294
+ fig = None
295
+
296
+ qis.plot_line(df=df,
297
+ linestyles=['--'] + ['-'] * len(params.gmm_weights),
298
+ y_limits=(0.0, None),
299
+ xvar_format='{:,.2f}',
300
+ xlabel='log-price',
301
+ first_color_fixed=True,
302
+ ax=axs[0],
303
+ **kwargs)
304
+ axs[0].get_lines()[0].set_linewidth(4.0)
305
+ axs[0].get_legend().get_lines()[0].set_linewidth(4.0)
306
+ qis.set_title(ax=axs[0], title='(A) State PDF and Aggregate Risk-Neutral PDF', **kwargs)
307
+
308
+ gmm_pricer = GmmPricer()
309
+ gmm_pricer.plot_model_ivols_vs_bid_ask(option_chain=option_chain0, params=params,
310
+ is_log_strike_xaxis=True,
311
+ axs=[axs[1]],
312
+ **kwargs)
313
+ return fig
314
+
315
+
262
316
  class UnitTests(Enum):
263
317
  CALIBRATOR = 1
264
318
 
@@ -5,7 +5,7 @@ import functools
5
5
  import time
6
6
  import numpy as np
7
7
  import pandas as pd
8
- from numba import njit, int32, int64
8
+ from numba import njit
9
9
  from numba.typed import List
10
10
  from typing import Tuple, Dict, Any, Optional, Union
11
11
 
@@ -92,11 +92,5 @@ def ncdf(x: Union[float, np.ndarray]) -> Union[float, np.ndarray]:
92
92
 
93
93
 
94
94
  @njit(cache=False, fastmath=True)
95
- def npdf(x: Union[float, np.ndarray]) -> Union[float, np.ndarray]:
96
- return np.exp(-0.5*np.square(x))/np.sqrt(2.0*np.pi)
97
-
98
-
99
- @njit(cache=False, fastmath=True)
100
- def npdf1(x: Union[float, np.ndarray], mu: float, vol: float) -> Union[float, np.ndarray]:
101
- vol2 = vol*vol
102
- return np.exp(-0.5*np.square(x-mu)/vol2)/np.sqrt(2.0*np.pi*vol2)
95
+ def npdf(x: Union[float, np.ndarray], mu: float = 0.0, vol: float = 1.0) -> Union[float, np.ndarray]:
96
+ return np.exp(-0.5*np.square((x-mu)/vol))/(vol*np.sqrt(2.0*np.pi))