Coverage Report

Created: 2025-08-28 06:30

/src/quantlib/ql/termstructures/volatility/equityfx/blackvoltermstructure.hpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2002, 2003 Ferdinando Ametrano
5
 Copyright (C) 2003, 2004, 2005, 2006 StatPro Italia srl
6
7
 This file is part of QuantLib, a free-software/open-source library
8
 for financial quantitative analysts and developers - http://quantlib.org/
9
10
 QuantLib is free software: you can redistribute it and/or modify it
11
 under the terms of the QuantLib license.  You should have received a
12
 copy of the license along with this program; if not, please email
13
 <quantlib-dev@lists.sf.net>. The license is also available online at
14
 <http://quantlib.org/license.shtml>.
15
16
 This program is distributed in the hope that it will be useful, but WITHOUT
17
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 FOR A PARTICULAR PURPOSE.  See the license for more details.
19
*/
20
21
/*! \file blackvoltermstructure.hpp
22
    \brief Black volatility term structure base classes
23
*/
24
25
#ifndef quantlib_black_vol_term_structures_hpp
26
#define quantlib_black_vol_term_structures_hpp
27
28
#include <ql/termstructures/voltermstructure.hpp>
29
#include <ql/patterns/visitor.hpp>
30
31
namespace QuantLib {
32
33
    //! Black-volatility term structure
34
    /*! This abstract class defines the interface of concrete
35
        Black-volatility term structures which will be derived from
36
        this one.
37
38
        Volatilities are assumed to be expressed on an annual basis.
39
    */
40
    class BlackVolTermStructure : public VolatilityTermStructure {
41
      public:
42
        /*! \name Constructors
43
            See the TermStructure documentation for issues regarding
44
            constructors.
45
        */
46
        //@{
47
        //! default constructor
48
        /*! \warning term structures initialized by means of this
49
                     constructor must manage their own reference date
50
                     by overriding the referenceDate() method.
51
        */
52
        BlackVolTermStructure(BusinessDayConvention bdc = Following,
53
                              const DayCounter& dc = DayCounter());
54
        //! initialize with a fixed reference date
55
        BlackVolTermStructure(const Date& referenceDate,
56
                              const Calendar& cal = Calendar(),
57
                              BusinessDayConvention bdc = Following,
58
                              const DayCounter& dc = DayCounter());
59
        //! calculate the reference date based on the global evaluation date
60
        BlackVolTermStructure(Natural settlementDays,
61
                              const Calendar&,
62
                              BusinessDayConvention bdc = Following,
63
                              const DayCounter& dc = DayCounter());
64
        //@}
65
1.02k
        ~BlackVolTermStructure() override = default;
66
        //! \name Black Volatility
67
        //@{
68
        //! spot volatility
69
        Volatility blackVol(const Date& maturity,
70
                            Real strike,
71
                            bool extrapolate = false) const;
72
        //! spot volatility
73
        Volatility blackVol(Time maturity,
74
                            Real strike,
75
                            bool extrapolate = false) const;
76
        //! spot variance
77
        Real blackVariance(const Date& maturity,
78
                           Real strike,
79
                           bool extrapolate = false) const;
80
        //! spot variance
81
        Real blackVariance(Time maturity,
82
                           Real strike,
83
                           bool extrapolate = false) const;
84
        //! forward (at-the-money) volatility
85
        Volatility blackForwardVol(const Date& date1,
86
                                   const Date& date2,
87
                                   Real strike,
88
                                   bool extrapolate = false) const;
89
        //! forward (at-the-money) volatility
90
        Volatility blackForwardVol(Time time1,
91
                                   Time time2,
92
                                   Real strike,
93
                                   bool extrapolate = false) const;
94
        //! forward (at-the-money) variance
95
        Real blackForwardVariance(const Date& date1,
96
                                  const Date& date2,
97
                                  Real strike,
98
                                  bool extrapolate = false) const;
99
        //! forward (at-the-money) variance
100
        Real blackForwardVariance(Time time1,
101
                                  Time time2,
102
                                  Real strike,
103
                                  bool extrapolate = false) const;
104
        //@}
105
        //! \name Visitability
106
        //@{
107
        virtual void accept(AcyclicVisitor&);
108
        //@}
109
      protected:
110
        /*! \name Calculations
111
112
            These methods must be implemented in derived classes to perform
113
            the actual volatility calculations. When they are called,
114
            range check has already been performed; therefore, they must
115
            assume that extrapolation is required.
116
        */
117
        //@{
118
        //! Black variance calculation
119
        virtual Real blackVarianceImpl(Time t, Real strike) const = 0;
120
        //! Black volatility calculation
121
        virtual Volatility blackVolImpl(Time t, Real strike) const = 0;
122
        //@}
123
    };
124
125
    //! Black-volatility term structure
126
    /*! This abstract class acts as an adapter to BlackVolTermStructure
127
        allowing the programmer to implement only the
128
        <tt>blackVolImpl(Time, Real, bool)</tt> method in derived classes.
129
130
        Volatility are assumed to be expressed on an annual basis.
131
    */
132
    class BlackVolatilityTermStructure : public BlackVolTermStructure {
133
      public:
134
        /*! \name Constructors
135
            See the TermStructure documentation for issues regarding
136
            constructors.
137
        */
138
        //@{
139
        //! default constructor
140
        /*! \warning term structures initialized by means of this
141
                     constructor must manage their own reference date
142
                     by overriding the referenceDate() method.
143
        */
144
        BlackVolatilityTermStructure(BusinessDayConvention bdc = Following,
145
                                     const DayCounter& dc = DayCounter());
146
        //! initialize with a fixed reference date
147
        BlackVolatilityTermStructure(const Date& referenceDate,
148
                                     const Calendar& cal = Calendar(),
149
                                     BusinessDayConvention bdc = Following,
150
                                     const DayCounter& dc = DayCounter());
151
        //! calculate the reference date based on the global evaluation date
152
        BlackVolatilityTermStructure(Natural settlementDays,
153
                                     const Calendar& cal,
154
                                     BusinessDayConvention bdc = Following,
155
                                     const DayCounter& dc = DayCounter());
156
        //@}
157
        //! \name Visitability
158
        //@{
159
        void accept(AcyclicVisitor&) override;
160
        //@}
161
      protected:
162
        /*! Returns the variance for the given strike and date calculating it
163
            from the volatility.
164
        */
165
        Real blackVarianceImpl(Time maturity, Real strike) const override;
166
    };
167
168
169
    //! Black variance term structure
170
    /*! This abstract class acts as an adapter to VolTermStructure allowing
171
        the programmer to implement only the
172
        <tt>blackVarianceImpl(Time, Real, bool)</tt> method in derived
173
        classes.
174
175
        Volatility are assumed to be expressed on an annual basis.
176
    */
177
    class BlackVarianceTermStructure : public BlackVolTermStructure {
178
      public:
179
        /*! \name Constructors
180
            See the TermStructure documentation for issues regarding
181
            constructors.
182
        */
183
        //@{
184
        //! default constructor
185
        /*! \warning term structures initialized by means of this
186
                     constructor must manage their own reference date
187
                     by overriding the referenceDate() method.
188
        */
189
        BlackVarianceTermStructure(BusinessDayConvention bdc = Following,
190
                                   const DayCounter& dc = DayCounter());
191
        //! initialize with a fixed reference date
192
        BlackVarianceTermStructure(const Date& referenceDate,
193
                                   const Calendar& cal = Calendar(),
194
                                   BusinessDayConvention bdc = Following,
195
                                   const DayCounter& dc = DayCounter());
196
        //! calculate the reference date based on the global evaluation date
197
        BlackVarianceTermStructure(Natural settlementDays,
198
                                   const Calendar&,
199
                                   BusinessDayConvention bdc = Following,
200
                                   const DayCounter& dc = DayCounter());
201
        //@}
202
        //! \name Visitability
203
        //@{
204
        void accept(AcyclicVisitor&) override;
205
        //@}
206
      protected:
207
        /*! Returns the volatility for the given strike and date calculating it
208
            from the variance.
209
        */
210
        Volatility blackVolImpl(Time t, Real strike) const override;
211
    };
212
213
214
215
    // inline definitions
216
217
    inline Volatility BlackVolTermStructure::blackVol(const Date& d,
218
                                                      Real strike,
219
0
                                                      bool extrapolate) const {
220
0
        checkRange(d, extrapolate);
221
0
        checkStrike(strike, extrapolate);
222
0
        Time t = timeFromReference(d);
223
0
        return blackVolImpl(t, strike);
224
0
    }
225
226
    inline Volatility BlackVolTermStructure::blackVol(Time t,
227
                                                      Real strike,
228
0
                                                      bool extrapolate) const {
229
0
        checkRange(t, extrapolate);
230
0
        checkStrike(strike, extrapolate);
231
0
        return blackVolImpl(t, strike);
232
0
    }
233
234
    inline Real BlackVolTermStructure::blackVariance(const Date& d,
235
                                                     Real strike,
236
0
                                                     bool extrapolate) const {
237
0
        checkRange(d, extrapolate);
238
0
        checkStrike(strike, extrapolate);
239
0
        Time t = timeFromReference(d);
240
0
        return blackVarianceImpl(t, strike);
241
0
    }
242
243
    inline Real BlackVolTermStructure::blackVariance(Time t,
244
                                                     Real strike,
245
0
                                                     bool extrapolate) const {
246
0
        checkRange(t, extrapolate);
247
0
        checkStrike(strike, extrapolate);
248
0
        return blackVarianceImpl(t, strike);
249
0
    }
250
251
0
    inline void BlackVolTermStructure::accept(AcyclicVisitor& v) {
252
0
        auto* v1 = dynamic_cast<Visitor<BlackVolTermStructure>*>(&v);
253
0
        if (v1 != nullptr)
254
0
            v1->visit(*this);
255
0
        else
256
0
            QL_FAIL("not a Black-volatility term structure visitor");
257
0
    }
258
259
    inline
260
    Real BlackVolatilityTermStructure::blackVarianceImpl(Time t,
261
0
                                                         Real strike) const {
262
0
        Volatility vol = blackVolImpl(t, strike);
263
0
        return vol*vol*t;
264
0
    }
265
266
0
    inline void BlackVolatilityTermStructure::accept(AcyclicVisitor& v) {
267
0
        auto* v1 = dynamic_cast<Visitor<BlackVolatilityTermStructure>*>(&v);
268
0
        if (v1 != nullptr)
269
0
            v1->visit(*this);
270
0
        else
271
0
            BlackVolTermStructure::accept(v);
272
0
    }
273
274
    inline
275
    Volatility BlackVarianceTermStructure ::blackVolImpl(Time t,
276
0
                                                         Real strike) const {
277
0
        Time nonZeroMaturity = (t==0.0 ? 0.00001 : t);
278
0
        Real var = blackVarianceImpl(nonZeroMaturity, strike);
279
0
        return std::sqrt(var/nonZeroMaturity);
280
0
    }
281
282
0
    inline void BlackVarianceTermStructure::accept(AcyclicVisitor& v) {
283
0
        auto* v1 = dynamic_cast<Visitor<BlackVarianceTermStructure>*>(&v);
284
0
        if (v1 != nullptr)
285
0
            v1->visit(*this);
286
0
        else
287
0
            BlackVolTermStructure::accept(v);
288
0
    }
289
290
}
291
292
#endif