QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
defaultprobabilitylatentmodel.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2014 Jose Aparicio
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#ifndef quantlib_default_latent_model_hpp
21#define quantlib_default_latent_model_hpp
22
23#include <ql/experimental/credit/basket.hpp>
24#include <ql/experimental/math/latentmodel.hpp>
25#include <ql/experimental/math/gaussiancopulapolicy.hpp>
26#include <boost/dynamic_bitset.hpp>
27
28namespace QuantLib {
29
43 template<class copulaPolicy>
44 class DefaultLatentModel : public LatentModel<copulaPolicy> {
45 // import template members
46 protected:
50 public:
54 protected:
55 // not a handle, the model doesnt keep any cached magnitudes, no need
56 // for notifications, still...
57 mutable ext::shared_ptr<Basket> basket_;
58 ext::shared_ptr<LMIntegration> integration_;
59 private:
60 typedef typename copulaPolicy::initTraits initTraits;
61 public:
71 const std::vector<std::vector<Real> >& factorWeights,
73 const initTraits& ini = initTraits()
74 )
76 integration_(LatentModel<copulaPolicy>::IntegrationFactory::
77 createLMIntegration(factorWeights[0].size(), integralType))
78 { }
80 const Handle<Quote>& mktCorrel,
81 Size nVariables,
83 const initTraits& ini = initTraits()
84 )
85 : LatentModel<copulaPolicy>(mktCorrel, nVariables, ini),
86 integration_(LatentModel<copulaPolicy>::IntegrationFactory::
87 createLMIntegration(1, integralType))
88 { }
89 /* \todo
90 Add other constructors as in LatentModel for ease of use. (less
91 dimensions, factors, etcc...)
92 */
93
94 /* To interface with loss models. It is possible to change the basket
95 since there are no cached magnitudes.
96 */
97 void resetBasket(const ext::shared_ptr<Basket>& basket) const {
98 basket_ = basket;
99 // in the future change 'size' to 'liveSize'
100 QL_REQUIRE(basket_->size() == factorWeights_.size(),
101 "Incompatible new basket and model sizes.");
102 }
103
115 const std::vector<Real>& mktFactors) const
116 {
117 // we can be called from the outside (from an integrable loss model)
118 // but we are called often at integration points. This or
119 // consider a list of friends.
120 #if defined(QL_EXTRA_SAFETY_CHECKS)
121 QL_REQUIRE(basket_, "No portfolio basket set.");
122 #endif
123 /*Avoid redundant call to minimum value inversion (might be \infty),
124 and this independently of the copula function.
125 */
126 if (prob < 1.e-10) return 0.;// use library macro...
128 inverseCumulativeY(prob, iName), iName, mktFactors);
129 }
130 protected:
131 void update() override {
132 if (basket_ != nullptr)
133 basket_->notifyObservers();
135 }
136
137 public:// open since users access it for performance on joint integrations.
138
152 Size iName,
153 const std::vector<Real>& m) const {
154 Real sumMs =
155 std::inner_product(factorWeights_[iName].begin(),
156 factorWeights_[iName].end(), m.begin(), Real(0.));
157 Real res = cumulativeZ((invCumYProb - sumMs) /
158 idiosyncFctrs_[iName] );
159 #if defined(QL_EXTRA_SAFETY_CHECKS)
160 QL_REQUIRE (res >= 0. && res <= 1.,
161 "conditional probability " << res << "out of range");
162 #endif
163
164 return res;
165 }
166 protected:
180 const std::vector<Real>& mktFactors) const
181 {
182 const ext::shared_ptr<Pool>& pool = basket_->pool();
183 Probability pDefUncond =
184 pool->get(pool->names()[iName]).
185 defaultProbability(basket_->defaultKeys()[iName])
186 ->defaultProbability(date);
187 return conditionalDefaultProbability(pDefUncond, iName, mktFactors);
188 }
191 Probability condProbProduct(Real invCumYProb1, Real invCumYProb2,
192 Size iName1, Size iName2,
193 const std::vector<Real>& mktFactors) const {
194 return
195 conditionalDefaultProbabilityInvP(invCumYProb1, iName1,
196 mktFactors) *
197 conditionalDefaultProbabilityInvP(invCumYProb2, iName2,
198 mktFactors);
199 }
201 // \todo: check the issuer has not defaulted.
203 const std::vector<Real>& mktFactors) const;
205 const ext::shared_ptr<LMIntegration>& integration() const override { return integration_; }
206
207 public:
211 Probability probOfDefault(Size iName, const Date& d) const {
212 QL_REQUIRE(basket_, "No portfolio basket set.");
213 const ext::shared_ptr<Pool>& pool = basket_->pool();
214 // avoid repeating this in the integration:
215 Probability pUncond = pool->get(pool->names()[iName]).
216 defaultProbability(basket_->defaultKeys()[iName])
217 ->defaultProbability(d);
218 if (pUncond < 1.e-10) return 0.;
219
221 [&](const std::vector<Real>& v1) {
223 inverseCumulativeY(pUncond, iName), iName, v1);
224 });
225 }
232 Real defaultCorrelation(const Date& d, Size iNamei, Size iNamej) const;
233
237 Probability probAtLeastNEvents(Size n, const Date& date) const {
239 [&](const std::vector<Real>& v1) {
240 return conditionalProbAtLeastNEvents(n, date, v1);
241 });
242 }
243 };
244
245
246 //---- Defines -----------------------------------------------------------
247
248 template<class CP>
250 Size iNamei, Size iNamej) const
251 {
252 QL_REQUIRE(basket_, "No portfolio basket set.");
253
254 const ext::shared_ptr<Pool>& pool = basket_->pool();
255 // unconditionals:
256 Probability pi = pool->get(pool->names()[iNamei]).
257 defaultProbability(basket_->defaultKeys()[iNamei])
258 ->defaultProbability(d);
259 Probability pj = pool->get(pool->names()[iNamej]).
260 defaultProbability(basket_->defaultKeys()[iNamej])
261 ->defaultProbability(d);
262 Real pipj = pi * pj;
263 Real invPi = inverseCumulativeY(pi, iNamei);
264 Real invPj = inverseCumulativeY(pj, iNamej);
265 // avoid repetitive calls when i=j?
266 Real E1i1j; // joint default covariance term
267 if(iNamei !=iNamej) {
268 E1i1j = integratedExpectedValue(
269 [&](const std::vector<Real>& v1) {
270 return condProbProduct(invPi, invPj, iNamei, iNamej, v1); });
271 }else{
272 E1i1j = pi;
273 }
274 return (E1i1j - pipj )/std::sqrt(pipj*(1.-pi)*(1.-pj));
275 }
276
277
278 template<class CP>
280 const Date& date,
281 const std::vector<Real>& mktFactors) const {
282 QL_REQUIRE(basket_, "No portfolio basket set.");
283
284 /* \todo
285 This algorithm traverses all permutations starting form the
286 lowest one. This is inneficient, there shouldnt be any need to
287 go through the invalid ones. Use combinations of n elements.
288
289 See integration in O'Kane for homogeneous ntds.
290 */
291 // first position with as many defaults as desired:
292 Size poolSize = basket_->size();//move to 'livesize'
293 const ext::shared_ptr<Pool>& pool = basket_->pool();
294
295 auto limit = static_cast<BigNatural>(std::pow(2., (int)(poolSize)));
296
297 // Precalc conditional probabilities
298 std::vector<Probability> pDefCond;
299 for(Size i=0; i<poolSize; i++)
300 pDefCond.push_back(conditionalDefaultProbability(
301 pool->get(pool->names()[i]).
302 defaultProbability(basket_->defaultKeys()[i])->
303 defaultProbability(date), i, mktFactors));
304
305 Probability probNEventsOrMore = 0.;
306 for (auto mask = static_cast<BigNatural>(std::pow(2., (int)(n)) - 1); mask < limit;
307 mask++) {
308 // cheap permutations
309 boost::dynamic_bitset<> bsetMask(poolSize, mask);
310 if(bsetMask.count() >= n) {
311 Probability pConfig = 1;
312 for(Size i=0; i<bsetMask.size(); i++)
313 pConfig *=
314 (bsetMask[i] ? pDefCond[i] : (1.- pDefCond[i]));
315 probNEventsOrMore += pConfig;
316 }
317 }
318 return probNEventsOrMore;
319 }
320
321
322 // often used:
325}
326
327#endif
Concrete date class.
Definition: date.hpp:125
DefaultLatentModel(const std::vector< std::vector< Real > > &factorWeights, LatentModelIntegrationType::LatentModelIntegrationType integralType, const initTraits &ini=initTraits())
Probability condProbProduct(Real invCumYProb1, Real invCumYProb2, Size iName1, Size iName2, const std::vector< Real > &mktFactors) const
Probability conditionalDefaultProbability(const Date &date, Size iName, const std::vector< Real > &mktFactors) const
Probability conditionalDefaultProbability(Probability prob, Size iName, const std::vector< Real > &mktFactors) const
DefaultLatentModel(const Handle< Quote > &mktCorrel, Size nVariables, LatentModelIntegrationType::LatentModelIntegrationType integralType, const initTraits &ini=initTraits())
void resetBasket(const ext::shared_ptr< Basket > &basket) const
Real defaultCorrelation(const Date &d, Size iNamei, Size iNamej) const
Real conditionalProbAtLeastNEvents(Size n, const Date &date, const std::vector< Real > &mktFactors) const
Conditional probability of n default events or more.
const ext::shared_ptr< LMIntegration > & integration() const override
access to integration:
ext::shared_ptr< LMIntegration > integration_
Probability probOfDefault(Size iName, const Date &d) const
Probability probAtLeastNEvents(Size n, const Date &date) const
Probability conditionalDefaultProbabilityInvP(Real invCumYProb, Size iName, const std::vector< Real > &m) const
Shared handle to an observable.
Definition: handle.hpp:41
Generic multifactor latent variable model.
Real inverseCumulativeY(Probability p, Size iVariable) const
std::vector< std::vector< Real > > factorWeights_
void update() override
Probability cumulativeZ(Real z) const
Cumulative distribution of Z, the idiosyncratic/error factors.
const std::vector< std::vector< Real > > & factorWeights() const
Provides values of the factors .
Real integratedExpectedValue(const ext::function< Real(const std::vector< Real > &v1)> &f) const
QL_REAL Real
real number
Definition: types.hpp:50
Real Probability
probability
Definition: types.hpp:82
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
DefaultLatentModel< GaussianCopulaPolicy > GaussianDefProbLM
DefaultLatentModel< TCopulaPolicy > TDefProbLM
unsigned QL_BIG_INTEGER BigNatural
large positive integer
Definition: types.hpp:46