Coverage Report

Created: 2026-03-11 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/termstructures/volatility/interpolatedsmilesection.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2006 Ferdinando Ametrano
5
 Copyright (C) 2006 François du Vignaud
6
 Copyright (C) 2015 Peter Caspers
7
8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10
11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <https://www.quantlib.org/license.shtml>.
16
17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21
22
/*! \file interpolatedsmilesection.hpp
23
    \brief Interpolated smile section class
24
*/
25
26
#ifndef quantlib_interpolated_smile_section_hpp
27
#define quantlib_interpolated_smile_section_hpp
28
29
#include <ql/math/interpolations/linearinterpolation.hpp>
30
#include <ql/patterns/lazyobject.hpp>
31
#include <ql/quotes/simplequote.hpp>
32
#include <ql/termstructure.hpp>
33
#include <ql/termstructures/volatility/smilesection.hpp>
34
#include <ql/time/daycounters/actual365fixed.hpp>
35
#include <utility>
36
37
namespace QuantLib {
38
39
    template<class Interpolator>
40
    class InterpolatedSmileSection : public SmileSection,
41
                                     public LazyObject {
42
      public:
43
        InterpolatedSmileSection(Time expiryTime,
44
                                 std::vector<Rate> strikes,
45
                                 const std::vector<Handle<Quote> >& stdDevHandles,
46
                                 Handle<Quote> atmLevel,
47
                                 const Interpolator& interpolator = Interpolator(),
48
                                 const DayCounter& dc = Actual365Fixed(),
49
                                 VolatilityType type = ShiftedLognormal,
50
                                 Real shift = 0.0);
51
        InterpolatedSmileSection(Time expiryTime,
52
                                 std::vector<Rate> strikes,
53
                                 const std::vector<Real>& stdDevs,
54
                                 Real atmLevel,
55
                                 const Interpolator& interpolator = Interpolator(),
56
                                 const DayCounter& dc = Actual365Fixed(),
57
                                 VolatilityType type = ShiftedLognormal,
58
                                 Real shift = 0.0);
59
        InterpolatedSmileSection(const Date& d,
60
                                 std::vector<Rate> strikes,
61
                                 const std::vector<Handle<Quote> >& stdDevHandles,
62
                                 Handle<Quote> atmLevel,
63
                                 const DayCounter& dc = Actual365Fixed(),
64
                                 const Interpolator& interpolator = Interpolator(),
65
                                 const Date& referenceDate = Date(),
66
                                 VolatilityType type = ShiftedLognormal,
67
                                 Real shift = 0.0);
68
        InterpolatedSmileSection(const Date& d,
69
                                 std::vector<Rate> strikes,
70
                                 const std::vector<Real>& stdDevs,
71
                                 Real atmLevel,
72
                                 const DayCounter& dc = Actual365Fixed(),
73
                                 const Interpolator& interpolator = Interpolator(),
74
                                 const Date& referenceDate = Date(),
75
                                 VolatilityType type = ShiftedLognormal,
76
                                 Real shift = 0.0);
77
78
        void performCalculations() const override;
79
        Real varianceImpl(Rate strike) const override;
80
        Volatility volatilityImpl(Rate strike) const override;
81
0
        Real minStrike() const override { return strikes_.front(); }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::minStrike() const
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::minStrike() const
82
0
        Real maxStrike() const override { return strikes_.back(); }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::maxStrike() const
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::maxStrike() const
83
0
        Real atmLevel() const override { return atmLevel_->value(); }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::atmLevel() const
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::atmLevel() const
84
        void update() override;
85
86
      private:
87
        Real exerciseTimeSquareRoot_;
88
        std::vector<Rate> strikes_;
89
        std::vector<Handle<Quote> > stdDevHandles_;
90
        Handle<Quote> atmLevel_;
91
        mutable std::vector<Volatility> vols_;
92
        mutable Interpolation interpolation_;
93
    };
94
95
96
    template <class Interpolator>
97
    InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection(
98
        Time timeToExpiry,
99
        std::vector<Rate> strikes,
100
        const std::vector<Handle<Quote> >& stdDevHandles,
101
        Handle<Quote> atmLevel,
102
        const Interpolator& interpolator,
103
        const DayCounter& dc,
104
        const VolatilityType type,
105
        const Real shift)
106
    : SmileSection(timeToExpiry, dc, type, shift),
107
      exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)),
108
      stdDevHandles_(stdDevHandles), atmLevel_(std::move(atmLevel)), vols_(stdDevHandles.size()) {
109
        for (auto& stdDevHandle : stdDevHandles_)
110
            LazyObject::registerWith(stdDevHandle);
111
        LazyObject::registerWith(atmLevel_);
112
        // check strikes!!!!!!!!!!!!!!!!!!!!
113
        interpolation_ = interpolator.interpolate(strikes_.begin(),
114
                                                  strikes_.end(),
115
                                                  vols_.begin());
116
    }
117
118
    template <class Interpolator>
119
    InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection(
120
        Time timeToExpiry,
121
        std::vector<Rate> strikes,
122
        const std::vector<Real>& stdDevs,
123
        Real atmLevel,
124
        const Interpolator& interpolator,
125
        const DayCounter& dc,
126
        const VolatilityType type,
127
        const Real shift)
128
0
    : SmileSection(timeToExpiry, dc, type, shift),
129
0
      exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)),
130
0
      stdDevHandles_(stdDevs.size()), vols_(stdDevs.size()) {
131
        // fill dummy handles to allow generic handle-based
132
        // computations later on
133
0
        for (Size i=0; i<stdDevs.size(); ++i)
134
0
            stdDevHandles_[i] = Handle<Quote>(ext::shared_ptr<Quote>(new
135
0
                SimpleQuote(stdDevs[i])));
136
0
        atmLevel_ = Handle<Quote>
137
0
           (ext::shared_ptr<Quote>(new SimpleQuote(atmLevel)));
138
        // check strikes!!!!!!!!!!!!!!!!!!!!
139
0
        interpolation_ = interpolator.interpolate(strikes_.begin(),
140
0
                                                  strikes_.end(),
141
0
                                                  vols_.begin());
142
0
    }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::InterpolatedSmileSection(double, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<double, std::__1::allocator<double> > const&, double, QuantLib::Cubic const&, QuantLib::DayCounter const&, QuantLib::VolatilityType, double)
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::InterpolatedSmileSection(double, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<double, std::__1::allocator<double> > const&, double, QuantLib::Linear const&, QuantLib::DayCounter const&, QuantLib::VolatilityType, double)
143
144
    template <class Interpolator>
145
    InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection(
146
        const Date& d,
147
        std::vector<Rate> strikes,
148
        const std::vector<Handle<Quote> >& stdDevHandles,
149
        Handle<Quote> atmLevel,
150
        const DayCounter& dc,
151
        const Interpolator& interpolator,
152
        const Date& referenceDate,
153
        const VolatilityType type,
154
        const Real shift)
155
    : SmileSection(d, dc, referenceDate, type, shift),
156
      exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)),
157
      stdDevHandles_(stdDevHandles), atmLevel_(std::move(atmLevel)), vols_(stdDevHandles.size()) {
158
        for (auto& stdDevHandle : stdDevHandles_)
159
            LazyObject::registerWith(stdDevHandle);
160
        LazyObject::registerWith(atmLevel_);
161
        // check strikes!!!!!!!!!!!!!!!!!!!!
162
        interpolation_ = interpolator.interpolate(strikes_.begin(),
163
                                                  strikes_.end(),
164
                                                  vols_.begin());
165
    }
166
167
    template <class Interpolator>
168
    InterpolatedSmileSection<Interpolator>::InterpolatedSmileSection(
169
        const Date& d,
170
        std::vector<Rate> strikes,
171
        const std::vector<Real>& stdDevs,
172
        Real atmLevel,
173
        const DayCounter& dc,
174
        const Interpolator& interpolator,
175
        const Date& referenceDate,
176
        const VolatilityType type,
177
        const Real shift)
178
0
    : SmileSection(d, dc, referenceDate, type, shift),
179
0
      exerciseTimeSquareRoot_(std::sqrt(exerciseTime())), strikes_(std::move(strikes)),
180
0
      stdDevHandles_(stdDevs.size()), vols_(stdDevs.size()) {
181
        //fill dummy handles to allow generic handle-based
182
        // computations later on
183
0
        for (Size i=0; i<stdDevs.size(); ++i)
184
0
            stdDevHandles_[i] = Handle<Quote>(ext::shared_ptr<Quote>(new
185
0
                SimpleQuote(stdDevs[i])));
186
0
        atmLevel_ = Handle<Quote>
187
0
           (ext::shared_ptr<Quote>(new SimpleQuote(atmLevel)));
188
        // check strikes!!!!!!!!!!!!!!!!!!!!
189
0
        interpolation_ = interpolator.interpolate(strikes_.begin(),
190
0
                                                  strikes_.end(),
191
0
                                                  vols_.begin());
192
0
    }
193
194
195
    template <class Interpolator>
196
    inline void InterpolatedSmileSection<Interpolator>::performCalculations()
197
0
                                                                      const {
198
0
        for (Size i=0; i<stdDevHandles_.size(); ++i)
199
0
            vols_[i] = stdDevHandles_[i]->value()/exerciseTimeSquareRoot_;
200
0
        interpolation_.update();
201
0
    }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::performCalculations() const
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::performCalculations() const
202
203
    #ifndef __DOXYGEN__
204
    template <class Interpolator>
205
0
    Real InterpolatedSmileSection<Interpolator>::varianceImpl(Real strike) const {
206
0
        calculate();
207
0
        Real v = interpolation_(strike, true);
208
0
        return v*v*exerciseTime();
209
0
    }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::varianceImpl(double) const
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::varianceImpl(double) const
210
211
    template <class Interpolator>
212
0
    Real InterpolatedSmileSection<Interpolator>::volatilityImpl(Real strike) const {
213
0
        calculate();
214
0
        return interpolation_(strike, true);
215
0
    }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::volatilityImpl(double) const
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::volatilityImpl(double) const
216
217
    template <class Interpolator>
218
0
    void InterpolatedSmileSection<Interpolator>::update() {
219
0
        LazyObject::update();
220
0
        SmileSection::update();
221
0
    }
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Linear>::update()
Unexecuted instantiation: QuantLib::InterpolatedSmileSection<QuantLib::Cubic>::update()
222
    #endif
223
224
}
225
226
#endif