stochvolmodels 1.0.6__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.6 → stochvolmodels-1.0.8}/PKG-INFO +18 -2
  2. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/README.md +17 -1
  3. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/pyproject.toml +1 -1
  4. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/__init__.py +35 -1
  5. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/data/option_chain.py +1 -1
  6. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/mgf_pricer.py +63 -13
  7. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/hawkes_jd_pricer.py +7 -8
  8. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/heston_pricer.py +7 -8
  9. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv_pricer.py +56 -21
  10. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/tests/bsm_mgf_pricer.py +6 -7
  11. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/LICENSE.txt +0 -0
  12. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/data/__init__.py +0 -0
  13. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/data/test_option_chain.py +0 -0
  14. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/__init__.py +0 -0
  15. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/__init__.py +0 -0
  16. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/bsm_pricer.py +0 -0
  17. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/config.py +0 -0
  18. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/mc_payoffs.py +0 -0
  19. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/core/normal_pricer.py +0 -0
  20. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv/__init__.py +0 -0
  21. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv/affine_expansion.py +0 -0
  22. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/logsv/vol_moments_ode.py +0 -0
  23. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/pricers/model_pricer.py +0 -0
  24. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/tests/__init__.py +0 -0
  25. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/tests/qv_pricer.py +0 -0
  26. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/utils/__init__.py +0 -0
  27. {stochvolmodels-1.0.6 → stochvolmodels-1.0.8}/stochvolmodels/utils/funcs.py +0 -0
  28. {stochvolmodels-1.0.6 → 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.6
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
@@ -50,12 +50,28 @@ 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
+ ## Illustrations
54
+
55
+ As illustrations of different analytics, this packadge includes the computations and visualisations
56
+ for
57
+
58
+ 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
59
+ ```python
60
+ stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
61
+ ```
62
+
63
+
64
+ 2) What is a robust stochastic volatility model by Sepp A and Rakhmonov P, SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
65
+ ```python
66
+ stochvolmodels/my_papers/volatility_models
67
+ ```
68
+
69
+
53
70
  ## Installation
54
71
  ```python
55
72
  pip install stochvolmodels
56
73
  ```
57
74
 
58
-
59
75
  # Table of contents
60
76
  1. [Model Interface](#introduction)
61
77
  1. [Log-normal stochastic volatility model](#logsv)
@@ -11,12 +11,28 @@ 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
+ ## Illustrations
15
+
16
+ As illustrations of different analytics, this packadge includes the computations and visualisations
17
+ for
18
+
19
+ 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
20
+ ```python
21
+ stochvolmodels/my_papers/logsv_model_wtih_quadratic_drift
22
+ ```
23
+
24
+
25
+ 2) What is a robust stochastic volatility model by Sepp A and Rakhmonov P, SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4647027
26
+ ```python
27
+ stochvolmodels/my_papers/volatility_models
28
+ ```
29
+
30
+
14
31
  ## Installation
15
32
  ```python
16
33
  pip install stochvolmodels
17
34
  ```
18
35
 
19
-
20
36
  # Table of contents
21
37
  1. [Model Interface](#introduction)
22
38
  1. [Log-normal stochastic volatility model](#logsv)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "stochvolmodels"
3
- version = "1.0.6"
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
 
@@ -92,6 +92,40 @@ from stochvolmodels.utils.plots import (
92
92
  vol_slice_fit
93
93
  )
94
94
 
95
+
96
+ from stochvolmodels.pricers.core.mgf_pricer import (
97
+ compute_integration_weights,
98
+ digital_slice_pricer_with_mgf_grid,
99
+ get_phi_grid,
100
+ get_psi_grid,
101
+ get_theta_grid,
102
+ get_transform_var_grid,
103
+ pdf_with_mgf_grid,
104
+ slice_pricer_with_mgf_grid_with_gamma,
105
+ slice_qvar_pricer_with_a_grid,
106
+ vanilla_slice_pricer_with_mgf_grid,
107
+ slice_pricer_with_mgf_grid_with_gamma,
108
+ )
109
+
110
+ from stochvolmodels.pricers.logsv.affine_expansion import (
111
+ ExpansionOrder,
112
+ VariableType,
113
+ compute_logsv_a_mgf_grid,
114
+ func_a_ode_quadratic_terms,
115
+ func_rhs,
116
+ func_rhs_jac,
117
+ get_expansion_n,
118
+ get_init_conditions_a,
119
+ solve_a_ode_grid,
120
+ solve_analytic_ode_for_a,
121
+ solve_analytic_ode_for_a0,
122
+ solve_analytic_ode_grid_phi,
123
+ solve_ode_for_a,
124
+ compute_logsv_a_mgf_grid,
125
+ solve_a_ode_grid,
126
+ solve_ode_for_a,
127
+ )
128
+
95
129
  from stochvolmodels.pricers.core.config import VariableType
96
130
 
97
131
  from stochvolmodels.pricers.core.mc_payoffs import compute_mc_vars_payoff
@@ -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]))
@@ -27,7 +27,10 @@ def get_phi_grid(is_spot_measure: bool = True,
27
27
  else:
28
28
  real_p = real_phi
29
29
  else:
30
- real_p = 0.5
30
+ if real_phi is None:
31
+ real_p = 0.5
32
+ else:
33
+ real_p = real_phi
31
34
  phi_grid = real_p + 1j * p
32
35
  return phi_grid
33
36
 
@@ -109,18 +112,17 @@ def compute_integration_weights(var_grid: np.ndarray,
109
112
 
110
113
 
111
114
  @njit(cache=False, fastmath=True)
112
- def slice_pricer_with_mgf_grid(log_mgf_grid: np.ndarray,
113
- phi_grid: np.ndarray,
114
- ttm: float,
115
- forward: float,
116
- strikes: np.ndarray,
117
- optiontypes: np.ndarray,
118
- discfactor: float = 1.0,
119
- is_spot_measure: bool = True,
120
- is_simpson: bool = True
121
- ) -> np.ndarray:
115
+ def vanilla_slice_pricer_with_mgf_grid(log_mgf_grid: np.ndarray,
116
+ phi_grid: np.ndarray,
117
+ forward: float,
118
+ strikes: np.ndarray,
119
+ optiontypes: np.ndarray,
120
+ discfactor: float = 1.0,
121
+ is_spot_measure: bool = True,
122
+ is_simpson: bool = True
123
+ ) -> np.ndarray:
122
124
  """
123
- generic function for pricing options on the spot given the mgf grid
125
+ generic function for pricing vanilla options on the spot given the mgf grid
124
126
  mgf in x is function defined on log-price transform phi grids
125
127
  transform variable is phi_grid = real_phi + i*p
126
128
  grid can be non-uniform
@@ -128,7 +130,7 @@ def slice_pricer_with_mgf_grid(log_mgf_grid: np.ndarray,
128
130
  p = np.imag(phi_grid)
129
131
  dp = compute_integration_weights(var_grid=phi_grid, is_simpson=is_simpson)
130
132
 
131
- if np.all(np.abs(np.real(phi_grid))-0.5 < 1e-10): # optimized for phi = +/-0.5 + i*p
133
+ if np.all(np.equal(np.abs(np.real(phi_grid)), 0.5)): # optimized for phi = +/-0.5 + i*p
132
134
  p_payoff = (dp / np.pi) / (p * p + 0.25) + 1j * 0.0 # add zero complex part for numba
133
135
  else:
134
136
  if is_spot_measure:
@@ -159,6 +161,54 @@ def slice_pricer_with_mgf_grid(log_mgf_grid: np.ndarray,
159
161
  return option_prices
160
162
 
161
163
 
164
+ @njit(cache=False, fastmath=True)
165
+ def digital_slice_pricer_with_mgf_grid(log_mgf_grid: np.ndarray,
166
+ phi_grid: np.ndarray,
167
+ forward: float,
168
+ strikes: np.ndarray,
169
+ optiontypes: np.ndarray,
170
+ discfactor: float = 1.0,
171
+ is_simpson: bool = True
172
+ ) -> np.ndarray:
173
+ """
174
+ generic function for pricing digital options on the spot given the mgf grid
175
+ mgf in x is function defined on log-price transform phi grids
176
+ transform variable is phi_grid = real_phi + i*p
177
+ grid can be non-uniform
178
+ """
179
+ dp = compute_integration_weights(var_grid=phi_grid, is_simpson=is_simpson)
180
+
181
+ # we can use positive or negative phi_real
182
+ if np.all(np.real(phi_grid) < 0.0): # use calls
183
+ is_all_calls = True
184
+ p_payoff = - (dp / np.pi) / (phi_grid) # for calls
185
+ else:
186
+ is_all_calls = False
187
+ p_payoff = (dp / np.pi) / (phi_grid) # for puts
188
+
189
+ log_strikes = np.log(forward/strikes)
190
+ option_prices = np.zeros_like(log_strikes)
191
+ for idx, (x, strike, type_) in enumerate(zip(log_strikes, strikes, optiontypes)):
192
+ # compute sum using trapesoidal rule
193
+ digital_option_price = np.nansum(np.real(p_payoff*np.exp(-x * phi_grid + log_mgf_grid)))
194
+ if type_ == 'C':
195
+ if is_all_calls:
196
+ price = digital_option_price
197
+ else:
198
+ price = 1.0 - digital_option_price
199
+ elif type_ == 'P':
200
+ if is_all_calls:
201
+ price = 1.0 - digital_option_price
202
+ else:
203
+ price = digital_option_price
204
+ else:
205
+ raise ValueError(f"not implemented")
206
+
207
+ option_prices[idx] = discfactor * price
208
+
209
+ return option_prices
210
+
211
+
162
212
  #@njit(cache=False, fastmath=True)
163
213
  def slice_pricer_with_mgf_grid_with_gamma(log_mgf_grid: np.ndarray,
164
214
  phi_grid: np.ndarray,
@@ -365,14 +365,13 @@ def hawkesjd_chain_pricer(model_params: HawkesJDParams,
365
365
  model_params=model_params)
366
366
 
367
367
  if variable_type == VariableType.LOG_RETURN:
368
- option_prices = mgfp.slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
369
- phi_grid=phi_grid,
370
- ttm=ttm,
371
- forward=forward,
372
- strikes=strikes_ttm,
373
- optiontypes=optiontypes_ttm,
374
- discfactor=discfactor,
375
- is_spot_measure=is_spot_measure)
368
+ option_prices = mgfp.vanilla_slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
369
+ phi_grid=phi_grid,
370
+ forward=forward,
371
+ strikes=strikes_ttm,
372
+ optiontypes=optiontypes_ttm,
373
+ discfactor=discfactor,
374
+ is_spot_measure=is_spot_measure)
376
375
  else:
377
376
  raise NotImplementedError
378
377
 
@@ -11,7 +11,7 @@ from numba.typed import List
11
11
  from typing import Tuple
12
12
  from enum import Enum
13
13
 
14
- from stochvolmodels.pricers.core.mgf_pricer import get_transform_var_grid, slice_pricer_with_mgf_grid
14
+ from stochvolmodels.pricers.core.mgf_pricer import get_transform_var_grid, vanilla_slice_pricer_with_mgf_grid
15
15
  from stochvolmodels.pricers.model_pricer import ModelParams, ModelPricer
16
16
  from stochvolmodels.data.option_chain import OptionChain
17
17
  from stochvolmodels.data.test_option_chain import get_btc_test_chain_data
@@ -213,13 +213,12 @@ def heston_chain_pricer(v0: float,
213
213
  a_t0=a_t0,
214
214
  b_t0=b_t0)
215
215
 
216
- option_prices = slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
217
- phi_grid=phi_grid,
218
- ttm=ttm,
219
- forward=forward,
220
- discfactor=discfactor,
221
- strikes=strikes_ttm,
222
- optiontypes=optiontypes_ttm)
216
+ option_prices = vanilla_slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
217
+ phi_grid=phi_grid,
218
+ forward=forward,
219
+ discfactor=discfactor,
220
+ strikes=strikes_ttm,
221
+ optiontypes=optiontypes_ttm)
223
222
  model_prices_ttms.append(option_prices)
224
223
  ttm0 = ttm
225
224
 
@@ -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],
@@ -481,14 +517,13 @@ def logsv_chain_pricer(params: LogSvParams,
481
517
  **params.to_dict())
482
518
 
483
519
  if variable_type == VariableType.LOG_RETURN:
484
- option_prices = mgfp.slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
485
- phi_grid=phi_grid,
486
- ttm=ttm,
487
- forward=forward,
488
- strikes=strikes_ttm,
489
- optiontypes=optiontypes_ttm,
490
- discfactor=discfactor,
491
- is_spot_measure=is_spot_measure)
520
+ option_prices = mgfp.vanilla_slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
521
+ phi_grid=phi_grid,
522
+ forward=forward,
523
+ strikes=strikes_ttm,
524
+ optiontypes=optiontypes_ttm,
525
+ discfactor=discfactor,
526
+ is_spot_measure=is_spot_measure)
492
527
 
493
528
  elif variable_type == VariableType.Q_VAR:
494
529
  option_prices = mgfp.slice_qvar_pricer_with_a_grid(log_mgf_grid=log_mgf_grid,
@@ -51,13 +51,12 @@ def bsm_slice_pricer(ttm: float,
51
51
 
52
52
  if variable_type == VariableType.LOG_RETURN:
53
53
  log_mgf_grid, phi_grid = compute_normal_mgf_grid(ttm=ttm, vol=vol, is_spot_measure=is_spot_measure)
54
- bsm_prices = mgfp.slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
55
- phi_grid=phi_grid,
56
- ttm=ttm,
57
- forward=forward,
58
- strikes=strikes,
59
- optiontypes=optiontypes,
60
- is_spot_measure=is_spot_measure)
54
+ bsm_prices = mgfp.vanilla_slice_pricer_with_mgf_grid(log_mgf_grid=log_mgf_grid,
55
+ phi_grid=phi_grid,
56
+ forward=forward,
57
+ strikes=strikes,
58
+ optiontypes=optiontypes,
59
+ is_spot_measure=is_spot_measure)
61
60
  bsm_ivols = infer_bsm_ivols_from_model_chain_prices(ttms=np.array([ttm]),
62
61
  forwards=np.array([forward]),
63
62
  discfactors=np.array([1.0]),