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 <http://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/termstructures/inflation/interpolatedzeroinflationcurve.hpp> 30 #include <ql/termstructures/inflation/interpolatedyoyinflationcurve.hpp> 31 #include <ql/termstructures/bootstraphelper.hpp> 32 33 namespace QuantLib { 34 35 namespace detail { 36 const Rate avgInflation = 0.02; 37 const Rate maxInflation = 0.5; 38 } 39 40 //! Bootstrap traits to use for PiecewiseZeroInflationCurve 41 class ZeroInflationTraits { 42 public: 43 typedef BootstrapHelper<ZeroInflationTermStructure> helper; 44 45 // start of curve data initialDate(const ZeroInflationTermStructure * t)46 static Date initialDate(const ZeroInflationTermStructure* t) { 47 if (t->indexIsInterpolated()) { 48 return t->referenceDate() - t->observationLag(); 49 } else { 50 return inflationPeriod(t->referenceDate() - t->observationLag(), 51 t->frequency()).first; 52 } 53 } 54 // value at reference date initialValue(const ZeroInflationTermStructure * t)55 static Rate initialValue(const ZeroInflationTermStructure* t) { 56 return t->baseRate(); 57 } 58 59 // guesses 60 template <class C> guess(Size i,const C * c,bool validData,Size)61 static Rate guess(Size i, 62 const C* c, 63 bool validData, 64 Size) // firstAliveHelper 65 { 66 if (validData) // previous iteration value 67 return c->data()[i]; 68 69 if (i==1) // first pillar 70 return detail::avgInflation; 71 72 // could/should extrapolate 73 return detail::avgInflation; 74 } 75 76 // constraints 77 template <class C> minValueAfter(Size i,const C * c,bool validData,Size)78 static Rate minValueAfter(Size i, 79 const C* c, 80 bool validData, 81 Size) // firstAliveHelper 82 { 83 if (validData) { 84 Rate r = *(std::min_element(c->data().begin(), c->data().end())); 85 return r<0.0 ? r*2.0 : r/2.0; 86 } 87 return -detail::maxInflation; 88 } 89 template <class C> maxValueAfter(Size i,const C * c,bool validData,Size)90 static Rate maxValueAfter(Size i, 91 const C* c, 92 bool validData, 93 Size) // firstAliveHelper 94 { 95 if (validData) { 96 Rate r = *(std::max_element(c->data().begin(), c->data().end())); 97 return r<0.0 ? r/2.0 : r*2.0; 98 } 99 // no constraints. 100 // We choose as max a value very unlikely to be exceeded. 101 return detail::maxInflation; 102 } 103 104 // update with new guess updateGuess(std::vector<Rate> & data,Rate level,Size i)105 static void updateGuess(std::vector<Rate>& data, 106 Rate level, 107 Size i) { 108 data[i] = level; 109 } 110 // upper bound for convergence loop 111 // calibration is trivial, should be immediate maxIterations()112 static Size maxIterations() { return 5; } 113 }; 114 115 //! Bootstrap traits to use for PiecewiseZeroInflationCurve 116 class YoYInflationTraits { 117 public: 118 // helper class 119 typedef BootstrapHelper<YoYInflationTermStructure> helper; 120 121 // start of curve data initialDate(const YoYInflationTermStructure * t)122 static Date initialDate(const YoYInflationTermStructure* t) { 123 if (t->indexIsInterpolated()) { 124 return t->referenceDate() - t->observationLag(); 125 } else { 126 return inflationPeriod(t->referenceDate() - t->observationLag(), 127 t->frequency()).first; 128 } 129 } 130 // value at reference date initialValue(const YoYInflationTermStructure * t)131 static Rate initialValue(const YoYInflationTermStructure* t) { 132 return t->baseRate(); 133 } 134 135 // guesses 136 template <class C> guess(Size i,const C * c,bool validData,Size)137 static Rate guess(Size i, 138 const C* c, 139 bool validData, 140 Size) // firstAliveHelper 141 { 142 if (validData) // previous iteration value 143 return c->data()[i]; 144 145 if (i==1) // first pillar 146 return detail::avgInflation; 147 148 // could/should extrapolate 149 return detail::avgInflation; 150 } 151 152 // constraints 153 template <class C> minValueAfter(Size i,const C * c,bool validData,Size)154 static Rate minValueAfter(Size i, 155 const C* c, 156 bool validData, 157 Size) // firstAliveHelper 158 { 159 if (validData) { 160 Rate r = *(std::min_element(c->data().begin(), c->data().end())); 161 return r<0.0 ? r*2.0 : r/2.0; 162 } 163 return -detail::maxInflation; 164 } 165 template <class C> maxValueAfter(Size i,const C * c,bool validData,Size)166 static Rate maxValueAfter(Size i, 167 const C* c, 168 bool validData, 169 Size) // firstAliveHelper 170 { 171 if (validData) { 172 Rate r = *(std::max_element(c->data().begin(), c->data().end())); 173 return r<0.0 ? r/2.0 : r*2.0; 174 } 175 // no constraints. 176 // We choose as max a value very unlikely to be exceeded. 177 return detail::maxInflation; 178 } 179 180 // update with new guess updateGuess(std::vector<Rate> & data,Rate level,Size i)181 static void updateGuess(std::vector<Rate>& data, 182 Rate level, 183 Size i) { 184 data[i] = level; 185 } 186 // upper bound for convergence loop maxIterations()187 static Size maxIterations() { return 40; } 188 }; 189 190 } 191 192 #endif 193