Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/termstructures/volatility/optionlet/strippedoptionlet.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2008 Ferdinando Ametrano
5
 Copyright (C) 2007 Giorgio Facchinetti
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
#include <ql/instruments/makecapfloor.hpp>
23
#include <ql/pricingengines/capfloor/blackcapfloorengine.hpp>
24
#include <ql/termstructures/volatility/optionlet/strippedoptionlet.hpp>
25
#include <ql/utilities/dataformatters.hpp>
26
#include <utility>
27
28
using std::vector;
29
30
namespace QuantLib {
31
32
    StrippedOptionlet::StrippedOptionlet(Natural settlementDays,
33
                                         const Calendar& calendar,
34
                                         BusinessDayConvention bdc,
35
                                         ext::shared_ptr<IborIndex> iborIndex,
36
                                         const vector<Date>& optionletDates,
37
                                         const vector<Rate>& strikes,
38
                                         vector<vector<Handle<Quote>>> v,
39
                                         DayCounter dc,
40
                                         VolatilityType type,
41
                                         Real displacement)
42
0
    : StrippedOptionlet(settlementDays,
43
0
                        calendar,
44
0
                        bdc,
45
0
                        std::move(iborIndex),
46
0
                        optionletDates,
47
0
                        vector<vector<Rate>>(optionletDates.size(), strikes),
48
0
                        std::move(v),
49
0
                        std::move(dc),
50
0
                        type,
51
0
                        displacement) {}
Unexecuted instantiation: QuantLib::StrippedOptionlet::StrippedOptionlet(unsigned int, QuantLib::Calendar const&, QuantLib::BusinessDayConvention, boost::shared_ptr<QuantLib::IborIndex>, std::__1::vector<QuantLib::Date, std::__1::allocator<QuantLib::Date> > const&, std::__1::vector<double, std::__1::allocator<double> > const&, std::__1::vector<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > >, std::__1::allocator<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > > > >, QuantLib::DayCounter, QuantLib::VolatilityType, double)
Unexecuted instantiation: QuantLib::StrippedOptionlet::StrippedOptionlet(unsigned int, QuantLib::Calendar const&, QuantLib::BusinessDayConvention, boost::shared_ptr<QuantLib::IborIndex>, std::__1::vector<QuantLib::Date, std::__1::allocator<QuantLib::Date> > const&, std::__1::vector<double, std::__1::allocator<double> > const&, std::__1::vector<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > >, std::__1::allocator<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > > > >, QuantLib::DayCounter, QuantLib::VolatilityType, double)
52
53
    StrippedOptionlet::StrippedOptionlet(Natural settlementDays,
54
                                         const Calendar& calendar,
55
                                         BusinessDayConvention bdc,
56
                                         ext::shared_ptr<IborIndex> iborIndex,
57
                                         const vector<Date>& optionletDates,
58
                                         const vector<vector<Rate>>& strikes,
59
                                         vector<vector<Handle<Quote>>> v,
60
                                         DayCounter dc,
61
                                         VolatilityType type,
62
                                         Real displacement)
63
0
    : calendar_(calendar), settlementDays_(settlementDays), businessDayConvention_(bdc),
64
0
      dc_(std::move(dc)), iborIndex_(std::move(iborIndex)), type_(type),
65
0
      displacement_(displacement), nOptionletDates_(optionletDates.size()),
66
0
      optionletDates_(optionletDates), optionletTimes_(nOptionletDates_),
67
0
      optionletAtmRates_(nOptionletDates_), optionletStrikes_(strikes),
68
0
      optionletVolQuotes_(std::move(v)) {
69
0
        checkInputs();
70
71
0
        for (Size i = 0; i < nOptionletDates_; ++i)
72
0
            optionletVolatilities_.emplace_back(strikes[i].size());
73
74
0
        registerWith(Settings::instance().evaluationDate());
75
0
        registerWithMarketData();
76
77
0
        Date refDate = calendar.advance(Settings::instance().evaluationDate(),
78
0
                                        settlementDays, Days);
79
80
0
        for (Size i=0; i<nOptionletDates_; ++i)
81
0
            optionletTimes_[i] = dc_.yearFraction(refDate, optionletDates_[i]);
82
0
    }
Unexecuted instantiation: QuantLib::StrippedOptionlet::StrippedOptionlet(unsigned int, QuantLib::Calendar const&, QuantLib::BusinessDayConvention, boost::shared_ptr<QuantLib::IborIndex>, std::__1::vector<QuantLib::Date, std::__1::allocator<QuantLib::Date> > const&, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > const&, std::__1::vector<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > >, std::__1::allocator<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > > > >, QuantLib::DayCounter, QuantLib::VolatilityType, double)
Unexecuted instantiation: QuantLib::StrippedOptionlet::StrippedOptionlet(unsigned int, QuantLib::Calendar const&, QuantLib::BusinessDayConvention, boost::shared_ptr<QuantLib::IborIndex>, std::__1::vector<QuantLib::Date, std::__1::allocator<QuantLib::Date> > const&, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > const&, std::__1::vector<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > >, std::__1::allocator<std::__1::vector<QuantLib::Handle<QuantLib::Quote>, std::__1::allocator<QuantLib::Handle<QuantLib::Quote> > > > >, QuantLib::DayCounter, QuantLib::VolatilityType, double)
83
84
0
    void StrippedOptionlet::checkInputs() const {
85
86
0
        QL_REQUIRE(!optionletDates_.empty(), "empty optionlet tenor vector");
87
0
        QL_REQUIRE(nOptionletDates_==optionletVolQuotes_.size(),
88
0
                   "mismatch between number of option tenors (" <<
89
0
                   nOptionletDates_ << ") and number of volatility rows (" <<
90
0
                   optionletVolQuotes_.size() << ")");
91
0
        QL_REQUIRE(optionletDates_[0]>Settings::instance().evaluationDate(),
92
0
                   "first option date (" << optionletDates_[0] << ") is in the past");
93
0
        for (Size i=1; i<nOptionletDates_; ++i)
94
0
            QL_REQUIRE(optionletDates_[i]>optionletDates_[i-1],
95
0
                       "non increasing option dates: " << io::ordinal(i) <<
96
0
                       " is " << optionletDates_[i-1] << ", " <<
97
0
                       io::ordinal(i+1) << " is " << optionletDates_[i]);
98
0
        QL_REQUIRE(nOptionletDates_ == optionletStrikes_.size(),
99
0
                   "mismatch between number of option tenors (" << nOptionletDates_
100
0
                                                                << ") and number of strikes ("
101
0
                                                                << optionletStrikes_.size() << ")");
102
0
        for (Size i = 0; i < nOptionletDates_; ++i) {
103
0
            QL_REQUIRE(optionletStrikes_[i].size() == optionletVolQuotes_[i].size(),
104
0
                       "mismatch between number of option tenors ("
105
0
                           << nOptionletDates_ << ") and number of vol columns at date " << i
106
0
                           << " (" << optionletVolQuotes_[i].size());
107
0
            for (Size j = 1; j < optionletStrikes_[i].size(); ++j)
108
0
                QL_REQUIRE(optionletStrikes_[i][j - 1] < optionletStrikes_[i][j],
109
0
                           "non increasing strikes at date "
110
0
                               << i << ": " << io::ordinal(j) << " is "
111
0
                               << io::rate(optionletStrikes_[0][j - 1]) << ", "
112
0
                               << io::ordinal(j + 1) << " is "
113
0
                               << io::rate(optionletStrikes_[0][j]));
114
0
        }
115
0
    }
116
117
0
    void StrippedOptionlet::registerWithMarketData() {
118
0
        for (Size i = 0; i < nOptionletDates_; ++i)
119
0
            for (auto& j : optionletVolQuotes_[i])
120
0
                registerWith(j);
121
0
    }
122
123
0
    void StrippedOptionlet::performCalculations() const {
124
0
        for (Size i = 0; i < nOptionletDates_; ++i)
125
0
            for (Size j = 0; j < optionletVolQuotes_[i].size(); ++j)
126
0
                optionletVolatilities_[i][j] = optionletVolQuotes_[i][j]->value();
127
0
    }
128
129
0
    const vector<Rate>& StrippedOptionlet::optionletStrikes(Size i) const{
130
0
        QL_REQUIRE(i<optionletStrikes_.size(),
131
0
                   "index (" << i <<
132
0
                   ") must be less than optionletStrikes size (" <<
133
0
                   optionletStrikes_.size() << ")");
134
0
        return optionletStrikes_[i];
135
0
    }
136
137
    const vector<Volatility>&
138
0
    StrippedOptionlet::optionletVolatilities(Size i) const{
139
0
        calculate();
140
0
        QL_REQUIRE(i<optionletVolatilities_.size(),
141
0
                   "index (" << i <<
142
0
                   ") must be less than optionletVolatilities size (" <<
143
0
                   optionletVolatilities_.size() << ")");
144
0
        return optionletVolatilities_[i];
145
0
    }
146
147
0
    const vector<Date>& StrippedOptionlet::optionletFixingDates() const {
148
0
        calculate();
149
0
        return optionletDates_;
150
0
    }
151
152
0
    const vector<Time>& StrippedOptionlet::optionletFixingTimes() const {
153
0
        calculate();
154
0
        return optionletTimes_;
155
0
    }
156
157
0
    Size StrippedOptionlet::optionletMaturities() const {
158
0
        return nOptionletDates_;
159
0
    }
160
161
0
    const vector<Time>& StrippedOptionlet::atmOptionletRates() const {
162
0
        calculate();
163
0
        for (Size i=0; i<nOptionletDates_; ++i)
164
0
            optionletAtmRates_[i] = iborIndex_->fixing(optionletDates_[i], true);
165
0
        return optionletAtmRates_;
166
0
    }
167
168
0
    DayCounter StrippedOptionlet::dayCounter() const {
169
0
        return dc_;
170
0
    }
171
172
0
    Calendar StrippedOptionlet::calendar() const {
173
0
        return calendar_;
174
0
    }
175
176
0
    Natural StrippedOptionlet::settlementDays() const {
177
0
        return settlementDays_;
178
0
    }
179
180
0
    BusinessDayConvention StrippedOptionlet::businessDayConvention() const {
181
0
        return businessDayConvention_;
182
0
    }
183
184
0
    VolatilityType StrippedOptionlet::volatilityType() const {
185
0
        return type_;
186
0
    }
187
188
0
    Real StrippedOptionlet::displacement() const {
189
0
        return displacement_;
190
0
    }
191
192
}