Real GaussianLHPLossModel::expectedShortfall(const Date& d, Probability perctl) const { // loss as a fraction of the live portfolio Real ptflLossPerc = percentilePortfolioLossFraction(d, perctl); Real remainingAttachAmount = basket_->remainingAttachmentAmount(); Real remainingDetachAmount = basket_->remainingDetachmentAmount(); const Real remainingNot = basket_->remainingNotional(d); const Real attach = std::min(remainingAttachAmount / remainingNot, 1.); const Real detach = std::min(remainingDetachAmount / remainingNot, 1.); if(ptflLossPerc >= detach-QL_EPSILON) return remainingNot * (detach-attach);//equivalent Real maxLossLevel = std::max(attach, ptflLossPerc); Probability prob = averageProb(d); Real averageRR = averageRecovery(d); Real valA = expectedTrancheLossImpl(remainingNot, prob, averageRR, maxLossLevel, detach); Real valB = // probOverLoss(d, maxLossLevel);//in live tranche units // from fraction of basket notional to fraction of tranche notional probOverLoss(d, std::min(std::max((maxLossLevel - attach) /(detach - attach), 0.), 1.)); return ( valA + (maxLossLevel - attach) * remainingNot * valB ) / (1.-perctl); }
Real GaussianLHPLossModel::percentilePortfolioLossFraction( const Date& d, Real perctl) const { // this test goes into basket<<<<<<<<<<<<<<<<<<<<<<<<< QL_REQUIRE(perctl >= 0. && perctl <=1., "Percentile argument out of bounds."); if(perctl==0.) return 0.;// portfl == attach if(perctl==1.) perctl = 1. - QL_EPSILON; // portfl == detach return (1.-averageRecovery(d)) * phi_( ( InverseCumulativeNormal::standard_value(averageProb(d)) + beta_ * InverseCumulativeNormal::standard_value(perctl) ) /sqrt1minuscorrel_); }
Real expectedTrancheLoss(const Date& d) const { //can calls to Basket::remainingNotional(d) be cached?<<<<<<<<<<<<< const Real remainingfullNot = basket_->remainingNotional(d); Real averageRR = averageRecovery(d); Probability prob = averageProb(d); Real remainingAttachAmount = basket_->remainingAttachmentAmount(); Real remainingDetachAmount = basket_->remainingDetachmentAmount(); //const Real attach = std::min(remainingAttachAmount // / remainingfullNot, 1.); //const Real detach = std::min(remainingDetachAmount // / remainingfullNot, 1.); const Real attach = remainingAttachAmount / remainingfullNot; const Real detach = remainingDetachAmount / remainingfullNot; return expectedTrancheLossImpl(remainingfullNot, prob, averageRR, attach, detach); }
Real GaussianLHPLossModel::probOverLoss(const Date& d, Real remainingLossFraction) const { // these test goes into basket<<<<<<<<<<<<<<<<<<<<<<<<< QL_REQUIRE(remainingLossFraction >=0., "Incorrect loss fraction."); QL_REQUIRE(remainingLossFraction <=1., "Incorrect loss fraction."); Real remainingAttachAmount = basket_->remainingAttachmentAmount(); Real remainingDetachAmount = basket_->remainingDetachmentAmount(); // live unerlying portfolio loss fraction (remaining portf fraction) const Real remainingBasktNot = basket_->remainingNotional(d); const Real attach = std::min(remainingAttachAmount / remainingBasktNot, 1.); const Real detach = std::min(remainingDetachAmount / remainingBasktNot, 1.); Real portfFract = attach + remainingLossFraction * (detach - attach); Real averageRR = averageRecovery(d); Real maxAttLossFract = (1.-averageRR); if(portfFract > maxAttLossFract) return 0.; // for non-equity losses add the probability jump at zero tranche // losses (since this method returns prob of losing more or // equal to) if(portfFract <= QL_EPSILON) return 1.; Probability prob = averageProb(d); Real ip = InverseCumulativeNormal::standard_value(prob); Real invFlightK = (ip-sqrt1minuscorrel_* InverseCumulativeNormal::standard_value(portfFract /(1.-averageRR)))/beta_; return phi_(invFlightK);//probOver }