1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2008 Chris Kenyon 5 Copyright (C) 2008 Roland Lichters 6 Copyright (C) 2008, 2009 StatPro Italia srl 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 interpolateddefaultdensitycurve.hpp 23 \brief interpolated default-density term structure 24 */ 25 26 #ifndef quantlib_interpolated_default_density_curve_hpp 27 #define quantlib_interpolated_default_density_curve_hpp 28 29 #include <ql/termstructures/credit/defaultdensitystructure.hpp> 30 #include <ql/termstructures/interpolatedcurve.hpp> 31 #include <utility> 32 33 namespace QuantLib { 34 35 //! DefaultProbabilityTermStructure based on interpolation of default densities 36 /*! \ingroup defaultprobabilitytermstructures */ 37 template <class Interpolator> 38 class InterpolatedDefaultDensityCurve 39 : public DefaultDensityStructure, 40 protected InterpolatedCurve<Interpolator> { 41 public: 42 InterpolatedDefaultDensityCurve( 43 const std::vector<Date>& dates, 44 const std::vector<Real>& densities, 45 const DayCounter& dayCounter, 46 const Calendar& calendar = Calendar(), 47 const std::vector<Handle<Quote> >& jumps = 48 std::vector<Handle<Quote> >(), 49 const std::vector<Date>& jumpDates = std::vector<Date>(), 50 const Interpolator& interpolator = Interpolator()); 51 InterpolatedDefaultDensityCurve( 52 const std::vector<Date>& dates, 53 const std::vector<Real>& densities, 54 const DayCounter& dayCounter, 55 const Calendar& calendar, 56 const Interpolator& interpolator); 57 InterpolatedDefaultDensityCurve( 58 const std::vector<Date>& dates, 59 const std::vector<Real>& densities, 60 const DayCounter& dayCounter, 61 const Interpolator& interpolator); 62 //! \name TermStructure interface 63 //@{ 64 Date maxDate() const; 65 //@} 66 //! \name other inspectors 67 //@{ 68 const std::vector<Time>& times() const; 69 const std::vector<Date>& dates() const; 70 const std::vector<Real>& data() const; 71 const std::vector<Real>& defaultDensities() const; 72 std::vector<std::pair<Date, Real> > nodes() const; 73 //@} 74 protected: 75 InterpolatedDefaultDensityCurve( 76 const DayCounter&, 77 const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(), 78 const std::vector<Date>& jumpDates = std::vector<Date>(), 79 const Interpolator& interpolator = Interpolator()); 80 InterpolatedDefaultDensityCurve( 81 const Date& referenceDate, 82 const DayCounter&, 83 const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(), 84 const std::vector<Date>& jumpDates = std::vector<Date>(), 85 const Interpolator& interpolator = Interpolator()); 86 InterpolatedDefaultDensityCurve( 87 Natural settlementDays, 88 const Calendar&, 89 const DayCounter&, 90 const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(), 91 const std::vector<Date>& jumpDates = std::vector<Date>(), 92 const Interpolator& interpolator = Interpolator()); 93 //! \name DefaultDensityStructure implementation 94 //@{ 95 Real defaultDensityImpl(Time) const; 96 Probability survivalProbabilityImpl(Time) const; 97 //@} 98 mutable std::vector<Date> dates_; 99 private: 100 void initialize(const std::vector<Date>& dates, 101 const std::vector<Real>& densities, 102 const DayCounter& dayCounter); 103 }; 104 105 // inline definitions 106 107 template <class T> maxDate() const108 inline Date InterpolatedDefaultDensityCurve<T>::maxDate() const { 109 return dates_.back(); 110 } 111 112 template <class T> 113 inline const std::vector<Time>& times() const114 InterpolatedDefaultDensityCurve<T>::times() const { 115 return this->times_; 116 } 117 118 template <class T> 119 inline const std::vector<Date>& dates() const120 InterpolatedDefaultDensityCurve<T>::dates() const { 121 return dates_; 122 } 123 124 template <class T> 125 inline const std::vector<Real>& data() const126 InterpolatedDefaultDensityCurve<T>::data() const { 127 return this->data_; 128 } 129 130 template <class T> 131 inline const std::vector<Real>& defaultDensities() const132 InterpolatedDefaultDensityCurve<T>::defaultDensities() const { 133 return this->data_; 134 } 135 136 template <class T> 137 inline std::vector<std::pair<Date, Real> > nodes() const138 InterpolatedDefaultDensityCurve<T>::nodes() const { 139 std::vector<std::pair<Date, Real> > results(dates_.size()); 140 for (Size i=0; i<dates_.size(); ++i) 141 results[i] = std::make_pair(dates_[i], this->data_[i]); 142 return results; 143 } 144 145 #ifndef __DOXYGEN__ 146 147 // template definitions 148 149 template <class T> defaultDensityImpl(Time t) const150 Real InterpolatedDefaultDensityCurve<T>::defaultDensityImpl(Time t) const { 151 if (t <= this->times_.back()) 152 return this->interpolation_(t, true); 153 154 // flat default density extrapolation 155 return this->data_.back(); 156 } 157 158 template <class T> 159 Probability survivalProbabilityImpl(Time t) const160 InterpolatedDefaultDensityCurve<T>::survivalProbabilityImpl(Time t) const { 161 if (t == 0.0) 162 return 1.0; 163 164 Real integral = 0.0; 165 if (t <= this->times_.back()) { 166 integral = this->interpolation_.primitive(t, true); 167 } else { 168 // flat default density extrapolation 169 integral = this->interpolation_.primitive(this->times_.back(), true) 170 + this->data_.back()*(t - this->times_.back()); 171 } 172 Probability P = 1.0 - integral; 173 // QL_ENSURE(P >= 0.0, "negative survival probability"); 174 return std::max<Real>(P, 0.0); 175 } 176 177 template <class T> InterpolatedDefaultDensityCurve(const DayCounter & dayCounter,const std::vector<Handle<Quote>> & jumps,const std::vector<Date> & jumpDates,const T & interpolator)178 InterpolatedDefaultDensityCurve<T>::InterpolatedDefaultDensityCurve( 179 const DayCounter& dayCounter, 180 const std::vector<Handle<Quote> >& jumps, 181 const std::vector<Date>& jumpDates, 182 const T& interpolator) 183 : DefaultDensityStructure(dayCounter, jumps, jumpDates), 184 InterpolatedCurve<T>(interpolator) {} 185 186 template <class T> InterpolatedDefaultDensityCurve(const Date & referenceDate,const DayCounter & dayCounter,const std::vector<Handle<Quote>> & jumps,const std::vector<Date> & jumpDates,const T & interpolator)187 InterpolatedDefaultDensityCurve<T>::InterpolatedDefaultDensityCurve( 188 const Date& referenceDate, 189 const DayCounter& dayCounter, 190 const std::vector<Handle<Quote> >& jumps, 191 const std::vector<Date>& jumpDates, 192 const T& interpolator) 193 : DefaultDensityStructure(referenceDate, Calendar(), dayCounter, jumps, jumpDates), 194 InterpolatedCurve<T>(interpolator) {} 195 196 template <class T> InterpolatedDefaultDensityCurve(Natural settlementDays,const Calendar & calendar,const DayCounter & dayCounter,const std::vector<Handle<Quote>> & jumps,const std::vector<Date> & jumpDates,const T & interpolator)197 InterpolatedDefaultDensityCurve<T>::InterpolatedDefaultDensityCurve( 198 Natural settlementDays, 199 const Calendar& calendar, 200 const DayCounter& dayCounter, 201 const std::vector<Handle<Quote> >& jumps, 202 const std::vector<Date>& jumpDates, 203 const T& interpolator) 204 : DefaultDensityStructure(settlementDays, calendar, dayCounter, jumps, jumpDates), 205 InterpolatedCurve<T>(interpolator) {} 206 207 template <class T> InterpolatedDefaultDensityCurve(const std::vector<Date> & dates,const std::vector<Real> & densities,const DayCounter & dayCounter,const Calendar & calendar,const std::vector<Handle<Quote>> & jumps,const std::vector<Date> & jumpDates,const T & interpolator)208 InterpolatedDefaultDensityCurve<T>::InterpolatedDefaultDensityCurve( 209 const std::vector<Date>& dates, 210 const std::vector<Real>& densities, 211 const DayCounter& dayCounter, 212 const Calendar& calendar, 213 const std::vector<Handle<Quote> >& jumps, 214 const std::vector<Date>& jumpDates, 215 const T& interpolator) 216 : DefaultDensityStructure(dates.at(0), calendar, dayCounter, jumps, jumpDates), 217 InterpolatedCurve<T>(std::vector<Time>(), densities, interpolator), 218 dates_(dates) 219 { 220 initialize(dates, densities, dayCounter); 221 } 222 223 template <class T> InterpolatedDefaultDensityCurve(const std::vector<Date> & dates,const std::vector<Real> & densities,const DayCounter & dayCounter,const Calendar & calendar,const T & interpolator)224 InterpolatedDefaultDensityCurve<T>::InterpolatedDefaultDensityCurve( 225 const std::vector<Date>& dates, 226 const std::vector<Real>& densities, 227 const DayCounter& dayCounter, 228 const Calendar& calendar, 229 const T& interpolator) 230 : DefaultDensityStructure(dates.at(0), calendar, dayCounter), 231 InterpolatedCurve<T>(std::vector<Time>(), densities, interpolator), 232 dates_(dates) 233 { 234 initialize(dates, densities, dayCounter); 235 } 236 237 template <class T> InterpolatedDefaultDensityCurve(const std::vector<Date> & dates,const std::vector<Real> & densities,const DayCounter & dayCounter,const T & interpolator)238 InterpolatedDefaultDensityCurve<T>::InterpolatedDefaultDensityCurve( 239 const std::vector<Date>& dates, 240 const std::vector<Real>& densities, 241 const DayCounter& dayCounter, 242 const T& interpolator) 243 : DefaultDensityStructure(dates.at(0), Calendar(), dayCounter), 244 InterpolatedCurve<T>(std::vector<Time>(), densities, interpolator), 245 dates_(dates) 246 { 247 initialize(dates, densities, dayCounter); 248 } 249 250 251 #endif 252 253 254 template <class T> initialize(const std::vector<Date> & dates,const std::vector<Real> & densities,const DayCounter & dayCounter)255 void InterpolatedDefaultDensityCurve<T>::initialize( 256 const std::vector<Date>& dates, 257 const std::vector<Real>& densities, 258 const DayCounter& dayCounter) 259 { 260 QL_REQUIRE(dates_.size() >= T::requiredPoints, 261 "not enough input dates given"); 262 QL_REQUIRE(this->data_.size() == dates_.size(), 263 "dates/data count mismatch"); 264 265 this->times_.resize(dates_.size()); 266 this->times_[0] = 0.0; 267 for (Size i=1; i<dates_.size(); ++i) { 268 QL_REQUIRE(dates_[i] > dates_[i-1], 269 "invalid date (" << dates_[i] << ", vs " 270 << dates_[i-1] << ")"); 271 this->times_[i] = dayCounter.yearFraction(dates_[0], dates_[i]); 272 QL_REQUIRE(!close(this->times_[i],this->times_[i-1]), 273 "two dates correspond to the same time " 274 "under this curve's day count convention"); 275 QL_REQUIRE(this->data_[i] >= 0.0, "negative default density"); 276 } 277 278 this->interpolation_ = 279 this->interpolator_.interpolate(this->times_.begin(), 280 this->times_.end(), 281 this->data_.begin()); 282 this->interpolation_.update(); 283 } 284 285 } 286 287 #endif 288