QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
inhomogeneouspooldef.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2008 Roland Lichters
5 Copyright (C) 2009, 2014 Jose Aparicio
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#ifndef quantlib_inhomogenous_pool_default_model_hpp
22#define quantlib_inhomogenous_pool_default_model_hpp
23
24#include <ql/experimental/credit/lossdistribution.hpp>
25#include <ql/experimental/credit/basket.hpp>
26#include <ql/experimental/credit/constantlosslatentmodel.hpp>
27#include <ql/experimental/credit/defaultlossmodel.hpp>
28
29// Intended to replace InhomogeneousPoolCDOEngine in syntheticcdoengines.hpp
30
31namespace QuantLib {
32
33 //-------------------------------------------------------------------------
35 /* A note on the number of buckets: As it is now the code goes splitting
36 losses into buckets from loses equal to zero to losses up to the value of
37 the underlying basket. This is in view of a stochastic loss given default
38 but in a constant LGD situation this is a waste and it is more efficient to
39 go up to the attainable losses.
40 \todo Extend to the multifactor case for a generic LM
41 \todo Many common code with the homogeneous version, both classes perform
42 the same work on different loss distribution types, merge and send the
43 distribution object?
44 */
45 template<class copulaPolicy>
47 private:
48 void resetModel() override;
49
50 public:
51 // allow base correlations:
53
55 // restricted to non random recoveries, but it could be possible.
56 const ext::shared_ptr<ConstantLossLatentmodel<copulaPolicy> >&
57 copula,
58 Size nBuckets,
59 Real max = 5.,
60 Real min = -5.,
61 Size nSteps = 50)
62 : copula_(copula),
63 nBuckets_(nBuckets),
64 max_(max), min_(min), nSteps_(nSteps), delta_((max - min)/nSteps)
65 {
66 QL_REQUIRE(copula->numFactors() == 1,
67 "Inhomogeneous model not implemented for multifactor");
68 }
69 // Write another constructor sending the LM factors and recoveries.
70 protected:
71 Distribution lossDistrib(const Date& d) const;
72 public:
73 Real expectedTrancheLoss(const Date& d) const override {
75 // This one if the distribution is over the whole loss structure:
76 // but it becomes very expensive
77 /*
78 return lossDistrib(d).trancheExpectedValue(
79 attachAmount_, detachAmount_);
80 */
81 }
82 Real percentile(const Date& d, Real percentile) const override {
84 return std::min(std::max(portfLoss - attachAmount_, 0.), detachAmount_ - attachAmount_);
85 }
86 Real expectedShortfall(const Date& d, Probability percentile) const override {
87 Distribution dist = lossDistrib(d);
89 return dist.expectedShortfall(percentile);
90 }
91
92 protected:
93 const ext::shared_ptr<ConstantLossLatentmodel<copulaPolicy> > copula_;
96 mutable std::vector<Real> notionals_;
97 private:
98 // integration:
99 // \todo move integration to latent model types when moving to a
100 // multifactor version
101 const Real max_;// redundant?
102 const Real min_;
104 const Real delta_;
105 };
106 // \todo Add other loss distribution statistics
110
111 //-----------------------------------------------------------------------
112
113 template<class CP>
115 {
116 // need to be capped now since the limit amounts might be over the
117 // remaining notional (think amortizing)
118 attach_ = std::min(basket_->remainingAttachmentAmount() /
119 basket_->remainingNotional(), 1.);
120 detach_ = std::min(basket_->remainingDetachmentAmount() /
121 basket_->remainingNotional(), 1.);
122 notional_ = basket_->remainingNotional();
123 notionals_ = basket_->remainingNotionals();
124 attachAmount_ = basket_->remainingAttachmentAmount();
125 detachAmount_ = basket_->remainingDetachmentAmount();
126
127 copula_->resetBasket(basket_.currentLink());
128 }
129
130 template<class CP>
132 const Date& d) const
133 {
134 LossDistBucketing bucktLDistBuff(nBuckets_, detachAmount_);
135
136 std::vector<Real> lgd;// switch to a mutable cache member
137 std::vector<Real> recoveries = copula_->recoveries();
138 std::transform(recoveries.begin(), recoveries.end(),
139 std::back_inserter(lgd),
140 [](Real x) -> Real { return 1.0-x; });
141 std::transform(lgd.begin(), lgd.end(), notionals_.begin(),
142 lgd.begin(), std::multiplies<>());
143 std::vector<Real> prob = basket_->remainingProbabilities(d);
144 for(Size iName=0; iName<prob.size(); iName++)
145 prob[iName] = copula_->inverseCumulativeY(prob[iName], iName);
146
147 // integrate locally (1 factor).
148 // use explicitly a 1D latent model object?
149 // \todo Use a library integrator here and in the homogeneous case.
150 Distribution dist(nBuckets_, 0.0,
151 detachAmount_);
152 //notional_);
153 std::vector<Real> mkft(1, min_ + delta_ /2.);
154 for (Size i = 0; i < nSteps_; i++) {
155 std::vector<Real> conditionalProbs;
156 for(Size iName=0; iName<notionals_.size(); iName++)
157 conditionalProbs.push_back(
158 copula_->conditionalDefaultProbabilityInvP(prob[iName], iName,
159 mkft));
160 Distribution bld = bucktLDistBuff(lgd, conditionalProbs);
161 Real densitydm = delta_ * copula_->density(mkft);
162 // also, instead of calling the static method it could be wrapped
163 // through an inlined call in the latent model
164 for (Size j = 0; j < nBuckets_; j++)
165 dist.addDensity(j, bld.density(j) * densitydm);
166 mkft[0] += delta_;
167 }
168 return dist;
169 }
170
171
172}
173
174#endif
Concrete date class.
Definition: date.hpp:125
void tranche(Real attachmentPoint, Real detachmentPoint)
Real cumulativeExcessProbability(Real a, Real b)
Real confidenceLevel(Real quantil)
void addDensity(int bucket, Real value)
Real expectedShortfall(Real percValue)
Default loss distribution convolution for finite non homogeneous pool.
Distribution lossDistrib(const Date &d) const
Real percentile(const Date &d, Real percentile) const override
Value at Risk given a default loss percentile.
const ext::shared_ptr< ConstantLossLatentmodel< copulaPolicy > > copula_
InhomogeneousPoolLossModel(const ext::shared_ptr< ConstantLossLatentmodel< copulaPolicy > > &copula, Size nBuckets, Real max=5., Real min=-5., Size nSteps=50)
void resetModel() override
Concrete models do now any updates/inits they need on basket reset.
Real expectedShortfall(const Date &d, Probability percentile) const override
Expected shortfall given a default loss percentile.
Real expectedTrancheLoss(const Date &d) const override
Loss distribution with Hull-White bucketing.
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
InhomogeneousPoolLossModel< GaussianCopulaPolicy > IHGaussPoolLossModel
InhomogeneousPoolLossModel< TCopulaPolicy > IHStudentPoolLossModel