With syntetic market price#

Here with an Heston model.

[ ]:
from hestonpy.models.heston import Heston
from hestonpy.models.calibration.volatilitySmile import VolatilitySmile
import numpy as np

r = 0.00

Some parameters

[3]:
spot = 100
time_to_maturity = 1
true_params = {
    "vol_initial": 0.06,
    "kappa": 1.25,
    "theta": 0.06,
    "sigma": 0.6,
    "rho": -0.5,
    "drift_emm": 0.00,
}
vol = np.sqrt(0.04)

heston = Heston(spot=spot, r=r, **true_params)
price_function = heston.call_price

strikes = np.linspace(70, 140, 10)

Without noise#

[4]:
market_prices = price_function(**true_params, strike=strikes, time_to_maturity=time_to_maturity, s=spot)

volSmile = VolatilitySmile(
    strikes=strikes,
    time_to_maturity=time_to_maturity,
    atm=spot,
    market_prices=market_prices,
    r=r
)
volSmile.plot()
../../_images/examples_calibration_calibration_synthetic_data_6_0.png

Local optimization#

[5]:
calibrated_params = volSmile.calibration(
    price_function=price_function,
    initial_guess = [1.0, 0.03, 0.4, -0.5],
    guess_correlation_sign='negative',
    speed='local',
)
calibrated_heston = Heston(spot=spot, r=r, **calibrated_params)
volSmile.plot(calibrated_prices=heston.call_price(strike=strikes, time_to_maturity=time_to_maturity))
calibrated_params
Calibrated parameters: v0=0.046 | kappa=0.985 | theta=0.085 | sigma=0.580 | rho=-0.506

../../_images/examples_calibration_calibration_synthetic_data_8_1.png
[5]:
{'vol_initial': np.float64(0.04589503493265889),
 'kappa': np.float64(0.9849851420478373),
 'theta': np.float64(0.08456116488309652),
 'sigma': np.float64(0.580145120734101),
 'rho': np.float64(-0.5063722128514593),
 'drift_emm': 0}
[6]:
true_params
[6]:
{'vol_initial': 0.06,
 'kappa': 1.25,
 'theta': 0.06,
 'sigma': 0.6,
 'rho': -0.5,
 'drift_emm': 0.0}

Global optimization#

[7]:
calibrated_params = volSmile.calibration(
    price_function=price_function,
    initial_guess = [1.0, 0.03, 0.4, -0.5],
    guess_correlation_sign='negative',
    speed='global',
)
calibrated_heston = Heston(spot=spot, r=r, **calibrated_params)
volSmile.plot(calibrated_prices=heston.call_price(strike=strikes, time_to_maturity=time_to_maturity))
calibrated_params
at minimum 0.000002 accepted 1
Parameters: kappa=0.985 | theta=0.085 | sigma=0.580 | rho=-0.506

at minimum 0.000309 accepted 1
Parameters: kappa=0.021 | theta=1.289 | sigma=0.390 | rho=-0.519

at minimum 0.000310 accepted 1
Parameters: kappa=0.020 | theta=1.367 | sigma=0.390 | rho=-0.519

at minimum 0.000317 accepted 1
Parameters: kappa=0.011 | theta=2.352 | sigma=0.388 | rho=-0.520

at minimum 0.000314 accepted 1
Parameters: kappa=0.015 | theta=1.816 | sigma=0.389 | rho=-0.520

at minimum 0.000309 accepted 1
Parameters: kappa=0.021 | theta=1.322 | sigma=0.390 | rho=-0.519

['success condition satisfied'] True
Calibrated parameters: v0=0.046 | kappa=0.985 | theta=0.085 | sigma=0.580 | rho=-0.506

../../_images/examples_calibration_calibration_synthetic_data_11_1.png
[7]:
{'vol_initial': np.float64(0.04589503493265889),
 'kappa': np.float64(0.9849851420478373),
 'theta': np.float64(0.08456116488309652),
 'sigma': np.float64(0.580145120734101),
 'rho': np.float64(-0.5063722128514593),
 'drift_emm': 0}
[8]:
true_params
[8]:
{'vol_initial': 0.06,
 'kappa': 1.25,
 'theta': 0.06,
 'sigma': 0.6,
 'rho': -0.5,
 'drift_emm': 0.0}

With noise#

[9]:
market_prices = market_prices * (1 + np.random.normal(scale=0.01, size=len(market_prices)))  # a little of market noise
volSmile = VolatilitySmile(
    strikes=strikes,
    time_to_maturity=time_to_maturity,
    atm=spot,
    market_prices=market_prices,
    r=r
)
volSmile.plot()
../../_images/examples_calibration_calibration_synthetic_data_14_0.png

Local optimization#

[10]:
calibrated_params = volSmile.calibration(
    price_function=price_function,
    initial_guess = [1.0, 0.03, 0.4, -0.5],
    guess_correlation_sign='negative',
    speed='local',
)
calibrated_heston = Heston(spot=spot, r=r, **calibrated_params)
volSmile.plot(calibrated_prices=heston.call_price(strike=strikes, time_to_maturity=time_to_maturity))
calibrated_params
Calibrated parameters: v0=0.047 | kappa=1.637 | theta=0.078 | sigma=0.813 | rho=-0.505

../../_images/examples_calibration_calibration_synthetic_data_16_1.png
[10]:
{'vol_initial': np.float64(0.04748090898419823),
 'kappa': np.float64(1.6367968439862783),
 'theta': np.float64(0.07784948797483981),
 'sigma': np.float64(0.8134296600989249),
 'rho': np.float64(-0.5052904061780317),
 'drift_emm': 0}

Global optimization#

[11]:
calibrated_params = volSmile.calibration(
    price_function=price_function,
    initial_guess = [1.0, 0.03, 0.4, -0.5],
    guess_correlation_sign='negative',
    speed='global',
)
calibrated_heston = Heston(spot=spot, r=r, **calibrated_params)
volSmile.plot(calibrated_prices=heston.call_price(strike=strikes, time_to_maturity=time_to_maturity))
calibrated_params
at minimum 0.031536 accepted 1
Parameters: kappa=1.637 | theta=0.078 | sigma=0.813 | rho=-0.505

at minimum 0.035471 accepted 1
Parameters: kappa=0.011 | theta=2.569 | sigma=0.425 | rho=-0.525

at minimum 0.035471 accepted 1
Parameters: kappa=0.011 | theta=2.564 | sigma=0.425 | rho=-0.525

at minimum 0.035472 accepted 1
Parameters: kappa=0.010 | theta=2.618 | sigma=0.425 | rho=-0.525

['success condition satisfied'] True
Calibrated parameters: v0=0.047 | kappa=1.637 | theta=0.078 | sigma=0.813 | rho=-0.505

../../_images/examples_calibration_calibration_synthetic_data_18_1.png
[11]:
{'vol_initial': np.float64(0.04748090898419823),
 'kappa': np.float64(1.6367968439862783),
 'theta': np.float64(0.07784948797483981),
 'sigma': np.float64(0.8134296600989249),
 'rho': np.float64(-0.5052904061780317),
 'drift_emm': 0}