File: implied_volatility.py

package info (click to toggle)
quantlib-python 0.2.1.cvs20020322-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 2,040 kB
  • ctags: 3,245
  • sloc: cpp: 32,997; python: 7,156; makefile: 70
file content (116 lines) | stat: -rwxr-xr-x 5,072 bytes parent folder | download
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)