Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
interpolatedsurvivalprobabilitycurve.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*
20 Copyright (C) 2009 Ferdinando Ametrano
21
22 This file is part of QuantLib, a free-software/open-source library
23 for financial quantitative analysts and developers - http://quantlib.org/
24
25 QuantLib is free software: you can redistribute it and/or modify it
26 under the terms of the QuantLib license. You should have received a
27 copy of the license along with this program; if not, please email
28 <quantlib-dev@lists.sf.net>. The license is also available online at
29 <http://quantlib.org/license.shtml>.
30
31 This program is distributed in the hope that it will be useful, but WITHOUT
32 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
33 FOR A PARTICULAR PURPOSE. See the license for more details.
34*/
35
36/*! \file interpolatedsurvivalprobabilitycurve.hpp
37 \brief interpolated survival-probability term structure (with the option to
38 disable the check for negative hazard rates)
39*/
40
41#ifndef quantext_interpolated_survival_probability_curve_hpp
42#define quantext_interpolated_survival_probability_curve_hpp
43
44#include <ql/termstructures/credit/survivalprobabilitystructure.hpp>
45#include <ql/termstructures/interpolatedcurve.hpp>
46#include <utility>
47
48namespace QuantExt {
49using namespace QuantLib;
50
51 //! DefaultProbabilityTermStructure based on interpolation of survival probabilities
52 /*! \ingroup defaultprobabilitytermstructures */
53 template <class Interpolator>
56 protected InterpolatedCurve<Interpolator> {
57 public:
59 const std::vector<Date>& dates,
60 const std::vector<Probability>& probabilities,
61 const DayCounter& dayCounter,
62 const Calendar& calendar = Calendar(),
63 const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(),
64 const std::vector<Date>& jumpDates = std::vector<Date>(),
65 const Interpolator& interpolator = Interpolator(),
66 const bool allowNegativeRates = false);
67 //! \name TermStructure interface
68 //@{
69 Date maxDate() const override;
70 //@}
71 //! \name other inspectors
72 //@{
73 const std::vector<Time>& times() const;
74 const std::vector<Date>& dates() const;
75 const std::vector<Real>& data() const;
76 const std::vector<Probability>& survivalProbabilities() const;
77 std::vector<std::pair<Date, Real> > nodes() const;
78 //@}
79 protected:
81 const DayCounter&,
82 const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(),
83 const std::vector<Date>& jumpDates = std::vector<Date>(),
84 const Interpolator& interpolator = Interpolator(),
85 const bool allowNegativeRates = false);
87 const Date& referenceDate,
88 const DayCounter&,
89 const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(),
90 const std::vector<Date>& jumpDates = std::vector<Date>(),
91 const Interpolator& interpolator = Interpolator(),
92 const bool allowNegativeRates = false);
94 Natural settlementDays,
95 const Calendar&,
96 const DayCounter&,
97 const std::vector<Handle<Quote> >& jumps = std::vector<Handle<Quote> >(),
98 const std::vector<Date>& jumpDates = std::vector<Date>(),
99 const Interpolator& interpolator = Interpolator(),
100 const bool allowNegativeRates = false);
101 //! \name DefaultProbabilityTermStructure implementation
102 //@{
103 Probability survivalProbabilityImpl(Time) const override;
104 Real defaultDensityImpl(Time) const override;
105 //@}
106 mutable std::vector<Date> dates_;
107 private:
109 };
110
111 // inline definitions
112
113 template <class T>
115 return dates_.back();
116 }
117
118 template <class T>
119 inline const std::vector<Time>&
121 return this->times_;
122 }
123
124 template <class T>
125 inline const std::vector<Date>&
127 return dates_;
128 }
129
130 template <class T>
131 inline const std::vector<Real>&
133 return this->data_;
134 }
135
136 template <class T>
137 inline const std::vector<Probability>&
139 return this->data_;
140 }
141
142 template <class T>
143 inline std::vector<std::pair<Date,Real> >
145 std::vector<std::pair<Date,Real> > results(dates_.size());
146 for (Size i=0; i<dates_.size(); ++i)
147 results[i] = std::make_pair(dates_[i],this->data_[i]);
148 return results;
149 }
150
151 #ifndef __DOXYGEN__
152
153 // template definitions
154
155 template <class T>
156 Probability
158 const {
159 if (t <= this->times_.back())
160 return this->interpolation_(t, true);
161
162 // flat hazard rate extrapolation
163 Time tMax = this->times_.back();
164 Probability sMax = this->data_.back();
165 Rate hazardMax = - this->interpolation_.derivative(tMax) / sMax;
166 return sMax * std::exp(- hazardMax * (t-tMax));
167 }
168
169 template <class T>
170 Real
172 if (t <= this->times_.back())
173 return -this->interpolation_.derivative(t, true);
174
175 // flat hazard rate extrapolation
176 Time tMax = this->times_.back();
177 Probability sMax = this->data_.back();
178 Rate hazardMax = - this->interpolation_.derivative(tMax) / sMax;
179 return sMax * hazardMax * std::exp(- hazardMax * (t-tMax));
180 }
181
182 template <class T>
184 const DayCounter& dayCounter,
185 const std::vector<Handle<Quote> >& jumps,
186 const std::vector<Date>& jumpDates,
187 const T& interpolator,
188 const bool allowNegativeRates)
189 : SurvivalProbabilityStructure(dayCounter, jumps, jumpDates),
190 InterpolatedCurve<T>(interpolator), allowNegativeRates_(allowNegativeRates) {}
191
192 template <class T>
194 const Date& referenceDate,
195 const DayCounter& dayCounter,
196 const std::vector<Handle<Quote> >& jumps,
197 const std::vector<Date>& jumpDates,
198 const T& interpolator,
199 const bool allowNegativeRates)
200 : SurvivalProbabilityStructure(referenceDate, Calendar(), dayCounter, jumps, jumpDates),
201 InterpolatedCurve<T>(interpolator), allowNegativeRates_(allowNegativeRates) {}
202
203 template <class T>
205 Natural settlementDays,
206 const Calendar& calendar,
207 const DayCounter& dayCounter,
208 const std::vector<Handle<Quote> >& jumps,
209 const std::vector<Date>& jumpDates,
210 const T& interpolator,
211 const bool allowNegativeRates)
212 : SurvivalProbabilityStructure(settlementDays, calendar, dayCounter, jumps, jumpDates),
213 InterpolatedCurve<T>(interpolator), allowNegativeRates_(allowNegativeRates) {}
214
215 template <class T>
217 const std::vector<Date>& dates,
218 const std::vector<Probability>& probabilities,
219 const DayCounter& dayCounter,
220 const Calendar& calendar,
221 const std::vector<Handle<Quote> >& jumps,
222 const std::vector<Date>& jumpDates,
223 const T& interpolator,
224 const bool allowNegativeRates)
225 : SurvivalProbabilityStructure(dates.at(0), calendar, dayCounter, jumps, jumpDates),
226 InterpolatedCurve<T>(std::vector<Time>(), probabilities, interpolator),
227 dates_(dates), allowNegativeRates_(allowNegativeRates)
228 {
229 QL_REQUIRE(dates_.size() >= T::requiredPoints,
230 "not enough input dates given");
231 QL_REQUIRE(this->data_.size() == dates_.size(),
232 "dates/data count mismatch");
233 QL_REQUIRE(this->data_[0] == 1.0,
234 "the first probability must be == 1.0 "
235 "to flag the corresponding date as reference date");
236
237 this->times_.resize(dates_.size());
238 this->times_[0] = 0.0;
239 for (Size i=1; i<dates_.size(); ++i) {
240 QL_REQUIRE(dates_[i] > dates_[i-1],
241 "invalid date (" << dates_[i] << ", vs "
242 << dates_[i-1] << ")");
243 this->times_[i] = dayCounter.yearFraction(dates_[0], dates_[i]);
244 QL_REQUIRE(!close(this->times_[i],this->times_[i-1]),
245 "two dates correspond to the same time "
246 "under this curve's day count convention");
247 QL_REQUIRE(this->data_[i] > 0.0, "negative probability");
248 QL_REQUIRE(allowNegativeRates_ || this->data_[i] <= this->data_[i-1],
249 "negative hazard rate implied by the survival "
250 "probability " <<
251 this->data_[i] << " at " << dates_[i] <<
252 " (t=" << this->times_[i] << ") after the survival "
253 "probability " <<
254 this->data_[i-1] << " at " << dates_[i-1] <<
255 " (t=" << this->times_[i-1] << ")");
256 }
257
258 this->interpolation_ =
259 this->interpolator_.interpolate(this->times_.begin(),
260 this->times_.end(),
261 this->data_.begin());
262 this->interpolation_.update();
263 }
264
265 #endif
266}
267
268#endif
DefaultProbabilityTermStructure based on interpolation of survival probabilities.
Real defaultDensityImpl(Time) const override
InterpolatedSurvivalProbabilityCurve(const Date &referenceDate, const DayCounter &, const std::vector< Handle< Quote > > &jumps=std::vector< Handle< Quote > >(), const std::vector< Date > &jumpDates=std::vector< Date >(), const Interpolator &interpolator=Interpolator(), const bool allowNegativeRates=false)
const std::vector< Probability > & survivalProbabilities() const
InterpolatedSurvivalProbabilityCurve(const DayCounter &, const std::vector< Handle< Quote > > &jumps=std::vector< Handle< Quote > >(), const std::vector< Date > &jumpDates=std::vector< Date >(), const Interpolator &interpolator=Interpolator(), const bool allowNegativeRates=false)
InterpolatedSurvivalProbabilityCurve(Natural settlementDays, const Calendar &, const DayCounter &, const std::vector< Handle< Quote > > &jumps=std::vector< Handle< Quote > >(), const std::vector< Date > &jumpDates=std::vector< Date >(), const Interpolator &interpolator=Interpolator(), const bool allowNegativeRates=false)
Probability survivalProbabilityImpl(Time) const override
InterpolatedSurvivalProbabilityCurve(const std::vector< Date > &dates, const std::vector< Probability > &probabilities, const DayCounter &dayCounter, const Calendar &calendar=Calendar(), const std::vector< Handle< Quote > > &jumps=std::vector< Handle< Quote > >(), const std::vector< Date > &jumpDates=std::vector< Date >(), const Interpolator &interpolator=Interpolator(), const bool allowNegativeRates=false)