stochvolmodels 1.0.7__tar.gz → 1.0.8__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 (28) hide show
  1. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/PKG-INFO +1 -1
  2. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/pyproject.toml +1 -1
  3. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/__init__.py +1 -1
  4. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/data/option_chain.py +1 -1
  5. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv_pricer.py +49 -13
  6. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/LICENSE.txt +0 -0
  7. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/README.md +0 -0
  8. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/data/__init__.py +0 -0
  9. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/data/test_option_chain.py +0 -0
  10. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/__init__.py +0 -0
  11. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/__init__.py +0 -0
  12. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/bsm_pricer.py +0 -0
  13. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/config.py +0 -0
  14. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/mc_payoffs.py +0 -0
  15. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/mgf_pricer.py +0 -0
  16. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/normal_pricer.py +0 -0
  17. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/hawkes_jd_pricer.py +0 -0
  18. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/heston_pricer.py +0 -0
  19. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv/__init__.py +0 -0
  20. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv/affine_expansion.py +0 -0
  21. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv/vol_moments_ode.py +0 -0
  22. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/pricers/model_pricer.py +0 -0
  23. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/tests/__init__.py +0 -0
  24. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/tests/bsm_mgf_pricer.py +0 -0
  25. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/tests/qv_pricer.py +0 -0
  26. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/utils/__init__.py +0 -0
  27. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/utils/funcs.py +0 -0
  28. {stochvolmodels-1.0.7 → stochvolmodels-1.0.8}/stochvolmodels/utils/plots.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stochvolmodels
3
- Version: 1.0.7
3
+ Version: 1.0.8
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.7"
3
+ version = "1.0.8"
4
4
  description = "Implementation of stochastic volatility models for option pricing"
5
5
  license = "LICENSE.txt"
6
6
  authors = ["Artur Sepp <artursepp@gmail.com>"]
@@ -56,7 +56,7 @@ from stochvolmodels.pricers.logsv_pricer import (
56
56
  LOGSV_BTC_PARAMS,
57
57
  LogSVPricer,
58
58
  LogSvParams,
59
- ModelCalibrationType,
59
+ LogsvModelCalibrationType,
60
60
  ConstraintsType
61
61
  )
62
62
 
@@ -272,4 +272,4 @@ class OptionChain:
272
272
  strikes_ttms=List([strikes for _ in ttms]),
273
273
  bid_ivs=List([flat_vol*np.ones_like(strikes) for _ in ttms]),
274
274
  ask_ivs=List([flat_vol*np.ones_like(strikes) for _ in ttms]),
275
- optiontypes_ttms=List([np.where(strikes >= forward, 'C', 'P') for forward in forwards]))
275
+ optiontypes_ttms=List([np.where(strikes >= forward, 'C', 'P') for forward in forwards]))
@@ -29,9 +29,10 @@ from stochvolmodels.data.option_chain import OptionChain
29
29
  from stochvolmodels.data.test_option_chain import get_btc_test_chain_data
30
30
 
31
31
 
32
- class ModelCalibrationType(Enum):
33
- PARAMS5 = 1 # v0, theta, kappa1, beta, volvol
34
- PARAMS6 = 2 # v0, theta, kappa1, kappa2, beta, volvol
32
+ class LogsvModelCalibrationType(Enum):
33
+ PARAMS4 = 1 # v0, theta, beta, volvol; kappa1, kappa2 are set externally
34
+ PARAMS5 = 2 # v0, theta, kappa1, beta, volvol
35
+ PARAMS6 = 3 # v0, theta, kappa1, kappa2, beta, volvol
35
36
 
36
37
 
37
38
  class ConstraintsType(Enum):
@@ -59,8 +60,8 @@ class LogSvParams(ModelParams):
59
60
  self.kappa2 = self.kappa1 / self.theta
60
61
 
61
62
  def to_dict(self) -> Dict[str, Any]:
62
- # return dict(sigma0=self.sigma0, theta=self.theta, kappa1=self.kappa1, kappa2=self.kappa2, beta=self.beta, volvol=self.volvol)
63
63
  return asdict(self)
64
+
64
65
  @property
65
66
  def kappa(self) -> float:
66
67
  return self.kappa1+self.kappa2*self.theta
@@ -220,10 +221,10 @@ class LogSVPricer(ModelPricer):
220
221
  @timer
221
222
  def calibrate_model_params_to_chain(self,
222
223
  option_chain: OptionChain,
223
- params0: LogSvParams = None,
224
+ params0: LogSvParams,
224
225
  is_vega_weighted: bool = True,
225
226
  is_unit_ttm_vega: bool = False,
226
- model_calibration_type: ModelCalibrationType = ModelCalibrationType.PARAMS5,
227
+ model_calibration_type: LogsvModelCalibrationType = LogsvModelCalibrationType.PARAMS5,
227
228
  constraints_type: ConstraintsType = ConstraintsType.UNCONSTRAINT,
228
229
  **kwargs
229
230
  ) -> LogSvParams:
@@ -245,7 +246,39 @@ class LogSVPricer(ModelPricer):
245
246
  else:
246
247
  weights = np.ones_like(market_vols)
247
248
 
248
- if model_calibration_type == ModelCalibrationType.PARAMS5:
249
+ # implement different calibrato types
250
+ if model_calibration_type == LogsvModelCalibrationType.PARAMS4:
251
+ # fit: v0, theta, beta, volvol; kappa1, kappa2 is given with params0
252
+ if params0 is not None:
253
+ p0 = np.array([params0.sigma0, params0.theta, params0.beta, params0.volvol])
254
+ else:
255
+ p0 = np.array([0.8, 0.8, -0.2, 2.0])
256
+ bounds = ((0.01, 2.0), (0.01, 2.0), (-5.0, 3.0), (0.1, 10.0))
257
+
258
+ def objective(pars: np.ndarray, args: np.ndarray) -> float:
259
+ v0, theta, beta, volvol = pars[0], pars[1], pars[2], pars[3]
260
+ params = LogSvParams(sigma0=v0, theta=theta, kappa1=params0.kappa1,
261
+ kappa2=params0.kappa2, beta=beta, volvol=volvol)
262
+ model_vols = self.compute_model_ivols_for_chain(option_chain=option_chain, params=params,
263
+ vol_scaler=vol_scaler)
264
+ resid = np.nansum(weights * np.square(to_flat_np_array(model_vols) - market_vols))
265
+ return resid
266
+
267
+ def martingale_measure(pars: np.ndarray) -> float:
268
+ v0, theta, beta, volvol = pars[0], pars[1], pars[2], pars[3]
269
+ return params0.kappa2 - beta
270
+
271
+ def inverse_measure(pars: np.ndarray) -> float:
272
+ v0, theta, beta, volvol = pars[0], pars[1], pars[2], pars[3]
273
+ return params0.kappa2 - 2.0 * beta
274
+
275
+ def vol_4thmoment_finite(pars: np.ndarray) -> float:
276
+ v0, theta, beta, volvol = pars[0], pars[1], pars[2], pars[3]
277
+ vartheta2 = beta * beta + volvol * volvol
278
+ kappa = params0.kappa1 + params0.kappa2 * theta
279
+ return kappa - 1.5 * vartheta2
280
+
281
+ elif model_calibration_type == LogsvModelCalibrationType.PARAMS5:
249
282
  # fit: v0, theta, kappa1, beta, volvol; kappa2 is mapped as kappa1 / theta
250
283
  if params0 is not None:
251
284
  p0 = np.array([params0.sigma0, params0.theta, params0.kappa1, params0.beta, params0.volvol])
@@ -275,11 +308,6 @@ class LogSVPricer(ModelPricer):
275
308
  kappa = kappa1 + kappa2 * theta
276
309
  return kappa - 1.5*vartheta2
277
310
 
278
- def kurtosis_finite(pars: np.ndarray) -> float:
279
- v0, theta, kappa1, beta, volvol = pars[0], pars[1], pars[2], pars[3], pars[4]
280
- vartheta2 = beta*beta + volvol*volvol
281
- return kappa1 - 1.5*vartheta2
282
-
283
311
  else:
284
312
  raise NotImplementedError(f"{model_calibration_type}")
285
313
 
@@ -320,7 +348,15 @@ class LogSVPricer(ModelPricer):
320
348
 
321
349
  popt = res.x
322
350
 
323
- if model_calibration_type == ModelCalibrationType.PARAMS5:
351
+ if model_calibration_type == LogsvModelCalibrationType.PARAMS4:
352
+ fit_params = LogSvParams(sigma0=popt[0],
353
+ theta=popt[1],
354
+ kappa1=params0.kappa1,
355
+ kappa2=params0.kappa2,
356
+ beta=popt[2],
357
+ volvol=popt[3])
358
+
359
+ elif model_calibration_type == LogsvModelCalibrationType.PARAMS5:
324
360
  fit_params = LogSvParams(sigma0=popt[0],
325
361
  theta=popt[1],
326
362
  kappa1=popt[2],
File without changes