Skip to content

Commit 482fb7b

Browse files
committed
more tests
1 parent f587197 commit 482fb7b

File tree

1 file changed

+60
-16
lines changed

1 file changed

+60
-16
lines changed

test/test_hybridhestonhullwhite_process.py

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
from __future__ import division
2-
from __future__ import print_function
3-
41
import unittest
52

63
import numpy as np
@@ -15,12 +12,14 @@
1512
from quantlib.instruments.vanillaoption import VanillaOption
1613

1714
from quantlib.time.api import (today, Years, Actual365Fixed,
18-
Period, May, Date,
15+
Period, May, Date, Actual360,
1916
NullCalendar)
2017

2118
from quantlib.processes.api import (BlackScholesMertonProcess,
2219
HestonProcess,
23-
HullWhiteProcess)
20+
HullWhiteProcess,
21+
HullWhiteForwardProcess,
22+
HybridHestonHullWhiteProcess)
2423

2524
from quantlib.models.equity.heston_model import (
2625
HestonModel)
@@ -33,7 +32,8 @@
3332
AnalyticBSMHullWhiteEngine,
3433
AnalyticHestonEngine,
3534
AnalyticHestonHullWhiteEngine,
36-
FdHestonHullWhiteVanillaEngine)
35+
FdHestonHullWhiteVanillaEngine,
36+
MCHestonHullWhiteEngine)
3737

3838
from quantlib.quotes import SimpleQuote
3939

@@ -43,6 +43,7 @@
4343

4444
from .utilities import flat_rate
4545

46+
from math import sin, exp
4647

4748
class HybridHestonHullWhiteProcessTestCase(unittest.TestCase):
4849

@@ -95,8 +96,8 @@ def setUp(self):
9596
self.dates = dates
9697

9798
def test_bsm_hw(self):
98-
print("Testing European option pricing for a BSM process" +
99-
" with one-factor Hull-White model...")
99+
"""Testing European option pricing for a BSM process
100+
with one-factor Hull-White model"""
100101

101102
dc = Actual365Fixed()
102103
todays_date = today()
@@ -247,12 +248,8 @@ def test_compare_bsm_bsmhw_hestonhw(self):
247248
self.assertAlmostEqual(npv_bsm, npv_hestonhw, delta=tol)
248249

249250
def test_compare_BsmHW_HestonHW(self):
250-
"""
251-
From Quantlib test suite
252-
"""
253-
254-
print("Comparing European option pricing for a BSM " +
255-
"process with one-factor Hull-White model...")
251+
"""Comparing European option pricing for a BSM
252+
process with one-factor Hull-White model"""
256253

257254
dc = Actual365Fixed()
258255

@@ -355,8 +352,8 @@ def test_zanette(self):
355352
# constant yield and div curves
356353

357354
dates = [todays_date + Period(i, Years) for i in range(3)]
358-
rates = [0.04 for i in range(3)]
359-
divRates = [0.03 for i in range(3)]
355+
rates = [0.04] * 3
356+
divRates = [0.03] * 3
360357
r_ts = HandleYieldTermStructure(ZeroCurve(dates, rates, dc))
361358
q_ts = HandleYieldTermStructure(ZeroCurve(dates, divRates, dc))
362359

@@ -420,3 +417,50 @@ def price_cal(rho, tGrid):
420417
expected_price = [11.38, ] * 4 + [12.79, ] * 4 + [14.06, ] * 4
421418

422419
np.testing.assert_almost_equal(calc_price, expected_price, 2)
420+
421+
def test_mc_vanilla_pricing(self):
422+
"""Testing Monte-Carlo vanilla option pricing"""
423+
dc = Actual360()
424+
todays_date = today()
425+
settings = Settings()
426+
settings.evaluation_date = todays_date
427+
dates = [todays_date + Period(i, Years) for i in range(41)]
428+
rates = [0.03 + 0.0003 * exp(sin(i / 4.0)) for i in range(41)]
429+
div_rates = [0.02 + 0.0001 * exp(sin(i / 5.0)) for i in range(41)]
430+
maturity = todays_date + Period(20, Years)
431+
432+
s0 = SimpleQuote(100)
433+
r_ts = HandleYieldTermStructure(ZeroCurve(dates, rates, dc))
434+
q_ts = HandleYieldTermStructure(ZeroCurve(dates, div_rates, dc))
435+
vol = SimpleQuote(0.25)
436+
vol_ts = BlackConstantVol(todays_date, NullCalendar(), vol, dc)
437+
bsm_process= BlackScholesMertonProcess(s0, q_ts, r_ts, vol_ts)
438+
heston_process = HestonProcess(r_ts, q_ts, s0, 0.0625, 0.5, 0.0625, 1e-5, 0.3)
439+
hw_process = HullWhiteForwardProcess(r_ts, 0.01, 0.01)
440+
hw_process.forward_measure_time = dc.year_fraction(todays_date, maturity)
441+
442+
tol = 0.05
443+
corr = [-0.9, -0.5, 0.0, 0.5, 0.9]
444+
strike = [100.0]
445+
exercise = EuropeanExercise(maturity)
446+
for rho in corr:
447+
for s in strike:
448+
joint_process = HybridHestonHullWhiteProcess(heston_process, hw_process, rho)
449+
payoff = PlainVanillaPayoff(OptionType.Put, s)
450+
option_heston_hw = VanillaOption(payoff, exercise)
451+
engine = MCHestonHullWhiteEngine(joint_process,
452+
time_steps=1,
453+
required_tolerance=tol,
454+
seed=42)
455+
option_heston_hw.set_pricing_engine(engine)
456+
hw_model = HullWhite(r_ts, hw_process.a, hw_process.sigma)
457+
option_BsmHW = VanillaOption(payoff, exercise)
458+
option_BsmHW.set_pricing_engine(AnalyticBSMHullWhiteEngine(rho, bsm_process, hw_model))
459+
calculated = option_heston_hw.npv
460+
error = option_heston_hw.error_estimate
461+
expected = option_BsmHW.npv
462+
print(abs(calculated - expected), error)
463+
if rho == 0:
464+
self.assertTrue(abs(calculated - expected) < tol)
465+
else:
466+
self.assertTrue(abs(calculated - expected) < 1.2 * error)

0 commit comments

Comments
 (0)