0
$\begingroup$

I am trying to fit a time dependent Heston model using Quantlib Python. I'm getting the following runtime error: Boost assertion failed : px !=0.

Can somebody help in this or is there an example of time dependent heston ?


import numpy as np
#% matplotlib inline
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from scipy.optimize import root
from scipy.optimize import root, least_squares, differential_evolution, basinhopping
from pandas import DataFrame

day_count = ql.Actual365Fixed()
calendar = ql.UnitedStates()

calculation_date = ql.Date(7, 6, 2023)

spot = 4271.21

ql.Settings.instance().evaluationDate = calculation_date

dividend_yield = ql.QuoteHandle(ql.SimpleQuote(0.0))
risk_free_rate = 0.0553
dividend_rate = 0.01283
flat_ts = ql.YieldTermStructureHandle(
    ql.FlatForward(calculation_date, risk_free_rate, day_count))

yield_ts = ql.YieldTermStructureHandle(
     ql.FlatForward(calculation_date, risk_free_rate, day_count))
dividend_ts = ql.YieldTermStructureHandle(
    ql.FlatForward(calculation_date, dividend_rate, day_count))

expiration_dates = [ql.Date(7,7,2023),  ql.Date(7,9,2023),
                     ql.Date(7,12,2023), ql.Date(7,6,2024)]
ttm=[ql.Period(m-calculation_date, ql.Days) for m in expiration_dates]
strikes = [3844.09, 4057.65, 4164.43, 4271.21, 4377.99, 4484.77, 4698.33]

data = [
[ 0.22004, 0.16338, 0.13716, 0.11289 ,0.10017, 0.10047, 0.13063 ],
#[, 0.20691, 0.16693, 0.14635, 0.12616 ,0.11087, 0.10298, 0.10272 ,0.17100],
[ 0.20358, 0.16993, 0.15206, 0.13394 ,0.11860, 0.10861, 0.10283 ],
[ 0.20554, 0.18071, 0.16752, 0.15401 ,0.14106, 0.12976, 0.11482 ],
#[0.24909, 0.20919, 0.18866, 0.17759, 0.16614 ,0.15474, 0.14404, 0.12691 ,0.11426],
[ 0.21129, 0.19361, 0.18420, 0.17443 ,0.16453, 0.15487, 0.13788 ]]


implied_vols = ql.Matrix(len(strikes), len(expiration_dates))
for i in range(implied_vols.rows()):
    for j in range(implied_vols.columns()):
        implied_vols[i][j] = data[j][i]
        
        black_var_surface = ql.BlackVarianceSurface(
    calculation_date, calendar, 
    expiration_dates, strikes, 
    implied_vols, day_count)
        
strike = 4300
expiry = 0.6 # years
black_var_surface.blackVol(expiry, strike)


v0 = 0.02; kappa = 3; theta = 0.02; rho = -0.8; sigma = 2;
times = [0.0833,0.25,0.5,1]

for i, time in enumerate(times):
    kappaTS.setParam(i, kappa[i])
#thetaTS.setParam(i, theta[i])
#rhoTS.setParam(i, rho[i])
#sigmaTS.setParam(i, sigma[i])

grid = ql.TimeGrid(times)

# process = ql.HestonProcess(flat_ts, dividend_ts, 
#                             ql.QuoteHandle(ql.SimpleQuote(spot)), 
#                             v0, kappa, theta, sigma, rho,grid)
model = ql.PiecewiseTimeDependentHestonModel(flat_ts, dividend_ts, 
                          ql.QuoteHandle(ql.SimpleQuote(spot)), 
                             v0, ql.Parameter(),ql.Parameter(),
                                                   ql.Parameter(), ql.Parameter(),grid)
engine = ql.AnalyticPTDHestonEngine(model) 
# engine = ql.FdHestonVanillaEngine(model)


heston_helpers = []
black_var_surface.setInterpolation("bicubic")



for i, date in enumerate(expiration_dates):
    for j, s in enumerate(strikes):
        t = (date - calculation_date )
        p = ql.Period(t, ql.Days)
        sigma = data[i][j]
        #sigma = black_var_surface.blackVol(t/365.25, s)
        helper = ql.HestonModelHelper(p, calendar, spot, s, 
                                      ql.QuoteHandle(ql.SimpleQuote(sigma)),
                                      flat_ts, 
                                      dividend_ts)
        helper.setPricingEngine(engine)
        heston_helpers.append(helper)


lm = ql.LevenbergMarquardt(1e-8, 1e-8, 1e-8)
#model.calibrate(heston_helpers, lm,
 #                ql.EndCriteria(500, 50, 1.0e-8,1.0e-8, 1.0e-8))
# theta, kappa, sigma, rho, v0 = model.params()
model.calibrate(heston_helpers, lm, ql.EndCriteria(500, 300, 1.0e-8, 1.0e-8, 1.0e-8))


$\endgroup$

1 Answer 1

1
$\begingroup$

I would guess that the problem is passing empty ql.Parameter instances (we should probably disable that constructor from Python). I would create actual parameters, as for instance in this test.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.