Coverage Report

Created: 2025-08-05 06:45

/src/quantlib/ql/indexes/inflationindex.hpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2007 Chris Kenyon
5
 Copyright (C) 2021 Ralf Konrad Eckel
6
7
 This file is part of QuantLib, a free-software/open-source library
8
 for financial quantitative analysts and developers - http://quantlib.org/
9
10
 QuantLib is free software: you can redistribute it and/or modify it
11
 under the terms of the QuantLib license.  You should have received a
12
 copy of the license along with this program; if not, please email
13
 <quantlib-dev@lists.sf.net>. The license is also available online at
14
 <http://quantlib.org/license.shtml>.
15
16
 This program is distributed in the hope that it will be useful, but WITHOUT
17
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 FOR A PARTICULAR PURPOSE.  See the license for more details.
19
*/
20
21
/*! \file inflationindex.hpp
22
    \brief base classes for inflation indexes
23
*/
24
25
#ifndef quantlib_inflation_index_hpp
26
#define quantlib_inflation_index_hpp
27
28
#include <ql/currency.hpp>
29
#include <ql/handle.hpp>
30
#include <ql/index.hpp>
31
#include <ql/indexes/region.hpp>
32
#include <ql/termstructures/inflationtermstructure.hpp>
33
34
namespace QuantLib {
35
36
    class ZeroInflationIndex;
37
    class YoYInflationIndex;
38
39
    struct CPI {
40
41
        //! when you observe an index, how do you interpolate between fixings?
42
        enum InterpolationType {
43
            AsIndex, //!< same interpolation as index
44
            Flat,    //!< flat from previous fixing
45
            Linear   //!< linearly between bracketing fixings
46
        };
47
48
        //! interpolated inflation fixing
49
        /*! \param index              The index whose fixing should be retrieved
50
            \param date               The date without lag; usually, the payment
51
                                      date for some inflation-based coupon.
52
            \param observationLag     The observation lag to be subtracted from the
53
                                      passed date; for instance, if the passed date is
54
                                      in May and the lag is three months, the inflation
55
                                      fixing from February (and March, in case of
56
                                      interpolation) will be observed.
57
            \param interpolationType  The interpolation type (flat or linear)
58
        */
59
        static Real laggedFixing(const ext::shared_ptr<ZeroInflationIndex>& index,
60
                                 const Date& date,
61
                                 const Period& observationLag,
62
                                 InterpolationType interpolationType);
63
64
65
        //! interpolated year-on-year inflation rate
66
        /*! \param index              The index whose fixing should be retrieved
67
            \param date               The date without lag; usually, the payment
68
                                      date for some inflation-based coupon.
69
            \param observationLag     The observation lag to be subtracted from the
70
                                      passed date; for instance, if the passed date is
71
                                      in May and the lag is three months, the year-on-year
72
                                      rate from February (and March, in case of
73
                                      interpolation) will be observed.
74
            \param interpolationType  The interpolation type (flat or linear)
75
        */
76
        static Real laggedYoYRate(const ext::shared_ptr<YoYInflationIndex>& index,
77
                                  const Date& date,
78
                                  const Period& observationLag,
79
                                  InterpolationType interpolationType);
80
    };
81
82
83
    //! Base class for inflation-rate indexes,
84
    class InflationIndex : public Index {
85
      public:
86
        InflationIndex(std::string familyName,
87
                       Region region,
88
                       bool revised,
89
                       Frequency frequency,
90
                       const Period& availabilitiyLag,
91
                       Currency currency);
92
93
        //! \name Index interface
94
        //@{
95
        std::string name() const override;
96
97
        /*! Inflation indices are not associated to a particular day,
98
            but to months or quarters.  Therefore, they do not have
99
            fixing calendars.  Since we're forced by the base `Index`
100
            interface to add one, this method returns a NullCalendar
101
            instance.
102
        */
103
        Calendar fixingCalendar() const override;
104
0
        bool isValidFixingDate(const Date&) const override { return true; }
105
106
        /*! Forecasting index values requires an inflation term
107
            structure, with a base date that is earlier than its asof
108
            date.  This must be so because indices are available only
109
            with a lag.  Usually, it makes sense for the base date to
110
            be the first day of the month of the last published
111
            fixing.
112
        */
113
        Real fixing(const Date& fixingDate, bool forecastTodaysFixing = false) const override = 0;
114
115
        //! returns a past fixing at the given date
116
        Real pastFixing(const Date& fixingDate) const override = 0;
117
118
        void addFixing(const Date& fixingDate, Rate fixing, bool forceOverwrite = false) override;
119
        //@}
120
121
        //! \name Inspectors
122
        //@{
123
        std::string familyName() const;
124
        Region region() const;
125
        bool revised() const;
126
        Frequency frequency() const;
127
        /*! The availability lag describes when the index might be
128
            available; for instance, the inflation value for January
129
            may only be available in April.  This doesn't mean that
130
            that inflation value is considered as the April fixing; it
131
            remains the January fixing, independently of the lag in
132
            availability.
133
        */
134
        Period availabilityLag() const;
135
        Currency currency() const;
136
        //@}
137
138
      protected:
139
        Date referenceDate_;
140
        std::string familyName_;
141
        Region region_;
142
        bool revised_;
143
        Frequency frequency_;
144
        Period availabilityLag_;
145
        Currency currency_;
146
147
      private:
148
        std::string name_;
149
    };
150
151
152
    //! Base class for zero inflation indices.
153
    class ZeroInflationIndex : public InflationIndex {
154
      public:
155
        ZeroInflationIndex(
156
            const std::string& familyName,
157
            const Region& region,
158
            bool revised,
159
            Frequency frequency,
160
            const Period& availabilityLag,
161
            const Currency& currency,
162
            Handle<ZeroInflationTermStructure> ts = {});
163
164
        //! \name Index interface
165
        //@{
166
        /*! \warning the forecastTodaysFixing parameter (required by
167
                     the Index interface) is currently ignored.
168
        */
169
        Real fixing(const Date& fixingDate, bool forecastTodaysFixing = false) const override;
170
        Real pastFixing(const Date& fixingDate) const override;
171
        //@}
172
        //! \name Other methods
173
        //@{
174
        Date lastFixingDate() const;
175
        Handle<ZeroInflationTermStructure> zeroInflationTermStructure() const;
176
        ext::shared_ptr<ZeroInflationIndex> clone(const Handle<ZeroInflationTermStructure>& h) const;
177
        bool needsForecast(const Date& fixingDate) const;
178
        //@}
179
      private:
180
        Real forecastFixing(const Date& fixingDate) const;
181
        Handle<ZeroInflationTermStructure> zeroInflation_;
182
    };
183
184
185
    //! Base class for year-on-year inflation indices.
186
    /*! These may be quoted indices published on, say, Bloomberg, or can be
187
        defined as the ratio of an index at different time points.
188
    */
189
    class YoYInflationIndex : public InflationIndex {
190
      public:
191
        //! \name Constructors
192
        //@{
193
        //! Constructor for year-on-year indices defined as a ratio.
194
        /*! An index build with this constructor won't store
195
            past fixings of its own; they will be calculated as a
196
            ratio from the past fixings stored in the underlying index.
197
        */
198
        explicit YoYInflationIndex(
199
            const ext::shared_ptr<ZeroInflationIndex>& underlyingIndex,
200
            Handle<YoYInflationTermStructure> ts = {});
201
202
        /*! \deprecated Use the similar overload without the interpolated parameter.
203
                        Deprecated in version 1.38.
204
        */
205
        [[deprecated("Use the similar overload without the interpolated parameter")]]
206
        YoYInflationIndex(
207
            const ext::shared_ptr<ZeroInflationIndex>& underlyingIndex,
208
            bool interpolated,
209
            Handle<YoYInflationTermStructure> ts = {});
210
211
        //! Constructor for quoted year-on-year indices.
212
        /*! An index built with this constructor needs its past
213
            fixings (i.e., the past year-on-year values) to be stored
214
            via the `addFixing` or `addFixings` method.
215
        */
216
        YoYInflationIndex(
217
            const std::string& familyName,
218
            const Region& region,
219
            bool revised,
220
            Frequency frequency,
221
            const Period& availabilityLag,
222
            const Currency& currency,
223
            Handle<YoYInflationTermStructure> ts = {});
224
225
        /*! \deprecated Use the similar overload without the interpolated parameter.
226
                        Deprecated in version 1.38.
227
        */
228
        [[deprecated("Use the similar overload without the interpolated parameter")]]
229
        YoYInflationIndex(
230
            const std::string& familyName,
231
            const Region& region,
232
            bool revised,
233
            bool interpolated,
234
            Frequency frequency,
235
            const Period& availabilityLag,
236
            const Currency& currency,
237
            Handle<YoYInflationTermStructure> ts = {});
238
        //@}
239
240
        //! \name Index interface
241
        //@{
242
        /*! \warning the forecastTodaysFixing parameter (required by
243
                     the Index interface) is currently ignored.
244
        */
245
        Rate fixing(const Date& fixingDate, bool forecastTodaysFixing = false) const override;
246
        Real pastFixing(const Date& fixingDate) const override;
247
        //@}
248
249
        //! \name Other methods
250
        //@{
251
        Date lastFixingDate() const;
252
        bool interpolated() const;
253
        bool ratio() const;
254
        ext::shared_ptr<ZeroInflationIndex> underlyingIndex() const;
255
        Handle<YoYInflationTermStructure> yoyInflationTermStructure() const;
256
257
        ext::shared_ptr<YoYInflationIndex> clone(const Handle<YoYInflationTermStructure>& h) const;
258
        bool needsForecast(const Date& fixingDate) const;
259
        //@}
260
261
      protected:
262
        bool interpolated_;
263
264
      private:
265
        Rate forecastFixing(const Date& fixingDate) const;
266
        bool ratio_;
267
        ext::shared_ptr<ZeroInflationIndex> underlyingIndex_;
268
        Handle<YoYInflationTermStructure> yoyInflation_;
269
    };
270
271
272
    namespace detail::CPI {
273
274
        // Returns either CPI::Flat or CPI::Linear depending on the combination of index and
275
        // CPI::InterpolationType.
276
        QuantLib::CPI::InterpolationType
277
        effectiveInterpolationType(const QuantLib::CPI::InterpolationType& type);
278
279
        QuantLib::CPI::InterpolationType
280
        effectiveInterpolationType(const QuantLib::CPI::InterpolationType& type,
281
                                   const ext::shared_ptr<YoYInflationIndex>& index);
282
283
        // checks whether the combination of index and CPI::InterpolationType results
284
        // effectively in CPI::Linear
285
        bool isInterpolated(const QuantLib::CPI::InterpolationType& type);
286
287
        bool isInterpolated(const QuantLib::CPI::InterpolationType& type,
288
                            const ext::shared_ptr<YoYInflationIndex>& index);
289
290
    }
291
292
293
    // inline
294
295
0
    inline std::string InflationIndex::name() const {
296
0
        return name_;
297
0
    }
298
299
0
    inline std::string InflationIndex::familyName() const {
300
0
        return familyName_;
301
0
    }
302
303
0
    inline Region InflationIndex::region() const {
304
0
        return region_;
305
0
    }
306
307
0
    inline bool InflationIndex::revised() const {
308
0
        return revised_;
309
0
    }
310
311
0
    inline Frequency InflationIndex::frequency() const {
312
0
        return frequency_;
313
0
    }
314
315
0
    inline Period InflationIndex::availabilityLag() const {
316
0
        return availabilityLag_;
317
0
    }
318
319
0
    inline Currency InflationIndex::currency() const {
320
0
        return currency_;
321
0
    }
322
323
    inline Handle<ZeroInflationTermStructure>
324
0
    ZeroInflationIndex::zeroInflationTermStructure() const {
325
0
        return zeroInflation_;
326
0
    }
327
328
0
    inline bool YoYInflationIndex::interpolated() const {
329
0
        return interpolated_;
330
0
    }
331
332
0
    inline bool YoYInflationIndex::ratio() const {
333
0
        return ratio_;
334
0
    }
335
336
0
    inline ext::shared_ptr<ZeroInflationIndex> YoYInflationIndex::underlyingIndex() const {
337
0
        return underlyingIndex_;
338
0
    }
339
340
    inline Handle<YoYInflationTermStructure>
341
0
    YoYInflationIndex::yoyInflationTermStructure() const {
342
0
        return yoyInflation_;
343
0
    }
344
345
}
346
347
#endif