QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
spotlosslatentmodel.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_spotlosslatentmodel_hpp
21#define quantlib_spotlosslatentmodel_hpp
22
23#include <ql/experimental/credit/defaultprobabilitylatentmodel.hpp>
24
25namespace QuantLib {
26
41 template <class copulaPolicy>
42 class SpotRecoveryLatentModel : public LatentModel<copulaPolicy> {
43 public:
44 // resolve LM interface:
50 private:
51 const std::vector<Real> recoveries_;
53 // products of default and recoveries factors, see refs ('covariances')
54 std::vector<Real> crossIdiosyncFctrs_;
55 mutable Size numNames_;
56 mutable ext::shared_ptr<Basket> basket_;
57 ext::shared_ptr<LMIntegration> integration_;
58 protected:
60 const ext::shared_ptr<LMIntegration>& integration() const override { return integration_; }
61
62 private:
63 typedef typename copulaPolicy::initTraits initTraits;
64 public:
66 const std::vector<std::vector<Real> >& factorWeights,
67 const std::vector<Real>& recoveries,
68 Real modelA,
70 const initTraits& ini = initTraits()
71 );
72
73 void resetBasket(const ext::shared_ptr<Basket>& basket) const;
75 const std::vector<Real>& mktFactors) const;
77 const std::vector<Real>& mktFactors) const;
79 Size iName,
80 const std::vector<Real>& m) const;
93 Real expCondRecovery/*conditionalRecovery*/(const Date& d, Size iName,
94 const std::vector<Real>& mktFactors) const;
95 Real expCondRecoveryP(Real uncondDefP, Size iName,
96 const std::vector<Real>& mktFactors) const;
97 Real expCondRecoveryInvPinvRR(Real invUncondDefP, Real invUncondRR,
98 Size iName, const std::vector<Real>& mktFactors) const;
104 Real conditionalRecovery(Real latentVarSample, Size iName,
105 const Date& d) const;
114 Real latentRRVarValue(const std::vector<Real>& allFactors,
115 Size iName) const;
116 Real conditionalExpLossRR(const Date& d, Size iName,
117 const std::vector<Real>& mktFactors) const;
118 Real conditionalExpLossRRInv(Real invP, Real invRR, Size iName,
119 const std::vector<Real>& mktFactors) const;
126 Real expectedLoss(const Date& d, Size iName) const;
127 };
128
129
132
133
134 // ------------------------------------------------------------------------
135
136 template <class CP>
137 inline void
138 SpotRecoveryLatentModel<CP>::resetBasket(const ext::shared_ptr<Basket>& basket) const {
139 basket_ = basket;
140 // in the future change 'size' to 'liveSize'
141 QL_REQUIRE(basket_->size() == numNames_,
142 "Incompatible new basket and model sizes.");
143 }
144
145 template<class CP>
146 inline Probability
148 const Date& date,
149 Size iName, const std::vector<Real>& mktFactors) const
150 {
151 const ext::shared_ptr<Pool>& pool = basket_->pool();
152 Probability pDefUncond =
153 pool->get(pool->names()[iName]).
154 defaultProbability(basket_->defaultKeys()[iName])
155 ->defaultProbability(date);
156 return conditionalDefaultProbability(pDefUncond, iName, mktFactors);
157 }
158
159 template<class CP>
160 inline Probability
162 Probability prob,
163 Size iName, const std::vector<Real>& mktFactors) const
164 {
165 // we can be called from the outside (from an integrable loss model)
166 // but we are called often at integration points. This or
167 // consider a list of friends.
168 #if defined(QL_EXTRA_SAFETY_CHECKS)
169 QL_REQUIRE(basket_, "No portfolio basket set.");
170 #endif
171 /*Avoid redundant call to minimum value inversion (might be \infty),
172 and this independently of the copula function.
173 */
174 if (prob < 1.e-10) return 0.;// use library macro...
175 return conditionalDefaultProbabilityInvP(
176 inverseCumulativeY(prob, iName), iName, mktFactors);
177 }
178
179 template<class CP>
180 inline Probability
182 Real invCumYProb,
183 Size iName,
184 const std::vector<Real>& m) const
185 {
186 Real sumMs =
187 std::inner_product(this->factorWeights_[iName].begin(),
188 this->factorWeights_[iName].end(), m.begin(), 0.);
189 Real res = this->cumulativeZ((invCumYProb - sumMs) /
190 this->idiosyncFctrs_[iName] );
191 #if defined(QL_EXTRA_SAFETY_CHECKS)
192 QL_REQUIRE (res >= 0. && res <= 1.,
193 "conditional probability " << res << "out of range");
194 #endif
195
196 return res;
197 }
198
199 template<class CP>
200 inline Real
202 Size iName,
203 const std::vector<Real>& mktFactors) const
204 {
205 #if defined(QL_EXTRA_SAFETY_CHECKS)
206 QL_REQUIRE(mktFactors.size() == this->numFactors(),
207 "Realization of market factors and latent model size do not match");
208 #endif
209 const ext::shared_ptr<Pool>& pool = basket_->pool();
210 Probability pDefUncond =
211 pool->get(pool->names()[iName]).
212 defaultProbability(basket_->defaultKeys()[iName])
213 ->defaultProbability(d);
214
215 return expCondRecoveryP(pDefUncond, iName, mktFactors);
216 }
217
218 template<class CP>
220 Real uncondDefP, Size iName, const std::vector<Real>& mktFactors) const
221 {
222 return expCondRecoveryInvPinvRR(
223 inverseCumulativeY(uncondDefP, iName),
224 inverseCumulativeY(recoveries_[iName], iName + numNames_),
225 iName, mktFactors);
226 }
227
228 template<class CP>
230 Real invUncondDefP,
231 Real invUncondRR,
232 Size iName,
233 const std::vector<Real>& mktFactors) const
234 {
235 const std::vector<std::vector<Real> >& fctrs_ = factorWeights();
236 //Size iRR = iName + basket_->size();// should be live pool
237 const Real sumMs =
238 std::inner_product(fctrs_[iName].begin(), fctrs_[iName].end(),
239 mktFactors.begin(), 0.);
240 const Real sumBetaLoss =
241 std::inner_product(fctrs_[iName + numNames_].begin(),
242 fctrs_[iName + numNames_].end(),
243 fctrs_[iName + numNames_].begin(),
244 0.);
245 return this->cumulativeZ((sumMs + std::sqrt(1.-crossIdiosyncFctrs_[iName])
246 * std::sqrt(1.+modelA_*modelA_) *
247 invUncondRR
248 - std::sqrt(crossIdiosyncFctrs_[iName]) *
249 invUncondDefP
250 )
251 / std::sqrt(1.- sumBetaLoss + modelA_*modelA_ *
252 (1.-crossIdiosyncFctrs_[iName])) );
253 }
254
255 template<class CP>
257 Size iName, const Date& d) const
258 {
259 const ext::shared_ptr<Pool>& pool = basket_->pool();
260
261 // retrieve the default probability for this name
263 pool->get(basket_->names()[iName]).defaultProbability(
264 basket_->defaultKeys()[iName]);
265 const Probability pdef = dfts->defaultProbability(d, true);
266 // before asking for -\infty
267 if (pdef < 1.e-10) return 0.;
268
269 Size iRecovery = iName + numNames_;// should be live pool
270 return cumulativeY(
271 (latentVarSample - std::sqrt(crossIdiosyncFctrs_[iName])
272 * inverseCumulativeY(pdef, iName)) /
273 (modelA_ * std::sqrt(1.-crossIdiosyncFctrs_[iName]))
274 // cache the sqrts
275 // cache this factor.
276 +std::sqrt(1.+ 1./(modelA_*modelA_)) *
277 inverseCumulativeY(recoveries_[iName], iRecovery)
278 , iRecovery);
279 }
280
281 template<class CP>
283 const std::vector<Real>& allFactors,
284 Size iName) const
285 {
286 Size iRecovery = iName + numNames_;// should be live pool
287 return latentVarValue(allFactors, iRecovery);
288 }
289
290 template<class CP>
292 Size iName,
293 const std::vector<Real>& mktFactors) const
294 {
295 const ext::shared_ptr<Pool>& pool = basket_->pool();
296 Probability pDefUncond =
297 pool->get(pool->names()[iName]).
298 defaultProbability(basket_->defaultKeys()[iName])
299 ->defaultProbability(d);
300
301 Real invP = inverseCumulativeY(pDefUncond, iName);
302 Real invRR = inverseCumulativeY(recoveries_[iName], iName + numNames_);
303
304 return conditionalExpLossRRInv(invP, invRR, iName, mktFactors);
305 }
306
307 template<class CP>
309 Real invP,
310 Real invRR,
311 Size iName,
312 const std::vector<Real>& mktFactors) const
313 {
314 return conditionalDefaultProbabilityInvP(invP, iName, mktFactors)
315 * (1.-this->conditionalRecoveryInvPinvRR(invP, invRR, iName, mktFactors));
316 }
317
318 template<class CP>
320 Size iName) const
321 {
322 const ext::shared_ptr<Pool>& pool = basket_->pool();
323 Probability pDefUncond =
324 pool->get(pool->names()[iName]).
325 defaultProbability(basket_->defaultKeys()[iName])
326 ->defaultProbability(d);
327
328 Real invP = inverseCumulativeY(pDefUncond, iName);
329 Real invRR = inverseCumulativeY(recoveries_[iName], iName + numNames_);
330
331 return integratedExpectedValue(
332 [&](const std::vector<Real>& v){
333 return conditionalExpLossRRInv(invP, invRR, iName, v);
334 });
335 }
336
337 template<class CP>
339 const std::vector<std::vector<Real> >& factorWeights,
340 const std::vector<Real>& recoveries,
341 Real modelA,
343 const typename CP::initTraits& ini
344 )
345 : LatentModel<CP>(factorWeights, ini),
346 recoveries_(recoveries),
347 modelA_(modelA),
348 numNames_(factorWeights.size()/2),
349 integration_(LatentModel<CP>::IntegrationFactory::
350 createLMIntegration(factorWeights[0].size(), integralType))
351 {
352 QL_REQUIRE(factorWeights.size() % 2 == 0,
353 "Number of RR variables must be equal to number of default variables");
354 QL_REQUIRE(recoveries.size() == numNames_ ,
355 "Number of recoveries does not match number of defaultable entities.");
356
357 // reminder: first betas are default, last ones are recovery
358 for(Size iName=0; iName<numNames_; iName++)
359 /* Corresponds to: (k denotes factor, i denotes modelled
360 variable -default and recoveries))
361 \sum_k a^2_{i,k} a^2_{N+i,k}
362 */
363 {
364 Real cumul = 0.;
365 for(Size iB=0; iB<factorWeights[iName].size(); iB++)
366 // actually this size is unique
367 cumul += factorWeights[iName][iB] *
368 factorWeights[iName][iB] *
369 factorWeights[iName + numNames_][iB] *
370 factorWeights[iName + numNames_][iB];
371 crossIdiosyncFctrs_.push_back(cumul);
372 }
373
374 }
375
376
377}
378
379#endif
Concrete date class.
Definition: date.hpp:125
Shared handle to an observable.
Definition: handle.hpp:41
Generic multifactor latent variable model.
Real latentVarValue(const std::vector< Real > &allFactors, Size iVar) const
Real inverseCumulativeY(Probability p, Size iVariable) const
Probability cumulativeY(Real val, Size iVariable) const
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
Random spot recovery rate latent variable portfolio model.
Real conditionalExpLossRR(const Date &d, Size iName, const std::vector< Real > &mktFactors) const
SpotRecoveryLatentModel(const std::vector< std::vector< Real > > &factorWeights, const std::vector< Real > &recoveries, Real modelA, LatentModelIntegrationType::LatentModelIntegrationType integralType, const initTraits &ini=initTraits())
Real expectedLoss(const Date &d, Size iName) const
Probability conditionalDefaultProbability(const Date &date, Size iName, const std::vector< Real > &mktFactors) const
Real expCondRecoveryP(Real uncondDefP, Size iName, const std::vector< Real > &mktFactors) const
void resetBasket(const ext::shared_ptr< Basket > &basket) const
Real expCondRecovery(const Date &d, Size iName, const std::vector< Real > &mktFactors) const
const std::vector< Real > recoveries_
Real conditionalRecovery(Real latentVarSample, Size iName, const Date &d) const
Real latentRRVarValue(const std::vector< Real > &allFactors, Size iName) const
const ext::shared_ptr< LMIntegration > & integration() const override
access to integration:
ext::shared_ptr< LMIntegration > integration_
Real expCondRecoveryInvPinvRR(Real invUncondDefP, Real invUncondRR, Size iName, const std::vector< Real > &mktFactors) const
Real conditionalExpLossRRInv(Real invP, Real invRR, Size iName, const std::vector< Real > &mktFactors) const
Probability conditionalDefaultProbabilityInvP(Real invCumYProb, Size iName, const std::vector< Real > &m) 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
SpotRecoveryLatentModel< TCopulaPolicy > TSpotLossLM
SpotRecoveryLatentModel< GaussianCopulaPolicy > GaussianSpotLossLM