Estoy tratando de calibrar un modelo Heston y una opción de precio vainilla utilizando Quantlib 1.15 y Python 2.7. Utilizo el siguiente código
import QuantLib as ql
#=====INITIALIZE INPUTS
day_count = ql.Actual365Fixed()
calendar = ql.TARGET()
calculation_date = ql.Date(2,1,2018)
ql.Settings.instance().evaluationDate = calculation_date
spot = 100.
dividend_yield = ql.QuoteHandle(ql.SimpleQuote(0.0))
risk_free_rate = 0.0
dividend_rate = 0.0
flat_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(2,1,2019)
strikes = [ 80, 90, 95, 97.5, 100, 102.5, 105, 110, 120 ]
data = [ 0.199634, 0.17565, 0.165468, 0.160864, 0.156803, 0.152733, 0.148948, 0.142499, 0.133428 ]
#=====CALIBRATE HESTON
v0 = 0.01; kappa = 0.2; theta = 0.02; rho = -0.75; sigma = 0.5;
process = ql.HestonProcess(flat_ts, dividend_ts,
ql.QuoteHandle(ql.SimpleQuote(spot)),
v0, kappa, theta, sigma, rho)
model = ql.HestonModel(process)
engine = ql.AnalyticHestonEngine(model, 0.0001, 1000)
date = expiration_dates
heston_helpers = []
for j, s in enumerate(strikes):
t = (date - calculation_date )
p = ql.Period(t, ql.Days)
sigma_implied = data[j]
helper = ql.HestonModelHelper(p, calendar, spot, s,
ql.QuoteHandle(ql.SimpleQuote(sigma_implied)),
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))
v0 = model.v0(); rho = model.rho(); kappa = model.kappa(); theta = model.theta(); sigma = model.sigma();
#=====PRICING
payoff = ql.PlainVanillaPayoff(ql.Option.Put, 97.5)
exercise = ql.EuropeanExercise(date)
european_option = ql.VanillaOption(payoff, exercise)
european_option.setPricingEngine(engine)
print "Price using VanillaOption = %2.4f" %european_option.NPV()
print "Price using HestonModelHelper = %2.4f" %heston_helpers[3].modelValue()
El resultado impreso es :
Precio con VanillaOption = 5,7024
Precio con HestonModelHelper = 6,4268
No entiendo por qué european_option.NPV() y heston_helpers[3].modelValue() proporcionan valores diferentes aunque utilice los mismos parámetros.
Gracias de antemano por su ayuda