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

lballabio / QuantLib / 18902330216

29 Oct 2025 08:56AM UTC coverage: 74.321% (+0.4%) from 73.914%
18902330216

Pull #2344

github

web-flow
Merge a8095fd90 into d823f4ecb
Pull Request #2344: add multicurve bootstrap

100 of 104 new or added lines in 8 files covered. (96.15%)

216 existing lines in 13 files now uncovered.

57073 of 76793 relevant lines covered (74.32%)

8779123.65 hits per line

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

74.07
/ql/cashflows/yoyinflationcoupon.cpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2009 Chris Kenyon
5

6
 This file is part of QuantLib, a free-software/open-source library
7
 for financial quantitative analysts and developers - http://quantlib.org/
8

9
 QuantLib is free software: you can redistribute it and/or modify it
10
 under the terms of the QuantLib license.  You should have received a
11
 copy of the license along with this program; if not, please email
12
 <quantlib-dev@lists.sf.net>. The license is also available online at
13
 <https://www.quantlib.org/license.shtml>.
14

15
 This program is distributed in the hope that it will be useful, but WITHOUT
16
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 FOR A PARTICULAR PURPOSE.  See the license for more details.
18
 */
19

20

21
#include <ql/cashflows/capflooredinflationcoupon.hpp>
22
#include <ql/cashflows/cashflowvectors.hpp>
23
#include <ql/cashflows/inflationcoupon.hpp>
24
#include <ql/cashflows/inflationcouponpricer.hpp>
25
#include <utility>
26

27
namespace QuantLib {
28

29
    YoYInflationCoupon::
89,435✔
30
    YoYInflationCoupon(const Date& paymentDate,
31
                       Real nominal,
32
                       const Date& startDate,
33
                       const Date& endDate,
34
                       Natural fixingDays,
35
                       const ext::shared_ptr<YoYInflationIndex>& yoyIndex,
36
                       const Period& observationLag,
37
                       CPI::InterpolationType interpolation,
38
                       const DayCounter& dayCounter,
39
                       Real gearing,
40
                       Spread spread,
41
                       const Date& refPeriodStart,
42
                       const Date& refPeriodEnd)
76,142✔
43
    : InflationCoupon(paymentDate, nominal, startDate, endDate,
44
                      fixingDays, yoyIndex, observationLag,
45
                      dayCounter, refPeriodStart, refPeriodEnd),
46
      yoyIndex_(yoyIndex), interpolation_(interpolation), gearing_(gearing), spread_(spread) {}
268,305✔
47

48
    void YoYInflationCoupon::accept(AcyclicVisitor& v) {
×
UNCOV
49
        auto* v1 = dynamic_cast<Visitor<YoYInflationCoupon>*>(&v);
×
UNCOV
50
        if (v1 != nullptr)
×
UNCOV
51
            v1->visit(*this);
×
52
        else
UNCOV
53
            InflationCoupon::accept(v);
×
UNCOV
54
    }
×
55

56
    bool YoYInflationCoupon::checkPricerImpl(
89,435✔
57
            const ext::shared_ptr<InflationCouponPricer>&pricer) const {
58
        return static_cast<bool>(
59
               ext::dynamic_pointer_cast<YoYInflationCouponPricer>(pricer));
89,435✔
60
    }
61

62
    Rate YoYInflationCoupon::indexFixing() const {
52,236✔
63
        return CPI::laggedYoYRate(yoyIndex(), accrualEndDate(), observationLag(), interpolation_);
52,236✔
64
    }
65

66

67
    yoyInflationLeg::yoyInflationLeg(Schedule schedule,
11,214✔
68
                                     Calendar paymentCalendar,
69
                                     ext::shared_ptr<YoYInflationIndex> index,
70
                                     const Period& observationLag,
71
                                     CPI::InterpolationType interpolation)
11,214✔
72
    : schedule_(std::move(schedule)), index_(std::move(index)), observationLag_(observationLag),
11,214✔
73
      interpolation_(interpolation), paymentCalendar_(std::move(paymentCalendar)) {}
11,214✔
74

75
    yoyInflationLeg& yoyInflationLeg::withNotionals(Real notional) {
1,961✔
76
        notionals_ = std::vector<Real>(1,notional);
1,961✔
77
        return *this;
1,961✔
78
    }
79

80
    yoyInflationLeg& yoyInflationLeg::withNotionals(const std::vector<Real>& notionals) {
9,253✔
81
        notionals_ = notionals;
9,253✔
82
        return *this;
9,253✔
83
    }
84

85
    yoyInflationLeg& yoyInflationLeg::withPaymentDayCounter(const DayCounter& dayCounter) {
11,214✔
86
        paymentDayCounter_ = dayCounter;
87
        return *this;
11,214✔
88
    }
89

90
    yoyInflationLeg& yoyInflationLeg::withPaymentAdjustment(BusinessDayConvention convention) {
11,214✔
91
        paymentAdjustment_ = convention;
11,214✔
92
        return *this;
11,214✔
93
    }
94

UNCOV
95
    yoyInflationLeg& yoyInflationLeg::withFixingDays(Natural fixingDays) {
×
96
        fixingDays_ = std::vector<Natural>(1,fixingDays);
×
97
        return *this;
×
98
    }
99

UNCOV
100
    yoyInflationLeg& yoyInflationLeg::withFixingDays(const std::vector<Natural>& fixingDays) {
×
UNCOV
101
        fixingDays_ = fixingDays;
×
UNCOV
102
        return *this;
×
103
    }
104

UNCOV
105
    yoyInflationLeg& yoyInflationLeg::withGearings(Real gearing) {
×
UNCOV
106
        gearings_ = std::vector<Real>(1,gearing);
×
UNCOV
107
        return *this;
×
108
    }
109

110
    yoyInflationLeg& yoyInflationLeg::withGearings(const std::vector<Real>& gearings) {
2,532✔
111
        gearings_ = gearings;
2,532✔
112
        return *this;
2,532✔
113
    }
114

115
    yoyInflationLeg& yoyInflationLeg::withSpreads(Spread spread) {
1,873✔
116
        spreads_ = std::vector<Spread>(1,spread);
1,873✔
117
        return *this;
1,873✔
118
    }
119

120
    yoyInflationLeg& yoyInflationLeg::withSpreads(const std::vector<Spread>& spreads) {
2,532✔
121
        spreads_ = spreads;
2,532✔
122
        return *this;
2,532✔
123
    }
124

125
    yoyInflationLeg& yoyInflationLeg::withCaps(Rate cap) {
×
126
        caps_ = std::vector<Rate>(1,cap);
×
127
        return *this;
×
128
    }
129

130
    yoyInflationLeg& yoyInflationLeg::withCaps(const std::vector<Rate>& caps) {
1,689✔
131
        caps_ = caps;
1,689✔
132
        return *this;
1,689✔
133
    }
134

UNCOV
135
    yoyInflationLeg& yoyInflationLeg::withFloors(Rate floor) {
×
UNCOV
136
        floors_ = std::vector<Rate>(1,floor);
×
UNCOV
137
        return *this;
×
138
    }
139

140
    yoyInflationLeg& yoyInflationLeg::withFloors(const std::vector<Rate>& floors) {
1,689✔
141
        floors_ = floors;
1,689✔
142
        return *this;
1,689✔
143
    }
144

145

146
    yoyInflationLeg::operator Leg() const {
11,214✔
147

148
        Size n = schedule_.size()-1;
11,214✔
149
        QL_REQUIRE(!paymentDayCounter_.empty(), "no payment daycounter given");
11,214✔
150
        QL_REQUIRE(!notionals_.empty(), "no notional given");
11,214✔
151
        QL_REQUIRE(notionals_.size() <= n,
11,214✔
152
                   "too many nominals (" << notionals_.size() <<
153
                   "), only " << n << " required");
154
        QL_REQUIRE(gearings_.size()<=n,
11,214✔
155
                   "too many gearings (" << gearings_.size() <<
156
                   "), only " << n << " required");
157
        QL_REQUIRE(spreads_.size()<=n,
11,214✔
158
                   "too many spreads (" << spreads_.size() <<
159
                   "), only " << n << " required");
160
        QL_REQUIRE(caps_.size()<=n,
11,214✔
161
                   "too many caps (" << caps_.size() <<
162
                   "), only " << n << " required");
163
        QL_REQUIRE(floors_.size()<=n,
11,214✔
164
                   "too many floors (" << floors_.size() <<
165
                   "), only " << n << " required");
166

167
        Leg leg; leg.reserve(n);
11,214✔
168

169
        Calendar calendar = paymentCalendar_;
170

171
        Date refStart, start, refEnd, end;
11,214✔
172

173
        for (Size i=0; i<n; ++i) {
100,649✔
174
            refStart = start = schedule_.date(i);
89,435✔
175
            refEnd   =   end = schedule_.date(i+1);
89,435✔
176
            Date paymentDate = calendar.adjust(end, paymentAdjustment_);
89,435✔
177
            if (i==0 && schedule_.hasIsRegular() && !schedule_.isRegular(i+1)) {
89,435✔
178
                BusinessDayConvention bdc = schedule_.businessDayConvention();
179
                refStart = schedule_.calendar().adjust(end - schedule_.tenor(), bdc);
180✔
180
            }
181
            if (i==n-1 && schedule_.hasIsRegular() && !schedule_.isRegular(i+1)) {
89,435✔
182
                BusinessDayConvention bdc = schedule_.businessDayConvention();
UNCOV
183
                refEnd = schedule_.calendar().adjust(start + schedule_.tenor(), bdc);
×
184
            }
185
            if (detail::get(gearings_, i, 1.0) == 0.0) { // fixed coupon
89,435✔
UNCOV
186
                leg.push_back(ext::make_shared<FixedRateCoupon>(
×
187
                            paymentDate,
UNCOV
188
                            detail::get(notionals_, i, 1.0),
×
UNCOV
189
                            detail::effectiveFixedRate(spreads_,caps_,
×
UNCOV
190
                                                       floors_,i),
×
UNCOV
191
                            paymentDayCounter_,
×
192
                            start, end, refStart, refEnd));
193
            } else { // yoy inflation coupon
194
                if (detail::noOption(caps_, floors_, i)) { // just swaplet
89,435✔
195
                    leg.push_back(ext::make_shared<YoYInflationCoupon>(
76,142✔
196
                            paymentDate,
197
                            detail::get(notionals_, i, 1.0),
152,284✔
198
                            start, end,
199
                            detail::get(fixingDays_, i, 0),
152,284✔
200
                            index_,
76,142✔
201
                            observationLag_,
76,142✔
202
                            interpolation_,
76,142✔
203
                            paymentDayCounter_,
76,142✔
204
                            detail::get(gearings_, i, 1.0),
152,284✔
205
                            detail::get(spreads_, i, 0.0),
152,284✔
206
                            refStart, refEnd));
207
                } else {    // cap/floorlet
208
                    leg.push_back(ext::make_shared<CappedFlooredYoYInflationCoupon>(
13,293✔
209
                            paymentDate,
210
                            detail::get(notionals_, i, 1.0),
26,586✔
211
                            start, end,
212
                            detail::get(fixingDays_, i, 0),
26,586✔
213
                            index_,
13,293✔
214
                            observationLag_,
13,293✔
215
                            interpolation_,
13,293✔
216
                            paymentDayCounter_,
13,293✔
217
                            detail::get(gearings_, i, 1.0),
26,586✔
218
                            detail::get(spreads_, i, 0.0),
26,586✔
219
                            detail::get(caps_,   i, Null<Rate>()),
26,586✔
220
                            detail::get(floors_, i, Null<Rate>()),
26,586✔
221
                            refStart, refEnd));
222
                }
223
            }
224
        }
225

226
        // Without caps or floors, this is enough; otherwise, a more
227
        // specific pricer will need to be set in client code.
228
        if (caps_.empty() && floors_.empty())
11,214✔
229
            setCouponPricer(leg, ext::make_shared<YoYInflationCouponPricer>());
19,050✔
230

231
        return leg;
11,214✔
UNCOV
232
    }
×
233

234
}
235

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

© 2025 Coveralls, Inc