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

lballabio / QuantLib / 20336157418

18 Dec 2025 11:57AM UTC coverage: 74.15% (-0.1%) from 74.295%
20336157418

Pull #2368

github

web-flow
Merge 856b09650 into c15a6fecb
Pull Request #2368: Fx options utils - `BlackVolatilitySurfaceDelta` class

109 of 170 new or added lines in 5 files covered. (64.12%)

423 existing lines in 23 files now uncovered.

57618 of 77705 relevant lines covered (74.15%)

8752879.52 hits per line

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

50.34
/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
    QL_DEPRECATED_DISABLE_WARNING
27

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

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

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

73
    QL_DEPRECATED_ENABLE_WARNING
74

75
    Date InflationTermStructure::baseDate() const {
243,743✔
76
        return baseDate_;
243,743✔
77
    }
78

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

90

91
    void InflationTermStructure::checkRange(const Date& d,
239,992✔
92
                                            bool extrapolate) const {
93
        QL_REQUIRE(d >= baseDate(),
239,992✔
94
                   "date (" << d << ") is before base date (" << baseDate() << ")");
95
        QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(),
239,992✔
96
                   "date (" << d << ") is past max curve date ("
97
                   << maxDate() << ")");
98
    }
239,992✔
99

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

109

110
    ZeroInflationTermStructure::ZeroInflationTermStructure(
×
111
                                   Date baseDate,
112
                                   Frequency frequency,
113
                                   const DayCounter& dayCounter,
114
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
115
    : InflationTermStructure(baseDate, frequency, dayCounter, seasonality) {}
×
116

117
    ZeroInflationTermStructure::ZeroInflationTermStructure(
17✔
118
                                   const Date& referenceDate,
119
                                   Date baseDate,
120
                                   Frequency frequency,
121
                                   const DayCounter& dayCounter,
122
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
123
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality) {}
34✔
124

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

134
    Rate ZeroInflationTermStructure::zeroRate(const Date &d, bool extrapolate) const {
4,080✔
135
        QL_DEPRECATED_DISABLE_WARNING
136
        return zeroRate(d, Period(0, Days), false, extrapolate);
4,080✔
137
        QL_DEPRECATED_ENABLE_WARNING
138
    }
139

140
    Rate ZeroInflationTermStructure::zeroRate(const Date &d, const Period& instObsLag,
4,677✔
141
                                              bool forceLinearInterpolation,
142
                                              bool extrapolate) const {
143

144
        Period useLag = instObsLag;
4,677✔
145
        if (instObsLag == Period(-1,Days)) {
4,677✔
146
            useLag = Period(0, Days);
147
        }
148

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

170
        if (hasSeasonality()) {
4,677✔
171
            zeroRate = seasonality()->correctZeroRate(d-useLag, zeroRate, *this);
452✔
172
        }
173
        return zeroRate;
4,677✔
174
    }
175

176
    Rate ZeroInflationTermStructure::zeroRate(Time t,
1✔
177
                                              bool extrapolate) const {
178
        checkRange(t, extrapolate);
1✔
179
        return zeroRateImpl(t);
1✔
180
    }
181

182

183
    QL_DEPRECATED_DISABLE_WARNING
184

185
    YoYInflationTermStructure::YoYInflationTermStructure(
×
186
                                    Date baseDate,
187
                                    Rate baseYoYRate,
188
                                    Frequency frequency,
189
                                    const DayCounter& dayCounter,
UNCOV
190
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
UNCOV
191
    : InflationTermStructure(baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
×
192

193
    YoYInflationTermStructure::YoYInflationTermStructure(
11✔
194
                                    const Date& referenceDate,
195
                                    Date baseDate,
196
                                    Rate baseYoYRate,
197
                                    Frequency frequency,
198
                                    const DayCounter& dayCounter,
UNCOV
199
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
200
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
22✔
201

UNCOV
202
    YoYInflationTermStructure::YoYInflationTermStructure(
×
203
                                    Natural settlementDays,
204
                                    const Calendar& calendar,
205
                                    Date baseDate,
206
                                    Rate baseYoYRate,
207
                                    Frequency frequency,
208
                                    const DayCounter& dayCounter,
UNCOV
209
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
UNCOV
210
    : InflationTermStructure(settlementDays, calendar, baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
×
211

212
    YoYInflationTermStructure::YoYInflationTermStructure(
×
213
                                    Date baseDate,
214
                                    Rate baseYoYRate,
215
                                    Frequency frequency,
216
                                    bool indexIsInterpolated,
217
                                    const DayCounter& dayCounter,
UNCOV
218
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
UNCOV
219
    : YoYInflationTermStructure(baseDate, baseYoYRate, frequency, dayCounter, seasonality) {
×
UNCOV
220
        indexIsInterpolated_ = indexIsInterpolated;
×
UNCOV
221
    }
×
222

UNCOV
223
    YoYInflationTermStructure::YoYInflationTermStructure(
×
224
                                    const Date& referenceDate,
225
                                    Date baseDate,
226
                                    Rate baseYoYRate,
227
                                    Frequency frequency,
228
                                    bool indexIsInterpolated,
229
                                    const DayCounter& dayCounter,
230
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
231
    : YoYInflationTermStructure(referenceDate, baseDate, baseYoYRate,
UNCOV
232
                                frequency, dayCounter, seasonality) {
×
UNCOV
233
        indexIsInterpolated_ = indexIsInterpolated;
×
UNCOV
234
    }
×
235

UNCOV
236
    YoYInflationTermStructure::YoYInflationTermStructure(
×
237
                                    Natural settlementDays,
238
                                    const Calendar& calendar,
239
                                    Date baseDate,
240
                                    Rate baseYoYRate,
241
                                    Frequency frequency,
242
                                    bool indexIsInterpolated,
243
                                    const DayCounter& dayCounter,
UNCOV
244
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
245
    : YoYInflationTermStructure(settlementDays, calendar, baseDate, baseYoYRate,
UNCOV
246
                                frequency, dayCounter, seasonality) {
×
UNCOV
247
        indexIsInterpolated_ = indexIsInterpolated;
×
UNCOV
248
    }
×
249

250
    QL_DEPRECATED_ENABLE_WARNING
251

252
    Rate YoYInflationTermStructure::yoyRate(const Date &d, bool extrapolate) const {
235,315✔
253
        QL_DEPRECATED_DISABLE_WARNING
254
        return yoyRate(d, Period(0, Days), false, extrapolate);
235,315✔
255
        QL_DEPRECATED_ENABLE_WARNING
256
    }
257

258
    Rate YoYInflationTermStructure::yoyRate(const Date &d, const Period& instObsLag,
235,315✔
259
                                            bool forceLinearInterpolation,
260
                                            bool extrapolate) const {
261

262
        Period useLag = instObsLag;
235,315✔
263
        if (instObsLag == Period(-1,Days)) {
235,315✔
264
            useLag = Period(0, Days);
265
        }
266

267
        Rate yoyRate;
268
        if (forceLinearInterpolation) {
235,315✔
UNCOV
269
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
×
UNCOV
270
            dd.second = dd.second + Period(1,Days);
×
UNCOV
271
            Real dp = dd.second - dd.first;
×
272
            Real dt = (d-useLag) - dd.first;
×
273
            // if we are interpolating we only check the exact point
274
            // this prevents falling off the end at curve maturity
UNCOV
275
            InflationTermStructure::checkRange(d, extrapolate);
×
UNCOV
276
            Time t1 = timeFromReference(dd.first);
×
UNCOV
277
            Time t2 = timeFromReference(dd.second);
×
UNCOV
278
            Rate y1 = yoyRateImpl(t1);
×
UNCOV
279
            Rate y2 = yoyRateImpl(t2);
×
UNCOV
280
            yoyRate = y1 + (y2-y1) * (dt/dp);
×
281
        } else {
282
            QL_DEPRECATED_DISABLE_WARNING
283
            if (indexIsInterpolated()) {
235,315✔
UNCOV
284
                InflationTermStructure::checkRange(d-useLag, extrapolate);
×
285
                Time t = timeFromReference(d-useLag);
×
UNCOV
286
                yoyRate = yoyRateImpl(t);
×
287
            } else {
288
                std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
470,630✔
289
                InflationTermStructure::checkRange(dd.first, extrapolate);
235,315✔
290
                Time t = timeFromReference(dd.first);
235,315✔
291
                yoyRate = yoyRateImpl(t);
235,315✔
292
            }
293
            QL_DEPRECATED_ENABLE_WARNING
294
        }
295

296
        if (hasSeasonality()) {
235,315✔
UNCOV
297
            yoyRate = seasonality()->correctYoYRate(d-useLag, yoyRate, *this);
×
298
        }
299
        return yoyRate;
235,315✔
300
    }
301

302
    Rate YoYInflationTermStructure::yoyRate(Time t,
1✔
303
                                            bool extrapolate) const {
304
        checkRange(t, extrapolate);
1✔
305
        return yoyRateImpl(t);
1✔
306
    }
307

308

309

310

311
    std::pair<Date,Date> inflationPeriod(const Date& d,
2,037,718✔
312
                                         Frequency frequency) {
313
        Month month = d.month();
2,037,718✔
314
        Year year = d.year();
2,037,718✔
315

316
        Month startMonth, endMonth;
317
        switch (frequency) {
2,037,718✔
318
          case Annual:
1,413,662✔
319
          case Semiannual:
320
          case EveryFourthMonth:
321
          case Quarterly:
322
          case Bimonthly: {
323
                int nMonths = 12 / frequency;
1,413,662✔
324
                startMonth = Month(month - (month - 1) % nMonths);
1,413,662✔
325
                endMonth = Month(startMonth + nMonths - 1);
1,413,662✔
326
            }
327
            break;
1,413,662✔
328
          case Monthly:
329
            startMonth = endMonth = month;
330
            break;
UNCOV
331
          default:
×
UNCOV
332
            QL_FAIL("Frequency not handled: " << frequency);
×
333
            break;
334
        };
335

336
        return {Date(1, startMonth, year), Date::endOfMonth(Date(1, endMonth, year))};
2,037,718✔
337
    }
338

339

340
    Time inflationYearFraction(Frequency f, bool indexIsInterpolated,
5,305✔
341
                               const DayCounter &dayCounter,
342
                               const Date &d1, const Date &d2) {
343

344
        Time t=0;
345
        if (indexIsInterpolated) {
5,305✔
346
            // N.B. we do not use linear interpolation between flat
347
            // fixing forecasts for forecasts.  This avoids awkwardnesses
348
            // when bootstrapping the inflation curve.
UNCOV
349
            t = dayCounter.yearFraction(d1, d2);
×
350
        } else {
351
            // I.e. fixing is constant for the whole inflation period.
352
            // Use the value for half way along the period.
353
            // But the inflation time is the time between period starts
354
            std::pair<Date,Date> limD1 = inflationPeriod(d1, f);
5,305✔
355
            std::pair<Date,Date> limD2 = inflationPeriod(d2, f);
5,305✔
356
            t = dayCounter.yearFraction(limD1.first, limD2.first);
5,305✔
357
        }
358

359
        return t;
5,305✔
360
    }
361

362

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