• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lballabio / QuantLib / 25787959715

13 May 2026 08:35AM UTC coverage: 74.571% (+0.005%) from 74.566%
25787959715

push

github

web-flow
Add `smileSection(...)` methods to `BlackVolTermStructure` (#2487)

22 of 26 new or added lines in 4 files covered. (84.62%)

1 existing line in 1 file now uncovered.

58610 of 78596 relevant lines covered (74.57%)

8659213.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.89
/ql/termstructures/volatility/equityfx/blackvoltermstructure.cpp
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) 2026 Yassine Idyiahia
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
 <https://www.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
#include <ql/termstructures/volatility/equityfx/blackvoltermstructure.hpp>
22
#include <ql/termstructures/volatility/smilesection.hpp>
23

24
namespace QuantLib {
25

26
    namespace {
27

28
        class BlackVolSmileSectionAdapter : public SmileSection {
29
          public:
30
            BlackVolSmileSectionAdapter(
3✔
31
                ext::shared_ptr<const BlackVolTermStructure> vol,
32
                Time t)
33
            : SmileSection(t, vol->dayCounter()), vol_(std::move(vol)) {}
6✔
NEW
34
            Real minStrike() const override { return vol_->minStrike(); }
×
NEW
35
            Real maxStrike() const override { return vol_->maxStrike(); }
×
36
            Real atmLevel() const override {
2✔
37
                return vol_->atmLevel(exerciseTime());
2✔
38
            }
39
          protected:
40
            Volatility volatilityImpl(Rate strike) const override {
10✔
41
                return vol_->blackVol(exerciseTime(), strike, true);
10✔
42
            }
43
          private:
44
            ext::shared_ptr<const BlackVolTermStructure> vol_;
45
        };
46

47
    }
48

49
    BlackVolTermStructure::BlackVolTermStructure(BusinessDayConvention bdc,
20✔
50
                                                 const DayCounter& dc)
×
51
    : VolatilityTermStructure(bdc, dc) {}
20✔
52

53
    BlackVolTermStructure::BlackVolTermStructure(const Date& refDate,
355,212✔
54
                                                 const Calendar& cal,
55
                                                 BusinessDayConvention bdc,
56
                                                 const DayCounter& dc)
×
57
    : VolatilityTermStructure(refDate, cal, bdc, dc) {}
355,212✔
58

59
    BlackVolTermStructure::BlackVolTermStructure(Natural settlDays,
257✔
60
                                                 const Calendar& cal,
61
                                                 BusinessDayConvention bdc,
62
                                                 const DayCounter& dc)
×
63
    : VolatilityTermStructure(settlDays, cal, bdc, dc) {}
257✔
64

65
    Volatility BlackVolTermStructure::blackForwardVol(const Date& date1,
×
66
                                                      const Date& date2,
67
                                                      Real strike,
68
                                                      bool extrapolate) const {
69
        // (redundant) date-based checks
70
        QL_REQUIRE(date1 <= date2,
×
71
                   date1 << " later than " << date2);
72
        checkRange(date2, extrapolate);
×
73

74
        // using the time implementation
75
        Time time1 = timeFromReference(date1);
×
76
        Time time2 = timeFromReference(date2);
×
77
        return blackForwardVol(time1, time2, strike, extrapolate);
×
78
    }
79

80
    Volatility BlackVolTermStructure::blackForwardVol(Time time1,
8,589,359✔
81
                                                      Time time2,
82
                                                      Real strike,
83
                                                      bool extrapolate) const {
84
        QL_REQUIRE(time1 <= time2,
8,589,359✔
85
                   time1 << " later than " << time2);
86
        checkRange(time2, extrapolate);
8,589,359✔
87
        checkStrike(strike, extrapolate);
8,589,359✔
88
        if (time2==time1) {
8,589,359✔
89
            if (time1==0.0) {
159,850✔
90
                Time epsilon = 1.0e-5;
91
                Real var = blackVarianceImpl(epsilon, strike);
×
92
                return std::sqrt(var/epsilon);
×
93
            } else {
94
                Time epsilon = std::min<Time>(1.0e-5, time1);
159,850✔
95
                Real var1 = blackVarianceImpl(time1-epsilon, strike);
159,850✔
96
                Real var2 = blackVarianceImpl(time1+epsilon, strike);
159,850✔
97
                QL_ENSURE(var2>=var1,
159,850✔
98
                          "variances must be non-decreasing");
99
                return std::sqrt((var2-var1)/(2*epsilon));
159,850✔
100
            }
101
        } else {
102
            Real var1 = blackVarianceImpl(time1, strike);
8,429,509✔
103
            Real var2 = blackVarianceImpl(time2, strike);
8,429,509✔
104
            QL_ENSURE(var2 >= var1,
8,429,509✔
105
                      "variances must be non-decreasing");
106
            return std::sqrt((var2-var1)/(time2-time1));
8,429,509✔
107
        }
108
    }
109

110
    Real BlackVolTermStructure::blackForwardVariance(const Date& date1,
49,893✔
111
                                                     const Date& date2,
112
                                                     Real strike,
113
                                                     bool extrapolate)
114
                                                                      const {
115
        // (redundant) date-based checks
116
        QL_REQUIRE(date1 <= date2,
49,893✔
117
                   date1 << " later than " << date2);
118
        checkRange(date2, extrapolate);
49,893✔
119

120
        // using the time implementation
121
        Time time1 = timeFromReference(date1);
49,893✔
122
        Time time2 = timeFromReference(date2);
49,893✔
123
        return blackForwardVariance(time1, time2, strike, extrapolate);
49,893✔
124
    }
125

126
    Real BlackVolTermStructure::blackForwardVariance(Time time1,
962,886✔
127
                                                     Time time2,
128
                                                     Real strike,
129
                                                     bool extrapolate) const {
130
        QL_REQUIRE(time1 <= time2,
962,886✔
131
                   time1 << " later than " << time2);
132
        checkRange(time2, extrapolate);
962,886✔
133
        checkStrike(strike, extrapolate);
962,886✔
134
        Real v1 = blackVarianceImpl(time1, strike);
962,886✔
135
        Real v2 = blackVarianceImpl(time2, strike);
962,886✔
136
        QL_ENSURE(v2 >= v1,
962,886✔
137
                  "variances must be non-decreasing");
138
        return v2-v1;
962,886✔
139
    }
140

141
    BlackVolatilityTermStructure::BlackVolatilityTermStructure(
×
142
                                                    BusinessDayConvention bdc,
143
                                                    const DayCounter& dc)
×
144
    : BlackVolTermStructure(bdc, dc) {}
×
145

146
    BlackVolatilityTermStructure::BlackVolatilityTermStructure(
310,291✔
147
                                                    const Date& refDate,
148
                                                    const Calendar& cal,
149
                                                    BusinessDayConvention bdc,
150
                                                    const DayCounter& dc)
×
151
    : BlackVolTermStructure(refDate, cal, bdc, dc) {}
310,291✔
152

153
    BlackVolatilityTermStructure::BlackVolatilityTermStructure(
257✔
154
                                                    Natural settlementDays,
155
                                                    const Calendar& cal,
156
                                                    BusinessDayConvention bdc,
157
                                                    const DayCounter& dc)
×
158
    : BlackVolTermStructure(settlementDays, cal, bdc, dc) {}
257✔
159

160
    BlackVarianceTermStructure::BlackVarianceTermStructure(
20✔
161
                                                    BusinessDayConvention bdc,
162
                                                    const DayCounter& dc)
×
163
    : BlackVolTermStructure(bdc, dc) {}
20✔
164

165
    BlackVarianceTermStructure::BlackVarianceTermStructure(
43,569✔
166
                                                    const Date& refDate,
167
                                                    const Calendar& cal,
168
                                                    BusinessDayConvention bdc,
169
                                                    const DayCounter& dc)
×
170
    : BlackVolTermStructure(refDate, cal, bdc, dc) {}
43,569✔
171

172
    BlackVarianceTermStructure::BlackVarianceTermStructure(
×
173
                                                    Natural settlementDays,
174
                                                    const Calendar& cal,
175
                                                    BusinessDayConvention bdc,
176
                                                    const DayCounter& dc)
×
177
    : BlackVolTermStructure(settlementDays, cal, bdc, dc) {}
×
178

179
    ext::shared_ptr<SmileSection>
180
    BlackVolTermStructure::smileSectionImpl(Time t) const {
4✔
181
        try {
182
            return ext::make_shared<BlackVolSmileSectionAdapter>(
3✔
183
#ifdef QL_ENABLE_THREAD_SAFE_OBSERVER_PATTERN
184
                ext::dynamic_pointer_cast<const BlackVolTermStructure>(
185
                    shared_from_this()),
186
#else
187
                shared_from_this(),
4✔
188
#endif
189
                t);
3✔
190
        } catch (const ext::bad_weak_ptr&) {
1✔
191
            QL_FAIL("smileSection() requires the BlackVolTermStructure "
3✔
192
                    "to be held by a shared_ptr");
193
        }
1✔
194
    }
195

196
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc