Coverage Report

Created: 2026-09-28 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/termstructures/inflation/inflationtraits.hpp
Line
Count
Source
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) 2007, 2008 StatPro Italia srl
6
 Copyright (C) 2011 Ferdinando Ametrano
7
8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10
11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <https://www.quantlib.org/license.shtml>.
16
17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21
22
/*! \file inflationtraits.hpp
23
    \brief inflation bootstrap traits
24
*/
25
26
#ifndef ql_inflation_bootstrap_traits_hpp
27
#define ql_inflation_bootstrap_traits_hpp
28
29
#include <ql/math/array.hpp>
30
#include <ql/termstructures/inflation/interpolatedzeroinflationcurve.hpp>
31
#include <ql/termstructures/inflation/interpolatedyoyinflationcurve.hpp>
32
#include <ql/termstructures/bootstraphelper.hpp>
33
#include <utility>
34
35
namespace QuantLib {
36
37
    namespace detail {
38
        constexpr double avgInflation = 0.02;
39
        constexpr double maxInflation = 0.5;
40
    }
41
42
    //! Bootstrap traits to use for PiecewiseZeroInflationCurve
43
    class ZeroInflationTraits {
44
      public:
45
        typedef BootstrapHelper<ZeroInflationTermStructure> helper;
46
47
        // start of curve data
48
0
        static Date initialDate(const ZeroInflationTermStructure* t) {
49
0
            return t->baseDate();
50
0
        }
51
        // value at reference date
52
0
        static Rate initialValue(const ZeroInflationTermStructure*) {
53
0
            // this will be overwritten during bootstrap
54
0
            return detail::avgInflation;
55
0
        }
56
57
        // guesses
58
        template <class C>
59
        static Rate guess(Size i,
60
                          const C* c,
61
                          bool validData,
62
                          Size) // firstAliveHelper
63
        {
64
            if (validData) // previous iteration value
65
                return c->data()[i];
66
67
            return detail::avgInflation;
68
        }
69
70
        // guess for the whole curve and whether it needs to be transformed
71
        template <class C>
72
        static std::pair<Array, bool> globalGuess(const C* c, bool validData)
73
        {
74
            if (validData)
75
                return {Array(c->data().begin() + 1, c->data().end()), true};
76
77
            return {Array(c->times().size() - 1, detail::avgInflation), true};
78
        }
79
80
        // constraints
81
        template <class C>
82
        static Rate minValueAfter(Size,
83
                                  const C* c,
84
                                  bool validData,
85
                                  Size) // firstAliveHelper
86
        {
87
            if (validData) {
88
                Rate r = *(std::min_element(c->data().begin(), c->data().end()));
89
                return r<0.0 ? Real(r*2.0) : r/2.0;
90
            }
91
            return -detail::maxInflation;
92
        }
93
        template <class C>
94
        static Rate maxValueAfter(Size,
95
                                  const C* c,
96
                                  bool validData,
97
                                  Size) // firstAliveHelper
98
        {
99
            if (validData) {
100
                Rate r = *(std::max_element(c->data().begin(), c->data().end()));
101
                return r<0.0 ? Real(r/2.0) : r*2.0;
102
            }
103
            // no constraints.
104
            // We choose as max a value very unlikely to be exceeded.
105
            return detail::maxInflation;
106
        }
107
108
        // update with new guess
109
        static void updateGuess(std::vector<Rate>& data,
110
                                Rate level,
111
0
                                Size i) {
112
0
            data[i] = level;
113
0
            if (i==1)
114
0
                data[0] = level; // the first point is updated as well
115
0
        }
116
        // upper bound for convergence loop
117
0
        static Size maxIterations() { return 40; }
118
    };
119
120
    //! Bootstrap traits to use for PiecewiseYoYInflationCurve
121
    class YoYInflationTraits {
122
      public:
123
        // helper class
124
        typedef BootstrapHelper<YoYInflationTermStructure> helper;
125
126
        // start of curve data
127
0
        static Date initialDate(const YoYInflationTermStructure* t) {
128
0
            return t->baseDate();
129
0
        }
130
131
        // value at reference date
132
0
        static Rate initialValue(const YoYInflationTermStructure* t) {
133
0
            return t->baseRate();
134
0
        }
135
136
        // guesses
137
        template <class C>
138
        static Rate guess(Size i,
139
                          const C* c,
140
                          bool validData,
141
                          Size) // firstAliveHelper
142
        {
143
            if (validData) // previous iteration value
144
                return c->data()[i];
145
146
            return detail::avgInflation;
147
        }
148
149
        // guess for the whole curve and whether it needs to be transformed
150
        template <class C>
151
        static std::pair<Array, bool> globalGuess(const C* c, bool validData)
152
        {
153
            if (validData)
154
                return {Array(c->data().begin() + 1, c->data().end()), true};
155
156
            return {Array(c->times().size() - 1, detail::avgInflation), true};
157
        }
158
159
        // constraints
160
        template <class C>
161
        static Rate minValueAfter(Size,
162
                                  const C* c,
163
                                  bool validData,
164
                                  Size) // firstAliveHelper
165
        {
166
            if (validData) {
167
                Rate r = *(std::min_element(c->data().begin(), c->data().end()));
168
                return r<0.0 ? Real(r*2.0) : r/2.0;
169
            }
170
            return -detail::maxInflation;
171
        }
172
        template <class C>
173
        static Rate maxValueAfter(Size,
174
                                  const C* c,
175
                                  bool validData,
176
                                  Size) // firstAliveHelper
177
        {
178
            if (validData) {
179
                Rate r = *(std::max_element(c->data().begin(), c->data().end()));
180
                return r<0.0 ? Real(r/2.0) : r*2.0;
181
            }
182
            // no constraints.
183
            // We choose as max a value very unlikely to be exceeded.
184
            return detail::maxInflation;
185
        }
186
187
        // update with new guess
188
        static void updateGuess(std::vector<Rate>& data,
189
                                Rate level,
190
0
                                Size i) {
191
0
            data[i] = level;
192
0
        }
193
        // upper bound for convergence loop
194
0
        static Size maxIterations() { return 40; }
195
    };
196
197
}
198
199
#endif