Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
survivalprobabilitycurve.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/*! \file qle/termstructures/survivalprobabilitycurve.hpp
20 \brief interpolated survival probability term structure
21 \ingroup termstructures
22*/
23
24#ifndef quantext_survival_probability_curve_hpp
25#define quantext_survival_probability_curve_hpp
26
27#include <boost/make_shared.hpp>
28#include <ql/patterns/lazyobject.hpp>
29#include <ql/termstructures/credit/survivalprobabilitystructure.hpp>
30#include <ql/termstructures/interpolatedcurve.hpp>
31
32namespace QuantExt {
33using namespace QuantLib;
34
35//! DefaultProbabilityTermStructure based on interpolation of survival probability quotes
36/*! \ingroup termstructures */
37template <class Interpolator>
39 protected InterpolatedCurve<Interpolator>,
40 public LazyObject {
41public:
43 SurvivalProbabilityCurve(const std::vector<Date>& dates, const std::vector<Handle<Quote>>& quotes,
44 const DayCounter& dayCounter, const Calendar& calendar = Calendar(),
45 const std::vector<Handle<Quote>>& jumps = std::vector<Handle<Quote>>(),
46 const std::vector<Date>& jumpDates = std::vector<Date>(),
47 const Interpolator& interpolator = Interpolator(),
48 const Extrapolation extrpolation = Extrapolation::flatFwd);
49 //! \name TermStructure interface
50 //@{
51 Date maxDate() const override;
52 //@}
53 //! \name other inspectors
54 //@{
55 const std::vector<Time>& times() const;
56 const std::vector<Date>& dates() const;
57 const std::vector<Real>& data() const;
58 const std::vector<Probability>& survivalProbabilities() const;
59 const std::vector<Handle<Quote>>& quotes() const;
60 std::vector<std::pair<Date, Real>> nodes() const;
61 //@}
62 //! \name Observer interface
63 //@{
64 void update() override;
65 //@}
66private:
67 void initialize();
68 //! \name LazyObject interface
69 //@{
70 void performCalculations() const override;
71 //@}
72
73 //! \name DefaultProbabilityTermStructure implementation
74 //@{
75 Probability survivalProbabilityImpl(Time) const override;
76 Real defaultDensityImpl(Time t) const override;
77 //@}
78 mutable std::vector<Date> dates_;
79 std::vector<Handle<Quote>> quotes_;
81};
82
83// inline definitions
84
85template <class T> inline Date SurvivalProbabilityCurve<T>::maxDate() const { return dates_.back(); }
86
87template <class T> inline const std::vector<Time>& SurvivalProbabilityCurve<T>::times() const { return this->times_; }
88
89template <class T> inline const std::vector<Date>& SurvivalProbabilityCurve<T>::dates() const { return dates_; }
90
91template <class T> inline const std::vector<Real>& SurvivalProbabilityCurve<T>::data() const { return this->data_; }
92
93template <class T> inline const std::vector<Probability>& SurvivalProbabilityCurve<T>::survivalProbabilities() const {
94 return this->data_;
95}
96
97template <class T> inline std::vector<std::pair<Date, Real>> SurvivalProbabilityCurve<T>::nodes() const {
98 std::vector<std::pair<Date, Real>> results(dates_.size());
99 for (Size i = 0; i < dates_.size(); ++i)
100 results[i] = std::make_pair(dates_[i], this->data_[i]);
101 return results;
102}
103
104// template definitions
105
106template <class T> Probability SurvivalProbabilityCurve<T>::survivalProbabilityImpl(Time t) const {
107 calculate();
108 if (t <= this->times_.back())
109 return this->interpolation_(t, true);
110
111 // flat hazard rate extrapolation
112 Time tMax = this->times_.back();
113 Probability sMax = this->data_.back();
114 if (this->extrapolation_ == Extrapolation::flatFwd) {
115 Rate hazardMax = -this->interpolation_.derivative(tMax) / sMax;
116 return sMax * std::exp(-hazardMax * (t - tMax));
117 } else {
118 return std::pow(sMax, t / tMax);
119 }
120}
121
122template <class T> Real SurvivalProbabilityCurve<T>::defaultDensityImpl(Time t) const {
123 calculate();
124 if (t <= this->times_.back())
125 return -this->interpolation_.derivative(t, true);
126
127 // flat hazard rate extrapolation
128 Time tMax = this->times_.back();
129 Probability sMax = this->data_.back();
130 if (this->extrapolation_ == Extrapolation::flatFwd) {
131 Rate hazardMax = -this->interpolation_.derivative(tMax) / sMax;
132 return sMax * hazardMax * std::exp(-hazardMax * (t - tMax));
133 } else {
134 return -std::log(sMax) / tMax * std::pow(sMax, t / tMax);
135 }
136}
137
138template <class T>
140 const std::vector<Handle<Quote>>& quotes,
141 const DayCounter& dayCounter, const Calendar& calendar,
142 const std::vector<Handle<Quote>>& jumps,
143 const std::vector<Date>& jumpDates, const T& interpolator,
144 const Extrapolation extrapolation)
145 : SurvivalProbabilityStructure(dates.front(), calendar, dayCounter, jumps, jumpDates),
146 InterpolatedCurve<T>(std::vector<Time>(), std::vector<Real>(), interpolator), dates_(dates), quotes_(quotes),
147 extrapolation_(extrapolation) {
148 QL_REQUIRE(dates_.size() >= T::requiredPoints, "not enough input dates given");
149 QL_REQUIRE(quotes_.size() == dates_.size(), "dates/data count mismatch");
150 for (Size i = 0; i < quotes_.size(); i++)
151 registerWith(quotes_[i]);
152 initialize();
153}
154
155template <class T> inline void SurvivalProbabilityCurve<T>::update() {
156 LazyObject::update();
157 DefaultProbabilityTermStructure::update();
158}
159
160template <class T> inline void SurvivalProbabilityCurve<T>::performCalculations() const {
161 for (Size i = 0; i < dates_.size(); ++i)
162 this->data_[i] = quotes_[i]->value();
163
164 this->interpolation_ =
165 this->interpolator_.interpolate(this->times_.begin(), this->times_.end(), this->data_.begin());
166 this->interpolation_.update();
167}
168
170 QL_REQUIRE(dates_.size() >= T::requiredPoints, "not enough input dates given");
171 QL_REQUIRE(quotes_.size() == dates_.size(), "dates/data count mismatch");
172
173 this->times_.resize(dates_.size());
174 this->data_.resize(dates_.size());
175 this->times_[0] = 0.0;
176 for (Size i = 1; i < dates_.size(); ++i) {
177 QL_REQUIRE(dates_[i] > dates_[i - 1], "invalid date (" << dates_[i] << ", vs " << dates_[i - 1] << ")");
178 this->times_[i] = dayCounter().yearFraction(dates_[0], dates_[i]);
179 QL_REQUIRE(!close(this->times_[i], this->times_[i - 1]), "two dates correspond to the same time "
180 "under this curve's day count convention");
181 // QL_REQUIRE(this->data_[i] > 0.0, "negative probability");
182 // QL_REQUIRE(this->data_[i] <= this->data_[i-1],
183 // "negative hazard rate implied by the survival "
184 // "probability " <<
185 // this->data_[i] << " at " << dates_[i] <<
186 // " (t=" << this->times_[i] << ") after the survival "
187 // "probability " <<
188 // this->data_[i-1] << " at " << dates_[i-1] <<
189 // " (t=" << this->times_[i-1] << ")");
190 }
191}
192} // namespace QuantExt
193
194#endif
DefaultProbabilityTermStructure based on interpolation of survival probability quotes.
const std::vector< Probability > & survivalProbabilities() const
const std::vector< Date > & dates() const
const std::vector< Real > & data() const
std::vector< std::pair< Date, Real > > nodes() const
Real defaultDensityImpl(Time t) const override
const std::vector< Time > & times() const
const std::vector< Handle< Quote > > & quotes() const
Probability survivalProbabilityImpl(Time) const override
std::vector< Handle< Quote > > quotes_
SurvivalProbabilityCurve(const std::vector< Date > &dates, const std::vector< Handle< Quote > > &quotes, 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 Extrapolation extrpolation=Extrapolation::flatFwd)