QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
homogeneouspooldef.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_homogenous_pool_default_model_hpp
22#define quantlib_homogenous_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 HomogeneousPoolCDOEngine 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 */
42 template<class copulaPolicy>
44 private:
45 void resetModel() override;
46
47 public:
49 const ext::shared_ptr<ConstantLossLatentmodel<copulaPolicy> >&
50 copula,
51 Size nBuckets,
52 Real max = 5.,
53 Real min = -5.,
54 Size nSteps = 50)
55 : copula_(copula),
56 nBuckets_(nBuckets),
57 max_(max), min_(min), nSteps_(nSteps), delta_((max - min)/nSteps)
58 {
59 QL_REQUIRE(copula->numFactors() == 1,
60 "Inhomogeneous model not implemented for multifactor");
61 }
62 protected:
63 Distribution lossDistrib(const Date& d) const;
64 public:
65 Real expectedTrancheLoss(const Date& d) const override {
67 // This one if the distribution is over the whole loss structure:
68 // but it becomes very expensive
69 /*
70 return lossDistrib(d).trancheExpectedValue(attach_ * notional_,
71 detach_ * notional_);
72 */
73 }
74 Real percentile(const Date& d, Real percentile) const override {
76 return std::min(std::max(portfLoss - attachAmount_, 0.), detachAmount_ - attachAmount_);
77 }
78 Real expectedShortfall(const Date& d, Probability percentile) const override {
79 Distribution dist = lossDistrib(d);
81 return dist.expectedShortfall(percentile);
82 }
83
84 protected:
85 const ext::shared_ptr<ConstantLossLatentmodel<copulaPolicy> > copula_;
88 mutable std::vector<Real> notionals_;
89 private:
90 // integration:
91 // \todo move integration to latent model types when moving to a
92 // multifactor version
93 const Real max_;// redundant?
94 const Real min_;
96 const Real delta_;
97 };
98 // \todo Add other loss distribution statistics
102
103 //-----------------------------------------------------------------------
104
105 template<class CP>
107 {
108 // need to be capped now since the limit amounts might be over the
109 // remaining notional (think amortizing)
110 attach_ = std::min(basket_->remainingAttachmentAmount() /
111 basket_->remainingNotional(), 1.);
112 detach_ = std::min(basket_->remainingDetachmentAmount() /
113 basket_->remainingNotional(), 1.);
114 notional_ = basket_->remainingNotional();
115 notionals_ = basket_->remainingNotionals();
116 attachAmount_ = basket_->remainingAttachmentAmount();
117 detachAmount_ = basket_->remainingDetachmentAmount();
118
119 copula_->resetBasket(basket_.currentLink());
120 }
121
122 template<class CP>
124 const Date& d) const
125 {
126 LossDistHomogeneous bucktLDistBuff(nBuckets_, detachAmount_);
127
128 std::vector<Real> lgd;// switch to a mutable cache member
129 std::vector<Real> recoveries = copula_->recoveries();
130 std::transform(recoveries.begin(), recoveries.end(),
131 std::back_inserter(lgd),
132 [](Real x) -> Real { return 1.0-x; });
133 std::transform(lgd.begin(), lgd.end(), notionals_.begin(),
134 lgd.begin(), std::multiplies<>());
135 std::vector<Real> prob = basket_->remainingProbabilities(d);
136 for(Size iName=0; iName<prob.size(); iName++)
137 prob[iName] = copula_->inverseCumulativeY(prob[iName], iName);
138
139 // integrate locally (1 factor).
140 // use explicitly a 1D latent model object?
141 Distribution dist(nBuckets_, 0.0,
142 detachAmount_);
143 //notional_);
144 std::vector<Real> mkft(1, min_ + delta_ /2.);
145 for (Size i = 0; i < nSteps_; i++) {
146 std::vector<Real> conditionalProbs;
147 for(Size iName=0; iName<notionals_.size(); iName++)
148 conditionalProbs.push_back(
149 copula_->conditionalDefaultProbabilityInvP(prob[iName], iName,
150 mkft));
151 Distribution bld = bucktLDistBuff(lgd, conditionalProbs);
152 Real densitydm = delta_ * copula_->density(mkft);
153 // also, instead of calling the static method it could be wrapped
154 // through an inlined call in the latent model
155 for (Size j = 0; j < nBuckets_; j++)
156 dist.addDensity(j, bld.density(j) * densitydm);
157 mkft[0] += delta_;
158 }
159 return dist;
160 }
161
162
163}
164
165#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 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_
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
HomogeneousPoolLossModel(const ext::shared_ptr< ConstantLossLatentmodel< copulaPolicy > > &copula, Size nBuckets, Real max=5., Real min=-5., Size nSteps=50)
Loss Distribution for Homogeneous Pool.
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
HomogeneousPoolLossModel< TCopulaPolicy > HomogTPoolLossModel
HomogeneousPoolLossModel< GaussianCopulaPolicy > HomogGaussPoolLossModel