22#ifndef QL_PATCH_SOLARIS
24#include <boost/make_shared.hpp>
35 const std::vector<Handle<RecoveryRateQuote>>& quotes)
36 :
LatentModel<GaussianCopulaPolicy>(
sqrt(correlQuote->value()), quotes.size(),
38 GaussianCopulaPolicy::initTraits()),
39 sqrt1minuscorrel_(std::
sqrt(1. - correlQuote->value())), correl_(correlQuote), rrQuotes_(quotes),
40 beta_(
sqrt(correlQuote->value())), biphi_(-
sqrt(correlQuote->value())) {
41 registerWith(correl_);
42 for (Size i = 0; i < quotes.size(); i++)
43 registerWith(quotes[i]);
46GaussianLHPLossModel::GaussianLHPLossModel(Real correlation,
const std::vector<Real>& recoveries)
47 :
LatentModel<GaussianCopulaPolicy>(
sqrt(correlation), recoveries.size(),
49 GaussianCopulaPolicy::initTraits()),
50 sqrt1minuscorrel_(std::
sqrt(1. - correlation)),
51 correl_(Handle<Quote>(
QuantLib::ext::make_shared<SimpleQuote>(correlation))), beta_(
sqrt(correlation)),
52 biphi_(-
sqrt(correlation)) {
53 for (Size i = 0; i < recoveries.size(); i++)
54 rrQuotes_.push_back(Handle<RecoveryRateQuote>(QuantLib::ext::make_shared<RecoveryRateQuote>(recoveries[i])));
58 :
LatentModel<GaussianCopulaPolicy>(
sqrt(correlQuote->value()), recoveries.size(),
60 GaussianCopulaPolicy::initTraits()),
61 sqrt1minuscorrel_(std::
sqrt(1. - correlQuote->value())), correl_(correlQuote), beta_(
sqrt(correlQuote->value())),
62 biphi_(-
sqrt(correlQuote->value())) {
64 for (Size i = 0; i < recoveries.size(); i++)
65 rrQuotes_.push_back(Handle<RecoveryRateQuote>(QuantLib::ext::make_shared<RecoveryRateQuote>(recoveries[i])));
72 Real attachLimit, Real detachLimit)
const {
74 if (attachLimit >= detachLimit)
77 if (remainingNot == 0.)
80 const Real one = 1.0 - 1.0e-12;
81 const Real k1 = std::min(one, attachLimit / (1.0 - averageRR)) + QL_EPSILON;
82 const Real k2 = std::min(one, detachLimit / (1.0 - averageRR)) + QL_EPSILON;
85 const Real ip = InverseCumulativeNormal::standard_value(prob);
89 return remainingNot * (detachLimit *
phi_(invFlightK2) - attachLimit *
phi_(invFlightK1) +
90 (1. - averageRR) * (
biphi_(ip, -invFlightK2) -
biphi_(ip, -invFlightK1)));
97 QL_REQUIRE(remainingLossFraction >= 0.,
"Incorrect loss fraction.");
98 QL_REQUIRE(remainingLossFraction <= 1.,
"Incorrect loss fraction.");
100 Real remainingAttachAmount =
basket_->remainingAttachmentAmount();
101 Real remainingDetachAmount =
basket_->remainingDetachmentAmount();
104 const Real remainingBasktNot =
basket_->remainingNotional(d);
105 const Real attach = std::min(remainingAttachAmount / remainingBasktNot, 1.);
106 const Real detach = std::min(remainingDetachAmount / remainingBasktNot, 1.);
108 Real portfFract = attach + remainingLossFraction * (detach - attach);
111 Real maxAttLossFract = (1. - averageRR);
112 if (portfFract > maxAttLossFract)
118 if (portfFract <= QL_EPSILON)
123 Real ip = InverseCumulativeNormal::standard_value(prob);
125 (ip -
sqrt1minuscorrel_ * InverseCumulativeNormal::standard_value(portfFract / (1. - averageRR))) /
beta_;
127 return phi_(invFlightK);
133 Real remainingAttachAmount =
basket_->remainingAttachmentAmount();
134 Real remainingDetachAmount =
basket_->remainingDetachmentAmount();
136 const Real remainingNot =
basket_->remainingNotional(d);
137 const Real attach = std::min(remainingAttachAmount / remainingNot, 1.);
138 const Real detach = std::min(remainingDetachAmount / remainingNot, 1.);
140 if (ptflLossPerc >= detach - QL_EPSILON)
141 return remainingNot * (detach - attach);
143 Real maxLossLevel = std::max(attach, ptflLossPerc);
150 probOverLoss(d, std::min(std::max((maxLossLevel - attach) / (detach - attach), 0.), 1.));
151 return (valA + (maxLossLevel - attach) * remainingNot * valB) / (1. - perctl);
156 QL_REQUIRE(perctl >= 0. && perctl <= 1.,
"Percentile argument out of bounds.");
161 perctl = 1. - QL_EPSILON;
164 beta_ * InverseCumulativeNormal::standard_value(perctl)) /
RelinkableHandle< QuantExt::Basket > basket_
Probability averageProb(const Date &d) const
Real percentilePortfolioLossFraction(const Date &d, Real perctl) const
std::vector< Handle< QuantLib::RecoveryRateQuote > > rrQuotes_
Real expectedTrancheLossImpl(Real remainingNot, Real prob, Real averageRR, Real attachLimit, Real detachLimit) const
BivariateCumulativeNormalDistribution biphi_
Real averageRecovery(const Date &d) const
Real probOverLoss(const Date &d, Real remainingLossFraction) const override
Real expectedShortfall(const Date &d, Probability perctl) const override
Returns the ESF as an absolute amount (rather than a fraction)
static CumulativeNormalDistribution const phi_
GaussianLHPLossModel(const Handle< Quote > &correlQuote, const std::vector< Handle< QuantLib::RecoveryRateQuote > > "es)
RandomVariable sqrt(RandomVariable x)