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

lballabio / QuantLib / 11398665858

18 Oct 2024 06:30AM UTC coverage: 72.784% (-0.02%) from 72.803%
11398665858

push

github

web-flow
Deprecate `indexIsInterpolated` parameter in YoY inflation curves (#2099)

4 of 20 new or added lines in 3 files covered. (20.0%)

5 existing lines in 1 file now uncovered.

55238 of 75893 relevant lines covered (72.78%)

8704329.15 hits per line

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

39.09
/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
    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
      hasExplicitBaseDate_(true) {
×
35
        if (seasonality_ != nullptr) {
×
36
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
37
                       "Seasonality inconsistent with inflation term structure");
38
        }
39
    }
×
40

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

74
    InflationTermStructure::InflationTermStructure(
×
75
                                        Rate baseRate,
76
                                        const Period& observationLag,
77
                                        Frequency frequency,
78
                                        const DayCounter& dayCounter,
79
                                        ext::shared_ptr<Seasonality> seasonality)
×
80
    : TermStructure(dayCounter), seasonality_(std::move(seasonality)),
×
81
      observationLag_(observationLag), frequency_(frequency),
×
82
      baseRate_(baseRate),
×
83
      hasExplicitBaseDate_(false) {
×
84
        if (seasonality_ != nullptr) {
×
85
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
86
                       "Seasonality inconsistent with inflation term structure");
87
        }
88
    }
×
89

90
    InflationTermStructure::InflationTermStructure(
2✔
91
                                        const Date& referenceDate,
92
                                        Rate baseRate,
93
                                        const Period& observationLag,
94
                                        Frequency frequency,
95
                                        const Calendar& calendar,
96
                                        const DayCounter& dayCounter,
97
                                        ext::shared_ptr<Seasonality> seasonality)
×
98
    : TermStructure(referenceDate, calendar, dayCounter), seasonality_(std::move(seasonality)),
2✔
99
      observationLag_(observationLag), frequency_(frequency), baseRate_(baseRate),
2✔
100
      hasExplicitBaseDate_(false) {
6✔
101
        if (seasonality_ != nullptr) {
2✔
102
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
103
                       "Seasonality inconsistent with inflation term structure");
104
        }
105
    }
2✔
106

107
    InflationTermStructure::InflationTermStructure(
×
108
                                        Natural settlementDays,
109
                                        const Calendar& calendar,
110
                                        Rate baseRate,
111
                                        const Period& observationLag,
112
                                        Frequency frequency,
113
                                        const DayCounter &dayCounter,
114
                                        ext::shared_ptr<Seasonality> seasonality)
×
115
    : TermStructure(settlementDays, calendar, dayCounter), seasonality_(std::move(seasonality)),
×
116
      observationLag_(observationLag), frequency_(frequency),
×
117
      baseRate_(baseRate),
×
118
      hasExplicitBaseDate_(false) {
×
119
        if (seasonality_ != nullptr) {
×
120
            QL_REQUIRE(seasonality_->isConsistent(*this),
×
121
                       "Seasonality inconsistent with inflation term structure");
122
        }
123
    }
×
124

125
    Date InflationTermStructure::baseDate() const {
238,906✔
126
        if (hasExplicitBaseDate()) {
238,906✔
127
            return baseDate_;
238,906✔
128
        } else {
129
            return inflationPeriod(referenceDate() - observationLag(), frequency()).first;
×
130
        }
131
    }
132

133
    void InflationTermStructure::setSeasonality(
5✔
134
                          const ext::shared_ptr<Seasonality>& seasonality) {
135
        // always reset, whether with null or new pointer
136
        seasonality_ = seasonality;
5✔
137
        if (seasonality_ != nullptr) {
5✔
138
            QL_REQUIRE(seasonality_->isConsistent(*this),
4✔
139
                       "Seasonality inconsistent with inflation term structure");
140
        }
141
        update();
5✔
142
    }
5✔
143

144

145
    void InflationTermStructure::checkRange(const Date& d,
238,975✔
146
                                            bool extrapolate) const {
147
        QL_REQUIRE(d >= baseDate(),
238,975✔
148
                   "date (" << d << ") is before base date (" << baseDate() << ")");
149
        QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(),
238,975✔
150
                   "date (" << d << ") is past max curve date ("
151
                   << maxDate() << ")");
152
    }
238,975✔
153

154
    void InflationTermStructure::checkRange(Time t,
×
155
                                            bool extrapolate) const {
156
        QL_REQUIRE(t >= timeFromReference(baseDate()),
×
157
                   "time (" << t << ") is before base date");
158
        QL_REQUIRE(extrapolate || allowsExtrapolation() || t <= maxTime(),
×
159
                   "time (" << t << ") is past max curve time ("
160
                   << maxTime() << ")");
161
    }
×
162

163

164
    ZeroInflationTermStructure::ZeroInflationTermStructure(
×
165
                                   Date baseDate,
166
                                   Frequency frequency,
167
                                   const DayCounter& dayCounter,
168
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
169
    : InflationTermStructure(baseDate, frequency, dayCounter, seasonality) {}
×
170

171
    ZeroInflationTermStructure::ZeroInflationTermStructure(
13✔
172
                                   const Date& referenceDate,
173
                                   Date baseDate,
174
                                   Frequency frequency,
175
                                   const DayCounter& dayCounter,
176
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
177
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality) {}
26✔
178

179
    ZeroInflationTermStructure::ZeroInflationTermStructure(
×
180
                                   Natural settlementDays,
181
                                   const Calendar& calendar,
182
                                   Date baseDate,
183
                                   Frequency frequency,
184
                                   const DayCounter& dayCounter,
185
                                   const ext::shared_ptr<Seasonality>& seasonality)
×
186
    : InflationTermStructure(settlementDays, calendar, baseDate, frequency, dayCounter, seasonality) {}
×
187

188
    QL_DEPRECATED_DISABLE_WARNING
189

190
    ZeroInflationTermStructure::ZeroInflationTermStructure(
×
191
                                    const DayCounter& dayCounter,
192
                                    Rate baseZeroRate,
193
                                    const Period& observationLag,
194
                                    Frequency frequency,
195
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
196
    : InflationTermStructure(baseZeroRate, observationLag, frequency,
197
                             dayCounter, seasonality) {}
×
198

199
    ZeroInflationTermStructure::ZeroInflationTermStructure(
1✔
200
                                    const Date& referenceDate,
201
                                    const Calendar& calendar,
202
                                    const DayCounter& dayCounter,
203
                                    Rate baseZeroRate,
204
                                    const Period& observationLag,
205
                                    Frequency frequency,
206
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
207
    : InflationTermStructure(referenceDate, baseZeroRate, observationLag, frequency,
208
                             calendar, dayCounter, seasonality) {}
2✔
209

210
    ZeroInflationTermStructure::ZeroInflationTermStructure(
×
211
                                    Natural settlementDays,
212
                                    const Calendar& calendar,
213
                                    const DayCounter& dayCounter,
214
                                    Rate baseZeroRate,
215
                                    const Period& observationLag,
216
                                    Frequency frequency,
217
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
218
    : InflationTermStructure(settlementDays, calendar, baseZeroRate, observationLag, frequency,
219
                             dayCounter, seasonality) {}
×
220

221
    QL_DEPRECATED_ENABLE_WARNING
222

223
    Rate ZeroInflationTermStructure::zeroRate(const Date &d, const Period& instObsLag,
4,163✔
224
                                              bool forceLinearInterpolation,
225
                                              bool extrapolate) const {
226

227
        Period useLag = instObsLag;
4,163✔
228
        if (instObsLag == Period(-1,Days)) {
4,163✔
229
            useLag = hasExplicitBaseDate() ? Period(0, Days) : observationLag();
×
230
        }
231

232
        Rate zeroRate;
233
        if (forceLinearInterpolation) {
4,163✔
234
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
×
235
            dd.second = dd.second + Period(1,Days);
×
236
            Real dp = dd.second - dd.first;
×
237
            Real dt = d - dd.first;
×
238
            // if we are interpolating we only check the exact point
239
            // this prevents falling off the end at curve maturity
240
            InflationTermStructure::checkRange(d, extrapolate);
×
241
            Time t1 = timeFromReference(dd.first);
×
242
            Time t2 = timeFromReference(dd.second);
×
243
            Rate z1 = zeroRateImpl(t1);
×
244
            Rate z2 = zeroRateImpl(t2);
×
245
            zeroRate = z1 + (z2-z1) * (dt/dp);
×
246
        } else {
247
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
8,326✔
248
            InflationTermStructure::checkRange(dd.first, extrapolate);
4,163✔
249
            Time t = timeFromReference(dd.first);
4,163✔
250
            zeroRate = zeroRateImpl(t);
4,163✔
251
        }
252

253
        if (hasSeasonality()) {
4,163✔
254
            zeroRate = seasonality()->correctZeroRate(d-useLag, zeroRate, *this);
374✔
255
        }
256
        return zeroRate;
4,163✔
257
    }
258

259
    Rate ZeroInflationTermStructure::zeroRate(Time t,
×
260
                                              bool extrapolate) const {
261
        checkRange(t, extrapolate);
×
262
        return zeroRateImpl(t);
×
263
    }
264

265

266
    QL_DEPRECATED_DISABLE_WARNING
267

NEW
268
    YoYInflationTermStructure::YoYInflationTermStructure(
×
269
                                    Date baseDate,
270
                                    Rate baseYoYRate,
271
                                    Frequency frequency,
272
                                    const DayCounter& dayCounter,
NEW
273
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
NEW
274
    : InflationTermStructure(baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
×
275

276
    YoYInflationTermStructure::YoYInflationTermStructure(
10✔
277
                                    const Date& referenceDate,
278
                                    Date baseDate,
279
                                    Rate baseYoYRate,
280
                                    Frequency frequency,
281
                                    const DayCounter& dayCounter,
NEW
282
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
283
    : InflationTermStructure(referenceDate, baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
20✔
284

NEW
285
    YoYInflationTermStructure::YoYInflationTermStructure(
×
286
                                    Natural settlementDays,
287
                                    const Calendar& calendar,
288
                                    Date baseDate,
289
                                    Rate baseYoYRate,
290
                                    Frequency frequency,
291
                                    const DayCounter& dayCounter,
NEW
292
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
NEW
293
    : InflationTermStructure(settlementDays, calendar, baseDate, frequency, dayCounter, seasonality, baseYoYRate) {}
×
294

UNCOV
295
    YoYInflationTermStructure::YoYInflationTermStructure(
×
296
                                    Date baseDate,
297
                                    Rate baseYoYRate,
298
                                    Frequency frequency,
299
                                    bool indexIsInterpolated,
300
                                    const DayCounter& dayCounter,
301
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
NEW
302
    : YoYInflationTermStructure(baseDate, baseYoYRate, frequency, dayCounter, seasonality) {
×
NEW
303
        indexIsInterpolated_ = indexIsInterpolated;
×
NEW
304
    }
×
305

UNCOV
306
    YoYInflationTermStructure::YoYInflationTermStructure(
×
307
                                    const Date& referenceDate,
308
                                    Date baseDate,
309
                                    Rate baseYoYRate,
310
                                    Frequency frequency,
311
                                    bool indexIsInterpolated,
312
                                    const DayCounter& dayCounter,
313
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
314
    : YoYInflationTermStructure(referenceDate, baseDate, baseYoYRate,
NEW
315
                                frequency, dayCounter, seasonality) {
×
NEW
316
        indexIsInterpolated_ = indexIsInterpolated;
×
NEW
317
    }
×
318

319
    YoYInflationTermStructure::YoYInflationTermStructure(
×
320
                                    Natural settlementDays,
321
                                    const Calendar& calendar,
322
                                    Date baseDate,
323
                                    Rate baseYoYRate,
324
                                    Frequency frequency,
325
                                    bool indexIsInterpolated,
326
                                    const DayCounter& dayCounter,
327
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
328
    : YoYInflationTermStructure(settlementDays, calendar, baseDate, baseYoYRate,
NEW
329
                                frequency, dayCounter, seasonality) {
×
NEW
330
        indexIsInterpolated_ = indexIsInterpolated;
×
NEW
331
    }
×
332

333
    YoYInflationTermStructure::YoYInflationTermStructure(
×
334
                                    const DayCounter& dayCounter,
335
                                    Rate baseYoYRate,
336
                                    const Period& observationLag,
337
                                    Frequency frequency,
338
                                    bool indexIsInterpolated,
339
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
340
    : InflationTermStructure(baseYoYRate, observationLag, frequency,
341
                             dayCounter, seasonality),
342
      indexIsInterpolated_(indexIsInterpolated) {}
×
343

344
    YoYInflationTermStructure::YoYInflationTermStructure(
1✔
345
                                    const Date& referenceDate,
346
                                    const Calendar& calendar,
347
                                    const DayCounter& dayCounter,
348
                                    Rate baseYoYRate,
349
                                    const Period& observationLag,
350
                                    Frequency frequency,
351
                                    bool indexIsInterpolated,
352
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
353
    : InflationTermStructure(referenceDate, baseYoYRate, observationLag, frequency,
354
                             calendar, dayCounter, seasonality),
355
      indexIsInterpolated_(indexIsInterpolated) {}
2✔
356

357
    YoYInflationTermStructure::YoYInflationTermStructure(
×
358
                                    Natural settlementDays,
359
                                    const Calendar& calendar,
360
                                    const DayCounter& dayCounter,
361
                                    Rate baseYoYRate,
362
                                    const Period& observationLag,
363
                                    Frequency frequency,
364
                                    bool indexIsInterpolated,
365
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
366
    : InflationTermStructure(settlementDays, calendar, baseYoYRate, observationLag,
367
                             frequency, dayCounter, seasonality),
368
      indexIsInterpolated_(indexIsInterpolated) {}
×
369

370
    QL_DEPRECATED_ENABLE_WARNING
371

372
    Rate YoYInflationTermStructure::yoyRate(const Date &d, const Period& instObsLag,
234,812✔
373
                                            bool forceLinearInterpolation,
374
                                            bool extrapolate) const {
375

376
        Period useLag = instObsLag;
234,812✔
377
        if (instObsLag == Period(-1,Days)) {
234,812✔
378
            useLag = hasExplicitBaseDate() ? Period(0, Days) : observationLag();
28✔
379
        }
380

381
        Rate yoyRate;
382
        if (forceLinearInterpolation) {
234,812✔
383
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
×
384
            dd.second = dd.second + Period(1,Days);
×
385
            Real dp = dd.second - dd.first;
×
386
            Real dt = (d-useLag) - dd.first;
×
387
            // if we are interpolating we only check the exact point
388
            // this prevents falling off the end at curve maturity
389
            InflationTermStructure::checkRange(d, extrapolate);
×
390
            Time t1 = timeFromReference(dd.first);
×
391
            Time t2 = timeFromReference(dd.second);
×
392
            Rate y1 = yoyRateImpl(t1);
×
393
            Rate y2 = yoyRateImpl(t2);
×
394
            yoyRate = y1 + (y2-y1) * (dt/dp);
×
395
        } else {
396
            QL_DEPRECATED_DISABLE_WARNING
397
            if (indexIsInterpolated()) {
234,812✔
UNCOV
398
                InflationTermStructure::checkRange(d-useLag, extrapolate);
×
UNCOV
399
                Time t = timeFromReference(d-useLag);
×
UNCOV
400
                yoyRate = yoyRateImpl(t);
×
401
            } else {
402
                std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
469,624✔
403
                InflationTermStructure::checkRange(dd.first, extrapolate);
234,812✔
404
                Time t = timeFromReference(dd.first);
234,812✔
405
                yoyRate = yoyRateImpl(t);
234,812✔
406
            }
407
            QL_DEPRECATED_ENABLE_WARNING
408
        }
409

410
        if (hasSeasonality()) {
234,812✔
411
            yoyRate = seasonality()->correctYoYRate(d-useLag, yoyRate, *this);
×
412
        }
413
        return yoyRate;
234,812✔
414
    }
415

416
    Rate YoYInflationTermStructure::yoyRate(Time t,
×
417
                                            bool extrapolate) const {
418
        checkRange(t, extrapolate);
×
419
        return yoyRateImpl(t);
×
420
    }
421

422

423

424

425
    std::pair<Date,Date> inflationPeriod(const Date& d,
2,014,159✔
426
                                         Frequency frequency) {
427

428
        Month month = d.month();
2,014,159✔
429
        Year year = d.year();
2,014,159✔
430

431
        Month startMonth, endMonth;
432
        switch (frequency) {
2,014,159✔
433
          case Annual:
434
            startMonth = January;
435
            endMonth = December;
436
            break;
437
          case Semiannual:
1,212✔
438
            if (month <= June) {
1,212✔
439
                startMonth = January;
440
                endMonth = June;
441
            } else {
442
                startMonth = July;
443
                endMonth = December;
444
            }
445
            break;
446
          case Quarterly:
1,214✔
447
            if (month <= March) {
1,214✔
448
                startMonth = January;
449
                endMonth = March;
450
            } else if (month <= June) {
911✔
451
                startMonth = April;
452
                endMonth = June;
453
            } else if (month <= September) {
608✔
454
                startMonth = July;
455
                endMonth = September;
456
            } else {
457
                startMonth = October;
458
                endMonth = December;
459
            }
460
            break;
461
          case Monthly:
600,497✔
462
            startMonth = endMonth = month;
463
            break;
600,497✔
464
          default:
×
465
            QL_FAIL("Frequency not handled: " << frequency);
×
466
            break;
467
        };
468

469
        Date startDate = Date(1, startMonth, year);
2,014,159✔
470
        Date endDate = Date::endOfMonth(Date(1, endMonth, year));
2,014,159✔
471

472
        return std::make_pair(startDate,endDate);
2,014,159✔
473
    }
474

475

476
    Time inflationYearFraction(Frequency f, bool indexIsInterpolated,
4,246✔
477
                               const DayCounter &dayCounter,
478
                               const Date &d1, const Date &d2) {
479

480
        Time t=0;
481
        if (indexIsInterpolated) {
4,246✔
482
            // N.B. we do not use linear interpolation between flat
483
            // fixing forecasts for forecasts.  This avoids awkwardnesses
484
            // when bootstrapping the inflation curve.
485
            t = dayCounter.yearFraction(d1, d2);
×
486
        } else {
487
            // I.e. fixing is constant for the whole inflation period.
488
            // Use the value for half way along the period.
489
            // But the inflation time is the time between period starts
490
            std::pair<Date,Date> limD1 = inflationPeriod(d1, f);
4,246✔
491
            std::pair<Date,Date> limD2 = inflationPeriod(d2, f);
4,246✔
492
            t = dayCounter.yearFraction(limD1.first, limD2.first);
4,246✔
493
        }
494

495
        return t;
4,246✔
496
    }
497

498

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