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

lballabio / QuantLib / 14910176578

08 May 2025 03:28PM UTC coverage: 73.315% (+0.02%) from 73.3%
14910176578

Pull #2195

github

web-flow
Merge 3a61f499c into 5d972fb7b
Pull Request #2195: Added `Handle<Quote>` for spread in `OISRateHelper`

32 of 33 new or added lines in 2 files covered. (96.97%)

277 existing lines in 25 files now uncovered.

56277 of 76761 relevant lines covered (73.31%)

8687029.35 hits per line

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

50.68
/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
 <http://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

UNCOV
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) {
×
UNCOV
37
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
38
                       "Seasonality inconsistent with inflation term structure");
39
        }
UNCOV
40
    }
×
41

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

73
    QL_DEPRECATED_ENABLE_WARNING
74

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

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

90

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

UNCOV
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(
14✔
118
                                   const Date& referenceDate,
119
                                   Date baseDate,
120
                                   Frequency frequency,
121
                                   const DayCounter& dayCounter,
UNCOV
122
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
123
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality) {}
28✔
124

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

134
    Rate ZeroInflationTermStructure::zeroRate(const Date &d, const Period& instObsLag,
2,925✔
135
                                              bool forceLinearInterpolation,
136
                                              bool extrapolate) const {
137

138
        Period useLag = instObsLag;
2,925✔
139
        if (instObsLag == Period(-1,Days)) {
2,925✔
140
            useLag = Period(0, Days);
141
        }
142

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

164
        if (hasSeasonality()) {
2,925✔
165
            zeroRate = seasonality()->correctZeroRate(d-useLag, zeroRate, *this);
262✔
166
        }
167
        return zeroRate;
2,925✔
168
    }
169

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

176

177
    QL_DEPRECATED_DISABLE_WARNING
178

179
    YoYInflationTermStructure::YoYInflationTermStructure(
×
180
                                    Date baseDate,
181
                                    Rate baseYoYRate,
182
                                    Frequency frequency,
183
                                    const DayCounter& dayCounter,
UNCOV
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,
UNCOV
193
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
194
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
22✔
195

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

206
    YoYInflationTermStructure::YoYInflationTermStructure(
×
207
                                    Date baseDate,
208
                                    Rate baseYoYRate,
209
                                    Frequency frequency,
210
                                    bool indexIsInterpolated,
211
                                    const DayCounter& dayCounter,
UNCOV
212
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
UNCOV
213
    : YoYInflationTermStructure(baseDate, baseYoYRate, frequency, dayCounter, seasonality) {
×
UNCOV
214
        indexIsInterpolated_ = indexIsInterpolated;
×
UNCOV
215
    }
×
216

217
    YoYInflationTermStructure::YoYInflationTermStructure(
×
218
                                    const Date& referenceDate,
219
                                    Date baseDate,
220
                                    Rate baseYoYRate,
221
                                    Frequency frequency,
222
                                    bool indexIsInterpolated,
223
                                    const DayCounter& dayCounter,
UNCOV
224
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
225
    : YoYInflationTermStructure(referenceDate, baseDate, baseYoYRate,
UNCOV
226
                                frequency, dayCounter, seasonality) {
×
UNCOV
227
        indexIsInterpolated_ = indexIsInterpolated;
×
UNCOV
228
    }
×
229

UNCOV
230
    YoYInflationTermStructure::YoYInflationTermStructure(
×
231
                                    Natural settlementDays,
232
                                    const Calendar& calendar,
233
                                    Date baseDate,
234
                                    Rate baseYoYRate,
235
                                    Frequency frequency,
236
                                    bool indexIsInterpolated,
237
                                    const DayCounter& dayCounter,
UNCOV
238
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
239
    : YoYInflationTermStructure(settlementDays, calendar, baseDate, baseYoYRate,
240
                                frequency, dayCounter, seasonality) {
×
241
        indexIsInterpolated_ = indexIsInterpolated;
×
242
    }
×
243

244
    QL_DEPRECATED_ENABLE_WARNING
245

246
    Rate YoYInflationTermStructure::yoyRate(const Date &d, const Period& instObsLag,
234,533✔
247
                                            bool forceLinearInterpolation,
248
                                            bool extrapolate) const {
249

250
        Period useLag = instObsLag;
234,533✔
251
        if (instObsLag == Period(-1,Days)) {
234,533✔
252
            useLag = Period(0, Days);
253
        }
254

255
        Rate yoyRate;
256
        if (forceLinearInterpolation) {
234,533✔
UNCOV
257
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
×
UNCOV
258
            dd.second = dd.second + Period(1,Days);
×
UNCOV
259
            Real dp = dd.second - dd.first;
×
UNCOV
260
            Real dt = (d-useLag) - dd.first;
×
261
            // if we are interpolating we only check the exact point
262
            // this prevents falling off the end at curve maturity
UNCOV
263
            InflationTermStructure::checkRange(d, extrapolate);
×
UNCOV
264
            Time t1 = timeFromReference(dd.first);
×
UNCOV
265
            Time t2 = timeFromReference(dd.second);
×
UNCOV
266
            Rate y1 = yoyRateImpl(t1);
×
UNCOV
267
            Rate y2 = yoyRateImpl(t2);
×
268
            yoyRate = y1 + (y2-y1) * (dt/dp);
×
269
        } else {
270
            QL_DEPRECATED_DISABLE_WARNING
271
            if (indexIsInterpolated()) {
234,533✔
UNCOV
272
                InflationTermStructure::checkRange(d-useLag, extrapolate);
×
273
                Time t = timeFromReference(d-useLag);
×
274
                yoyRate = yoyRateImpl(t);
×
275
            } else {
276
                std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
469,066✔
277
                InflationTermStructure::checkRange(dd.first, extrapolate);
234,533✔
278
                Time t = timeFromReference(dd.first);
234,533✔
279
                yoyRate = yoyRateImpl(t);
234,533✔
280
            }
281
            QL_DEPRECATED_ENABLE_WARNING
282
        }
283

284
        if (hasSeasonality()) {
234,533✔
285
            yoyRate = seasonality()->correctYoYRate(d-useLag, yoyRate, *this);
×
286
        }
287
        return yoyRate;
234,533✔
288
    }
289

290
    Rate YoYInflationTermStructure::yoyRate(Time t,
1✔
291
                                            bool extrapolate) const {
292
        checkRange(t, extrapolate);
1✔
293
        return yoyRateImpl(t);
1✔
294
    }
295

296

297

298

299
    std::pair<Date,Date> inflationPeriod(const Date& d,
2,013,784✔
300
                                         Frequency frequency) {
301

302
        Month month = d.month();
2,013,784✔
303
        Year year = d.year();
2,013,784✔
304

305
        Month startMonth, endMonth;
306
        switch (frequency) {
2,013,784✔
307
          case Annual:
308
            startMonth = January;
309
            endMonth = December;
310
            break;
311
          case Semiannual:
1,212✔
312
            if (month <= June) {
1,212✔
313
                startMonth = January;
314
                endMonth = June;
315
            } else {
316
                startMonth = July;
317
                endMonth = December;
318
            }
319
            break;
320
          case Quarterly:
1,214✔
321
            if (month <= March) {
1,214✔
322
                startMonth = January;
323
                endMonth = March;
324
            } else if (month <= June) {
911✔
325
                startMonth = April;
326
                endMonth = June;
327
            } else if (month <= September) {
608✔
328
                startMonth = July;
329
                endMonth = September;
330
            } else {
331
                startMonth = October;
332
                endMonth = December;
333
            }
334
            break;
335
          case Monthly:
600,122✔
336
            startMonth = endMonth = month;
337
            break;
600,122✔
UNCOV
338
          default:
×
339
            QL_FAIL("Frequency not handled: " << frequency);
×
340
            break;
341
        };
342

343
        Date startDate = Date(1, startMonth, year);
2,013,784✔
344
        Date endDate = Date::endOfMonth(Date(1, endMonth, year));
2,013,784✔
345

346
        return std::make_pair(startDate,endDate);
2,013,784✔
347
    }
348

349

350
    Time inflationYearFraction(Frequency f, bool indexIsInterpolated,
3,550✔
351
                               const DayCounter &dayCounter,
352
                               const Date &d1, const Date &d2) {
353

354
        Time t=0;
355
        if (indexIsInterpolated) {
3,550✔
356
            // N.B. we do not use linear interpolation between flat
357
            // fixing forecasts for forecasts.  This avoids awkwardnesses
358
            // when bootstrapping the inflation curve.
UNCOV
359
            t = dayCounter.yearFraction(d1, d2);
×
360
        } else {
361
            // I.e. fixing is constant for the whole inflation period.
362
            // Use the value for half way along the period.
363
            // But the inflation time is the time between period starts
364
            std::pair<Date,Date> limD1 = inflationPeriod(d1, f);
3,550✔
365
            std::pair<Date,Date> limD2 = inflationPeriod(d2, f);
3,550✔
366
            t = dayCounter.yearFraction(limD1.first, limD2.first);
3,550✔
367
        }
368

369
        return t;
3,550✔
370
    }
371

372

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