1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
"""
Copyright (C) 2019 Klaus Spanderen
This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/
QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev@lists.sf.net>. The license is also available online at
<https://www.quantlib.org/license.shtml>.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
"""
import unittest
import QuantLib as ql
class AmericanQuantoOptionTest(unittest.TestCase):
def setUp(self):
self.today = ql.Date(21, ql.April, 2019)
self.dc = ql.Actual365Fixed()
ql.Settings.instance().evaluationDate = self.today
self.domesticTS = ql.FlatForward(self.today, 0.025, self.dc)
self.foreignTS = ql.FlatForward(self.today, 0.075, self.dc)
self.fxVolTS = ql.BlackConstantVol(self.today, ql.TARGET(), 0.15, self.dc)
self.quantoHelper = ql.FdmQuantoHelper(
self.domesticTS, self.foreignTS, self.fxVolTS, -0.75, 1.0)
self.divYieldTS = ql.FlatForward(self.today, 0.03, self.dc)
self.dividends = [ql.FixedDividend(8.0, self.today + ql.Period(6, ql.Months))]
maturityDate = self.today + ql.Period(9, ql.Months)
self.option = ql.VanillaOption(
ql.PlainVanillaPayoff(ql.Option.Call, 105),
ql.AmericanExercise(self.today, maturityDate))
def tearDown(self):
ql.Settings.instance().evaluationDate = ql.Date()
def testAmericanBSQuantoOption(self):
""" Testing American Black-Scholes quanto option """
volTS = ql.BlackConstantVol(self.today, ql.TARGET(), 0.3, self.dc)
bsmProcess = ql.BlackScholesMertonProcess(
ql.makeQuoteHandle(100),
ql.YieldTermStructureHandle(self.divYieldTS),
ql.YieldTermStructureHandle(self.domesticTS),
ql.BlackVolTermStructureHandle(volTS))
fdmBlackScholesEngine = ql.FdBlackScholesVanillaEngine(
bsmProcess, self.dividends, self.quantoHelper, 100, 400, 1)
self.option.setPricingEngine(fdmBlackScholesEngine)
fdmPrice = self.option.NPV()
expected = 8.90611734
self.assertAlmostEqual(fdmPrice, expected, 3,
msg="Unable to reproduce American BS quanto option price.")
def testAmericanHestonQuantoOption(self):
""" Testing American Heston quanto option """
hestonModel = ql.HestonModel(
ql.HestonProcess(
ql.YieldTermStructureHandle(self.domesticTS),
ql.YieldTermStructureHandle(self.divYieldTS),
ql.makeQuoteHandle(100),
0.09, 1.0, 0.09, 1e-4, 0.0))
fdmHestonVanillaEngine = ql.FdHestonVanillaEngine(
hestonModel, self.dividends, self.quantoHelper, 100, 400, 3, 1)
self.option.setPricingEngine(fdmHestonVanillaEngine)
fdmPrice = self.option.NPV()
expected = 8.90611734
self.assertAlmostEqual(fdmPrice, expected, 3,
msg="Unable to reproduce American Heston quanto option price.")
if __name__ == '__main__':
print("testing QuantLib", ql.__version__)
unittest.main(verbosity=2)
|