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

lballabio / QuantLib / 29322798317

14 Jul 2026 09:44AM UTC coverage: 74.884% (-0.001%) from 74.885%
29322798317

Pull #2659

github

web-flow
Merge 1d1718774 into e10d38e2e
Pull Request #2659: Remove features deprecated in version 1.39

59498 of 79454 relevant lines covered (74.88%)

8605772.48 hits per line

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

57.14
/ql/termstructures/inflationtermstructure.cpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2007, 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
#include <ql/indexes/inflationindex.hpp>
21
#include <ql/termstructures/inflationtermstructure.hpp>
22
#include <utility>
23

24
namespace QuantLib {
25

26
    InflationTermStructure::InflationTermStructure(
×
27
                                        Date baseDate,
28
                                        Frequency frequency,
29
                                        const DayCounter& dayCounter,
30
                                        ext::shared_ptr<Seasonality> seasonality,
31
                                        Rate baseRate)
×
32
    : TermStructure(dayCounter), seasonality_(std::move(seasonality)),
×
33
      frequency_(frequency), baseRate_(baseRate), baseDate_(baseDate) {
×
34
        if (seasonality_ != nullptr) {
×
35
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
36
                       "Seasonality inconsistent with inflation term structure");
37
        }
38
    }
×
39

40
    InflationTermStructure::InflationTermStructure(
254✔
41
                                        const Date& referenceDate,
42
                                        Date baseDate,
43
                                        Frequency frequency,
44
                                        const DayCounter& dayCounter,
45
                                        ext::shared_ptr<Seasonality> seasonality,
46
                                        Rate baseRate)
×
47
    : TermStructure(referenceDate, Calendar(), dayCounter), seasonality_(std::move(seasonality)),
508✔
48
      frequency_(frequency), baseRate_(baseRate), baseDate_(baseDate) {
508✔
49
        if (seasonality_ != nullptr) {
254✔
50
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
51
                       "Seasonality inconsistent with inflation term structure");
52
        }
53
    }
254✔
54

55
    InflationTermStructure::InflationTermStructure(
×
56
                                        Natural settlementDays,
57
                                        const Calendar& calendar,
58
                                        Date baseDate,
59
                                        Frequency frequency,
60
                                        const DayCounter& dayCounter,
61
                                        ext::shared_ptr<Seasonality> seasonality,
62
                                        Rate baseRate)
×
63
    : TermStructure(settlementDays, calendar, dayCounter), seasonality_(std::move(seasonality)),
×
64
      frequency_(frequency), baseRate_(baseRate), baseDate_(baseDate) {
×
65
        if (seasonality_ != nullptr) {
×
66
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
67
                       "Seasonality inconsistent with inflation term structure");
68
        }
69
    }
×
70

71
    Date InflationTermStructure::baseDate() const {
624,974✔
72
        return baseDate_;
624,974✔
73
    }
74

75
    void InflationTermStructure::setSeasonality(
4✔
76
                          const ext::shared_ptr<Seasonality>& seasonality) {
77
        // always reset, whether with null or new pointer
78
        seasonality_ = seasonality;
4✔
79
        if (seasonality_ != nullptr) {
4✔
80
            QL_REQUIRE(seasonality_->isConsistent(*this),
3✔
81
                       "Seasonality inconsistent with inflation term structure");
82
        }
83
        update();
4✔
84
    }
4✔
85

86

87
    void InflationTermStructure::checkRange(const Date& d,
430,358✔
88
                                            bool extrapolate) const {
89
        QL_REQUIRE(d >= baseDate(),
430,358✔
90
                   "date (" << d << ") is before base date (" << baseDate() << ")");
91
        QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(),
430,358✔
92
                   "date (" << d << ") is past max curve date ("
93
                   << maxDate() << ")");
94
    }
430,358✔
95

96
    void InflationTermStructure::checkRange(Time t,
2✔
97
                                            bool extrapolate) const {
98
        QL_REQUIRE(t >= timeFromReference(baseDate()),
2✔
99
                   "time (" << t << ") is before base date");
100
        QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime(),
2✔
101
                   "time (" << t << ") is past max curve time ("
102
                   << maxTime() << ")");
103
    }
2✔
104

105

106
    ZeroInflationTermStructure::ZeroInflationTermStructure(
×
107
                                   Date baseDate,
108
                                   Frequency frequency,
109
                                   const DayCounter& dayCounter,
110
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
111
    : InflationTermStructure(baseDate, frequency, dayCounter, seasonality) {}
×
112

113
    ZeroInflationTermStructure::ZeroInflationTermStructure(
243✔
114
                                   const Date& referenceDate,
115
                                   Date baseDate,
116
                                   Frequency frequency,
117
                                   const DayCounter& dayCounter,
118
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
119
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality) {}
486✔
120

121
    ZeroInflationTermStructure::ZeroInflationTermStructure(
×
122
                                   Natural settlementDays,
123
                                   const Calendar& calendar,
124
                                   Date baseDate,
125
                                   Frequency frequency,
126
                                   const DayCounter& dayCounter,
127
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
128
    : InflationTermStructure(settlementDays, calendar, baseDate, frequency, dayCounter, seasonality) {}
×
129

130
    Rate ZeroInflationTermStructure::zeroRate(const Date &d, bool extrapolate) const {
195,043✔
131
        QL_DEPRECATED_DISABLE_WARNING
132
        return zeroRate(d, Period(0, Days), false, extrapolate);
195,043✔
133
        QL_DEPRECATED_ENABLE_WARNING
134
    }
135

136
    Rate ZeroInflationTermStructure::zeroRate(const Date &d, const Period& instObsLag,
195,043✔
137
                                              bool forceLinearInterpolation,
138
                                              bool extrapolate) const {
139

140
        Period useLag = instObsLag;
195,043✔
141
        if (instObsLag == Period(-1,Days)) {
195,043✔
142
            useLag = Period(0, Days);
143
        }
144

145
        Rate zeroRate;
146
        if (forceLinearInterpolation) {
195,043✔
147
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
×
148
            dd.second = dd.second + Period(1,Days);
×
149
            Real dp = dd.second - dd.first;
×
150
            Real dt = d - dd.first;
×
151
            // if we are interpolating we only check the exact point
152
            // this prevents falling off the end at curve maturity
153
            InflationTermStructure::checkRange(d, extrapolate);
×
154
            Time t1 = timeFromReference(dd.first);
×
155
            Time t2 = timeFromReference(dd.second);
×
156
            Rate z1 = zeroRateImpl(t1);
×
157
            Rate z2 = zeroRateImpl(t2);
×
158
            zeroRate = z1 + (z2-z1) * (dt/dp);
×
159
        } else {
160
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
390,086✔
161
            InflationTermStructure::checkRange(dd.first, extrapolate);
195,043✔
162
            Time t = timeFromReference(dd.first);
195,043✔
163
            zeroRate = zeroRateImpl(t);
195,043✔
164
        }
165

166
        if (hasSeasonality()) {
195,043✔
167
            zeroRate = seasonality()->correctZeroRate(d-useLag, zeroRate, *this);
262✔
168
        }
169
        return zeroRate;
195,043✔
170
    }
171

172
    Rate ZeroInflationTermStructure::zeroRate(Time t,
1✔
173
                                              bool extrapolate) const {
174
        checkRange(t, extrapolate);
1✔
175
        return zeroRateImpl(t);
1✔
176
    }
177

178

179
    YoYInflationTermStructure::YoYInflationTermStructure(
×
180
                                    Date baseDate,
181
                                    Rate baseYoYRate,
182
                                    Frequency frequency,
183
                                    const DayCounter& dayCounter,
184
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
185
    : InflationTermStructure(baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
×
186

187
    YoYInflationTermStructure::YoYInflationTermStructure(
11✔
188
                                    const Date& referenceDate,
189
                                    Date baseDate,
190
                                    Rate baseYoYRate,
191
                                    Frequency frequency,
192
                                    const DayCounter& dayCounter,
193
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
194
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
22✔
195

196
    YoYInflationTermStructure::YoYInflationTermStructure(
×
197
                                    Natural settlementDays,
198
                                    const Calendar& calendar,
199
                                    Date baseDate,
200
                                    Rate baseYoYRate,
201
                                    Frequency frequency,
202
                                    const DayCounter& dayCounter,
203
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
204
    : InflationTermStructure(settlementDays, calendar, baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
×
205

206
    Rate YoYInflationTermStructure::yoyRate(const Date &d, bool extrapolate) const {
235,315✔
207
        QL_DEPRECATED_DISABLE_WARNING
208
        return yoyRate(d, Period(0, Days), false, extrapolate);
235,315✔
209
        QL_DEPRECATED_ENABLE_WARNING
210
    }
211

212
    Rate YoYInflationTermStructure::yoyRate(const Date &d, const Period& instObsLag,
235,315✔
213
                                            bool forceLinearInterpolation,
214
                                            bool extrapolate) const {
215

216
        Period useLag = instObsLag;
235,315✔
217
        if (instObsLag == Period(-1,Days)) {
235,315✔
218
            useLag = Period(0, Days);
219
        }
220

221
        Rate yoyRate;
222
        if (forceLinearInterpolation) {
235,315✔
223
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
×
224
            dd.second = dd.second + Period(1,Days);
×
225
            Real dp = dd.second - dd.first;
×
226
            Real dt = (d-useLag) - dd.first;
×
227
            // if we are interpolating we only check the exact point
228
            // this prevents falling off the end at curve maturity
229
            InflationTermStructure::checkRange(d, extrapolate);
×
230
            Time t1 = timeFromReference(dd.first);
×
231
            Time t2 = timeFromReference(dd.second);
×
232
            Rate y1 = yoyRateImpl(t1);
×
233
            Rate y2 = yoyRateImpl(t2);
×
234
            yoyRate = y1 + (y2-y1) * (dt/dp);
×
235
        } else {
236
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
470,630✔
237
            InflationTermStructure::checkRange(dd.first, extrapolate);
235,315✔
238
            Time t = timeFromReference(dd.first);
235,315✔
239
            yoyRate = yoyRateImpl(t);
235,315✔
240
        }
241

242
        if (hasSeasonality()) {
235,315✔
243
            yoyRate = seasonality()->correctYoYRate(d-useLag, yoyRate, *this);
×
244
        }
245
        return yoyRate;
235,315✔
246
    }
247

248
    Rate YoYInflationTermStructure::yoyRate(Time t,
1✔
249
                                            bool extrapolate) const {
250
        checkRange(t, extrapolate);
1✔
251
        return yoyRateImpl(t);
1✔
252
    }
253

254

255

256

257
    std::pair<Date,Date> inflationPeriod(const Date& d,
5,042,846✔
258
                                         Frequency frequency) {
259
        Month month = d.month();
5,042,846✔
260
        Year year = d.year();
5,042,846✔
261

262
        Month startMonth, endMonth;
263
        switch (frequency) {
5,042,846✔
264
          case Annual:
1,413,662✔
265
          case Semiannual:
266
          case EveryFourthMonth:
267
          case Quarterly:
268
          case Bimonthly: {
269
                int nMonths = 12 / frequency;
1,413,662✔
270
                startMonth = Month(month - (month - 1) % nMonths);
1,413,662✔
271
                endMonth = Month(startMonth + nMonths - 1);
1,413,662✔
272
            }
273
            break;
1,413,662✔
274
          case Monthly:
275
            startMonth = endMonth = month;
276
            break;
277
          default:
×
278
            QL_FAIL("Frequency not handled: " << frequency);
×
279
            break;
280
        };
281

282
        return {Date(1, startMonth, year), Date::endOfMonth(Date(1, endMonth, year))};
5,042,846✔
283
    }
284

285

286
    Time inflationYearFraction(Frequency f, bool indexIsInterpolated,
194,234✔
287
                               const DayCounter &dayCounter,
288
                               const Date &d1, const Date &d2) {
289

290
        Time t=0;
291
        if (indexIsInterpolated) {
194,234✔
292
            // N.B. we do not use linear interpolation between flat
293
            // fixing forecasts for forecasts.  This avoids awkwardnesses
294
            // when bootstrapping the inflation curve.
295
            t = dayCounter.yearFraction(d1, d2);
×
296
        } else {
297
            // I.e. fixing is constant for the whole inflation period.
298
            // Use the value for half way along the period.
299
            // But the inflation time is the time between period starts
300
            std::pair<Date,Date> limD1 = inflationPeriod(d1, f);
194,234✔
301
            std::pair<Date,Date> limD2 = inflationPeriod(d2, f);
194,234✔
302
            t = dayCounter.yearFraction(limD1.first, limD2.first);
194,234✔
303
        }
304

305
        return t;
194,234✔
306
    }
307

308

309
}
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