QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
onefactorcopula.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 Roland Lichters
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20/*! \file onefactorcopula.hpp
21 \brief One-factor copula base class
22*/
23
24#ifndef quantlib_one_factor_copula_hpp
25#define quantlib_one_factor_copula_hpp
26
29#include <ql/quote.hpp>
30#include <utility>
31
32namespace QuantLib {
33
34 //! Abstract base class for one-factor copula models
35 /*! Reference: John Hull and Alan White, The Perfect Copula, June 2006
36
37 Let \f$Q_i(t)\f$ be the cumulative probability of default of
38 counterparty i before time t.
39
40 In a one-factor model, consider random variables
41 \f[ Y_i = a_i\,M+\sqrt{1-a_i^2}\:Z_i \f]
42 where \f$M\f$ and \f$Z_i\f$ have independent zero-mean
43 unit-variance distributions and \f$-1\leq a_i \leq 1\f$. The
44 correlation between \f$Y_i\f$ and \f$Y_j\f$ is then
45 \f$a_i a_j\f$.
46
47 Let \f$F_Y(y)\f$ be the cumulative distribution function of \f$Y_i\f$.
48 \f$y\f$ is mapped to \f$t\f$ such that percentiles match, i.e.
49 \f$F_Y(y)=Q_i(t)\f$ or \f$y=F_Y^{-1}(Q_i(t))\f$.
50
51 Now let \f$F_Z(z)\f$ be the cumulated distribution function of
52 \f$Z_i\f$. For given realization of \f$M\f$, this determines
53 the distribution of \f$y\f$:
54 \f[
55 Prob \,(Y_i < y|M) = F_Z \left( \frac{y-a_i\,M}{\sqrt{1-a_i^2}}\right)
56 \qquad
57 \mbox{or}
58 \qquad
59 Prob \,(t_i < t|M) = F_Z \left( \frac{F_Y^{-1}(Q_i(t))-a_i\,M}
60 {\sqrt{1-a_i^2}}
61 \right)
62 \f]
63
64 The distribution functions of \f$ M, Z_i \f$ are specified in
65 derived classes. The distribution function of \f$ Y \f$ is
66 then given by the convolution
67 \f[
68 F_Y(y) = Prob\,(Y<y) = \int_{-\infty}^\infty\,\int_{-\infty}^{\infty}\:
69 D_Z(z)\,D_M(m) \quad
70 \Theta \left(y - a\,m - \sqrt{1-a^2}\,z\right)\,dm\,dz,
71 \qquad
72 \Theta (x) = \left\{
73 \begin{array}{ll}
74 1 & x \geq 0 \\
75 0 & x < 0
76 \end{array}\right.
77 \f]
78 where \f$ D_Z(z) \f$ and \f$ D_M(m) \f$ are the probability
79 densities of \f$ Z\f$ and \f$ M, \f$ respectively.
80
81 This convolution can also be written
82 \f[
83 F(y) = Prob \,(Y < y) =
84 \int_{-\infty}^\infty D_M(m)\,dm\:
85 \int_{-\infty}^{g(y,a,m)} D_Z(z)\,dz, \qquad
86 g(y,a,m) = \frac{y - a\cdot m}{\sqrt{1-a^2}}, \qquad a < 1
87 \f]
88
89 or
90
91 \f[
92 F(y) = Prob \,(Y < y) =
93 \int_{-\infty}^\infty D_Z(z)\,dz\:
94 \int_{-\infty}^{h(y,a,z)} D_M(m)\,dm, \qquad
95 h(y,a,z) = \frac{y - \sqrt{1 - a^2}\cdot z}{a}, \qquad a > 0.
96 \f]
97
98 In general, \f$ F_Y(y) \f$ needs to be computed numerically.
99
100 \todo Improve on simple Euler integration
101 */
103 public:
105 Real maximum = 5.0,
106 Size integrationSteps = 50,
107 Real minimum = -5.0)
108 : correlation_(std::move(correlation)), max_(maximum), steps_(integrationSteps),
109 min_(minimum) {
110 QL_REQUIRE(correlation_->value() >= -1
111 && correlation_->value() <= 1,
112 "correlation out of range [-1, +1]");
114 }
115
116 //! Density function of M.
117 /*! Derived classes must override this method and ensure zero
118 mean and unit variance.
119 */
120 virtual Real density(Real m) const = 0;
121 //! Cumulative distribution of Z.
122 /*! Derived classes must override this method and ensure zero
123 mean and unit variance.
124 */
125 virtual Real cumulativeZ(Real z) const = 0;
126 //! Cumulative distribution of Y.
127 /*! This is the default implementation based on tabulated
128 data. The table needs to be filled by derived classes. If
129 analytic calculation is feasible, this method can also be
130 overridden.
131 */
132 virtual Real cumulativeY(Real y) const;
133 //! Inverse cumulative distribution of Y.
134 /*! This is the default implementation based on tabulated
135 data. The table needs to be filled by derived classes. If
136 analytic calculation is feasible, this method can also be
137 overridden.
138 */
139 virtual Real inverseCumulativeY(Real p) const;
140
141 //! Single correlation parameter
142 Real correlation() const;
143
144 //! Conditional probability
145 /*! \f[
146 \hat p(m) = F_Z \left( \frac{F_Y^{-1}(p)-a\,m}{\sqrt{1-a^2}}\right)
147 \f]
148 */
150 Real m) const;
151
152 //! Vector of conditional probabilities
153 /*! \f[
154 \hat p_i(m) = F_Z \left( \frac{F_Y^{-1}(p_i)-a\,m}{\sqrt{1-a^2}}
155 \right)
156 \f]
157 */
158 std::vector<Real> conditionalProbability(const std::vector<Real>& prob,
159 Real m) const;
160
161 /*! Integral over the density \f$ \rho(m) \f$ of M and the conditional
162 probability related to p:
163
164 \f[
165 \int_{-\infty}^\infty\,dm\,\rho(m)\,
166 F_Z \left( \frac{F_Y^{-1}(p)-a\,m}{\sqrt{1-a^2}}\right)
167 \f]
168 */
169 Real integral(Real p) const {
170 QL_REQUIRE(p >= 0 && p <= 1, "probability p=" << p
171 << " out of range [0,1]");
172 calculate();
173
174 Real avg = 0;
175 for (Size k = 0; k < steps(); k++) {
176 Real pp = conditionalProbability(p, m(k));
177 avg += pp * densitydm(k);
178 }
179 return avg;
180 }
181
182 /*! Integral over the density \f$ \rho(m) \f$ of M and a
183 one-dimensional function \f$ f \f$ of conditional
184 probabilities related to the input vector of probabilities p:
185
186 \f[
187 \int_{-\infty}^\infty\,dm\,\rho(m)\, f (\hat p_1, \hat p_2, \dots,
188 \hat p_N), \qquad
189 \hat p_i (m) = F_Z \left( \frac{F_Y^{-1}(p_i)-a\,m}{\sqrt{1-a^2}}
190 \right)
191 \f]
192 */
193 template <class F>
194 Real integral(const F& f, std::vector<Real>& probabilities) const {
195 calculate();
196
197 Real avg = 0.0;
198 for (Size i = 0; i < steps_; i++) {
199 std::vector<Real> conditional
200 = conditionalProbability(probabilities, m(i));
201 Real prob = f(conditional);
202 avg += prob * densitydm(i);
203 }
204 return avg;
205 }
206
207 /*! Integral over the density \f$ \rho(m) \f$ of M and a
208 multi-dimensional function \f$ f \f$ of conditional
209 probabilities related to the input vector of probabilities p:
210
211 \f[
212 \int_{-\infty}^\infty\,dm\,\rho(m)\, f (\hat p_1, \hat p_2, \dots,
213 \hat p_N), \qquad
214 \hat p_i = F_Z \left( \frac{F_Y^{-1}(p_i)-a\,m}{\sqrt{1-a^2}}\right)
215 \f]
216 */
217 template <class F>
219 const std::vector<Real>& nominals,
220 const std::vector<Real>& probabilities) const {
221 calculate();
222
223 Distribution dist(f.buckets(), 0.0, f.maximum());
224 for (Size i = 0; i < steps(); i++) {
225 std::vector<Real> conditional
226 = conditionalProbability(probabilities, m(i));
227 Distribution d = f(nominals, conditional);
228 for (Size j = 0; j < dist.size(); j++)
229 dist.addDensity(j, d.density(j) * densitydm(i));
230 }
231 return dist;
232 }
233
234 /*! Check moments (unit norm, zero mean and unit variance) of
235 the distributions of M, Z, and Y by numerically
236 integrating the respective density. Parameter tolerance
237 is the maximum tolerable absolute error.
238 */
239 int checkMoments(Real tolerance) const;
240
241 protected:
243 mutable Real max_;
244 mutable Size steps_;
245 mutable Real min_;
246
247 // Tabulated numerical solution of the cumulated distribution of Y
248 mutable std::vector<Real> y_;
249 mutable std::vector<Real> cumulativeY_;
250
251 //private:
252 // utilities for simple Euler integrations over the density of M
253 Size steps() const;
254
255 // i not used yet, might allow varying grid size
256 // for the copula integration in the future
257 Real dm(Size i) const;
258
259 Real m(Size i) const;
260 Real densitydm(Size i) const;
261 };
262
264 calculate();
265 return correlation_->value();
266 }
267
269 return steps_;
270 }
271
273 return (max_ - min_)/ steps_;
274 }
275
276 inline Real OneFactorCopula::m(Size i) const {
277 QL_REQUIRE(i < steps_, "index out of range");
278 return min_ + dm(i) * i + dm(i) / 2;
279 }
280
282 QL_REQUIRE(i < steps_, "index out of range");
283 return density(m(i)) * dm(i);
284 }
285
286}
287
288#endif
void addDensity(int bucket, Real value)
Shared handle to an observable.
Definition: handle.hpp:41
Framework for calculation on demand and result caching.
Definition: lazyobject.hpp:35
virtual void calculate() const
Definition: lazyobject.hpp:253
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Abstract base class for one-factor copula models.
Real conditionalProbability(Real prob, Real m) const
Conditional probability.
virtual Real density(Real m) const =0
Density function of M.
Real integral(Real p) const
Distribution integral(const F &f, const std::vector< Real > &nominals, const std::vector< Real > &probabilities) const
virtual Real cumulativeZ(Real z) const =0
Cumulative distribution of Z.
Real correlation() const
Single correlation parameter.
Real densitydm(Size i) const
std::vector< Real > cumulativeY_
virtual Real inverseCumulativeY(Real p) const
Inverse cumulative distribution of Y.
Real integral(const F &f, std::vector< Real > &probabilities) const
int checkMoments(Real tolerance) const
virtual Real cumulativeY(Real y) const
Cumulative distribution of Y.
OneFactorCopula(Handle< Quote > correlation, Real maximum=5.0, Size integrationSteps=50, Real minimum=-5.0)
Discretized probability density and cumulative probability.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
Date d
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
framework for calculation on demand and result caching
Definition: any.hpp:35
STL namespace.
purely virtual base class for market observables
Real F
Definition: sabr.cpp:200