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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#!/usr/bin/python
"""
Copyright (C) 2000, 2001, 2002 RiskMap srl
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 ferdinando@ametrano.net
The license is also available online at http://quantlib.org/html/license.html
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.
"""
__version__ = "$Revision: 1.16 $"
# $Source: /cvsroot/quantlib/QuantLib-Python/QuantLib/test/implied_volatility.py,v $
import QuantLib
from QuantLib import Date, DayCounter, Calendar
from QuantLib import PlainOption, EuropeanEngine
from QuantLib import MarketElementHandle, SimpleMarketElement
from QuantLib import TermStructureHandle, FlatForward
import unittest
from math import exp
def relErr(x1, x2, reference):
if reference != 0.0:
return abs(x1-x2)/reference
else:
return 10e10
def pricer(type,underlying,strike,divCurve,rfCurve,exDate,volatility):
return PlainOption(type,underlying,strike,divCurve,rfCurve,
exDate,volatility,EuropeanEngine())
class ImpliedVolatilityTest(unittest.TestCase):
def runTest(self):
"Testing implied volatility calculation"
maxEval = 100
tol = 1e-6
for Qrate in [0.01, 0.05, 0.10]:
divCurve = TermStructureHandle(FlatForward('EUR',
DayCounter('act/360'), Date(12,10,2001),
Calendar('TARGET'), 2, Qrate))
for Rrate in [0.01, 0.05, 0.10]:
rfCurve = TermStructureHandle(FlatForward('EUR',
DayCounter('act/360'), Date(12,10,2001),
Calendar('TARGET'), 2, Rrate))
for vol in [0.01, 0.2, 0.3, 0.7, 0.9]:
volatility = MarketElementHandle(SimpleMarketElement(vol))
for under in [80, 95, 99.9, 100, 100.1, 105, 120]:
underlying = MarketElementHandle(SimpleMarketElement(under))
for days in [1,36,180,360,1080]:
exDate = Date(16,10,2001) + days
for strike in [50, 99.5, 100, 100.5, 150]:
for type in ['Call','Put','Straddle']:
bsm = pricer(type,underlying,strike,
divCurve,rfCurve,exDate,volatility)
bsmValue = bsm.NPV()
if bsmValue == 0.0:
continue
for dVol in [0.5, 0.999, 1.0, 1.001, 1.5]:
volatility2 = MarketElementHandle(
SimpleMarketElement(vol*dVol))
bsm2 = pricer(type,underlying,strike,
divCurve,rfCurve,exDate,volatility2)
try:
implVol = bsm2.impliedVolatility(bsmValue, tol,
maxEval)
except Exception, e:
vol2 = vol+dVol
value2 = bsm2.NPV()
raise """
%(e)s
Option details: %(type)s %(under)f %(strike)f %(qRate)f %(rRate)f %(days)d
volatility: %(vol2)18.16f
option value: %(value2)20.12e
while trying to calculate implied vol from value %(bsmValue)20.12e
""" % locals()
if abs(implVol-vol) > tol:
volatility3 = MarketElementHandle(
SimpleMarketElement(vol*dVol))
bsm3 = pricer(type,underlying,strike,
divCurve,rfCurve,exDate,volatility3)
bsm3Value = bsm3.NPV()
if not (abs(bsm3Value-bsmValue)/under<=1.0e-3):
vol3 = vol*dVol
value3 = bsm2.NPV()
self.fail("""
Option details: %(type)s %(under)f %(strike)f %(qRate)f %(rRate)f %(days)d
at %(vol)18.16f vol the option value is %(bsmValue)20.12e
at %(vol3)18.16f vol the option value is %(value3)20.12e
at %(bsmValue)20.12e value the implied vol is %(implVol)20.16f
the error is %(err)10.2e (tolerance is %(tol)10.2e)
at %(implVol)18.16f vol the option value is %(bsm3Value)20.12e
""" % locals())
if __name__ == '__main__':
print 'testing QuantLib', QuantLib.__version__, QuantLib.QuantLibc.__file__, QuantLib.__file__
import sys
suite = unittest.TestSuite()
suite.addTest(ImpliedVolatilityTest())
if sys.hexversion >= 0x020100f0:
unittest.TextTestRunner(verbosity=2).run(suite)
else:
unittest.TextTestRunner().run(suite)
|