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

lballabio / QuantLib / 11328508063

14 Oct 2024 01:24PM UTC coverage: 72.674% (+0.05%) from 72.621%
11328508063

push

github

lballabio
Pin Ubuntu version in coverage workflow

55158 of 75898 relevant lines covered (72.67%)

8693210.46 hits per line

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

43.96
/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,903✔
126
        if (hasExplicitBaseDate()) {
238,903✔
127
            return baseDate_;
238,903✔
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,972✔
146
                                            bool extrapolate) const {
147
        QL_REQUIRE(d >= baseDate(),
238,972✔
148
                   "date (" << d << ") is before base date (" << baseDate() << ")");
149
        QL_REQUIRE(extrapolate || allowsExtrapolation() || d <= maxDate(),
238,972✔
150
                   "date (" << d << ") is past max curve date ("
151
                   << maxDate() << ")");
152
    }
238,972✔
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
    YoYInflationTermStructure::YoYInflationTermStructure(
×
267
                                    Date baseDate,
268
                                    Rate baseYoYRate,
269
                                    Frequency frequency,
270
                                    bool indexIsInterpolated,
271
                                    const DayCounter& dayCounter,
272
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
273
    : InflationTermStructure(baseDate, frequency, dayCounter, seasonality, baseYoYRate),
274
      indexIsInterpolated_(indexIsInterpolated) {}
×
275

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

288
    YoYInflationTermStructure::YoYInflationTermStructure(
×
289
                                    Natural settlementDays,
290
                                    const Calendar& calendar,
291
                                    Date baseDate,
292
                                    Rate baseYoYRate,
293
                                    Frequency frequency,
294
                                    bool indexIsInterpolated,
295
                                    const DayCounter& dayCounter,
296
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
297
    : InflationTermStructure(settlementDays, calendar, baseDate, frequency,
298
                             dayCounter, seasonality, baseYoYRate),
299
      indexIsInterpolated_(indexIsInterpolated) {}
×
300

301
    QL_DEPRECATED_DISABLE_WARNING
302

303
    YoYInflationTermStructure::YoYInflationTermStructure(
×
304
                                    const DayCounter& dayCounter,
305
                                    Rate baseYoYRate,
306
                                    const Period& observationLag,
307
                                    Frequency frequency,
308
                                    bool indexIsInterpolated,
309
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
310
    : InflationTermStructure(baseYoYRate, observationLag, frequency,
311
                             dayCounter, seasonality),
312
      indexIsInterpolated_(indexIsInterpolated) {}
×
313

314
    YoYInflationTermStructure::YoYInflationTermStructure(
1✔
315
                                    const Date& referenceDate,
316
                                    const Calendar& calendar,
317
                                    const DayCounter& dayCounter,
318
                                    Rate baseYoYRate,
319
                                    const Period& observationLag,
320
                                    Frequency frequency,
321
                                    bool indexIsInterpolated,
322
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
323
    : InflationTermStructure(referenceDate, baseYoYRate, observationLag, frequency,
324
                             calendar, dayCounter, seasonality),
325
      indexIsInterpolated_(indexIsInterpolated) {}
2✔
326

327
    YoYInflationTermStructure::YoYInflationTermStructure(
×
328
                                    Natural settlementDays,
329
                                    const Calendar& calendar,
330
                                    const DayCounter& dayCounter,
331
                                    Rate baseYoYRate,
332
                                    const Period& observationLag,
333
                                    Frequency frequency,
334
                                    bool indexIsInterpolated,
335
                                    const ext::shared_ptr<Seasonality> &seasonality)
×
336
    : InflationTermStructure(settlementDays, calendar, baseYoYRate, observationLag,
337
                             frequency, dayCounter, seasonality),
338
      indexIsInterpolated_(indexIsInterpolated) {}
×
339

340
    QL_DEPRECATED_ENABLE_WARNING
341

342

343
    Rate YoYInflationTermStructure::yoyRate(const Date &d, const Period& instObsLag,
234,809✔
344
                                              bool forceLinearInterpolation,
345
                                              bool extrapolate) const {
346

347
        Period useLag = instObsLag;
234,809✔
348
        if (instObsLag == Period(-1,Days)) {
234,809✔
349
            useLag = hasExplicitBaseDate() ? Period(0, Days) : observationLag();
28✔
350
        }
351

352
        Rate yoyRate;
353
        if (forceLinearInterpolation) {
234,809✔
354
            std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
×
355
            dd.second = dd.second + Period(1,Days);
×
356
            Real dp = dd.second - dd.first;
×
357
            Real dt = (d-useLag) - dd.first;
×
358
            // if we are interpolating we only check the exact point
359
            // this prevents falling off the end at curve maturity
360
            InflationTermStructure::checkRange(d, extrapolate);
×
361
            Time t1 = timeFromReference(dd.first);
×
362
            Time t2 = timeFromReference(dd.second);
×
363
            Rate y1 = yoyRateImpl(t1);
×
364
            Rate y2 = yoyRateImpl(t2);
×
365
            yoyRate = y1 + (y2-y1) * (dt/dp);
×
366
        } else {
367
            if (indexIsInterpolated()) {
234,809✔
368
                InflationTermStructure::checkRange(d-useLag, extrapolate);
23,049✔
369
                Time t = timeFromReference(d-useLag);
23,049✔
370
                yoyRate = yoyRateImpl(t);
23,049✔
371
            } else {
372
                std::pair<Date,Date> dd = inflationPeriod(d-useLag, frequency());
423,520✔
373
                InflationTermStructure::checkRange(dd.first, extrapolate);
211,760✔
374
                Time t = timeFromReference(dd.first);
211,760✔
375
                yoyRate = yoyRateImpl(t);
211,760✔
376
            }
377
        }
378

379
        if (hasSeasonality()) {
234,809✔
380
            yoyRate = seasonality()->correctYoYRate(d-useLag, yoyRate, *this);
×
381
        }
382
        return yoyRate;
234,809✔
383
    }
384

385
    Rate YoYInflationTermStructure::yoyRate(Time t,
×
386
                                            bool extrapolate) const {
387
        checkRange(t, extrapolate);
×
388
        return yoyRateImpl(t);
×
389
    }
390

391

392

393

394
    std::pair<Date,Date> inflationPeriod(const Date& d,
1,991,125✔
395
                                         Frequency frequency) {
396

397
        Month month = d.month();
1,991,125✔
398
        Year year = d.year();
1,991,125✔
399

400
        Month startMonth, endMonth;
401
        switch (frequency) {
1,991,125✔
402
          case Annual:
403
            startMonth = January;
404
            endMonth = December;
405
            break;
406
          case Semiannual:
1,212✔
407
            if (month <= June) {
1,212✔
408
                startMonth = January;
409
                endMonth = June;
410
            } else {
411
                startMonth = July;
412
                endMonth = December;
413
            }
414
            break;
415
          case Quarterly:
1,214✔
416
            if (month <= March) {
1,214✔
417
                startMonth = January;
418
                endMonth = March;
419
            } else if (month <= June) {
911✔
420
                startMonth = April;
421
                endMonth = June;
422
            } else if (month <= September) {
608✔
423
                startMonth = July;
424
                endMonth = September;
425
            } else {
426
                startMonth = October;
427
                endMonth = December;
428
            }
429
            break;
430
          case Monthly:
577,463✔
431
            startMonth = endMonth = month;
432
            break;
577,463✔
433
          default:
×
434
            QL_FAIL("Frequency not handled: " << frequency);
×
435
            break;
436
        };
437

438
        Date startDate = Date(1, startMonth, year);
1,991,125✔
439
        Date endDate = Date::endOfMonth(Date(1, endMonth, year));
1,991,125✔
440

441
        return std::make_pair(startDate,endDate);
1,991,125✔
442
    }
443

444

445
    Time inflationYearFraction(Frequency f, bool indexIsInterpolated,
4,246✔
446
                               const DayCounter &dayCounter,
447
                               const Date &d1, const Date &d2) {
448

449
        Time t=0;
450
        if (indexIsInterpolated) {
4,246✔
451
            // N.B. we do not use linear interpolation between flat
452
            // fixing forecasts for forecasts.  This avoids awkwardnesses
453
            // when bootstrapping the inflation curve.
454
            t = dayCounter.yearFraction(d1, d2);
×
455
        } else {
456
            // I.e. fixing is constant for the whole inflation period.
457
            // Use the value for half way along the period.
458
            // But the inflation time is the time between period starts
459
            std::pair<Date,Date> limD1 = inflationPeriod(d1, f);
4,246✔
460
            std::pair<Date,Date> limD2 = inflationPeriod(d2, f);
4,246✔
461
            t = dayCounter.yearFraction(limD1.first, limD2.first);
4,246✔
462
        }
463

464
        return t;
4,246✔
465
    }
466

467

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