/** * The average spread of a CDS portfolio (index), defined as the weighted average of the * (implied) par spreads of the constituent names. * * @see #intrinsicIndexSpread * @param indexCDS representation of the index cashflows (seen from today). * @param yieldCurve The current yield curves * @param intrinsicData credit curves, weights and recovery rates of the intrinsic names * @return The average spread */ public double averageSpread( CDS indexCDS, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData) { if (intrinsicData.getNumOfDefaults() == intrinsicData.getIndexSize()) { } CDS cds = indexCDS.withRecoveryRate(0.0); int n = intrinsicData.getIndexSize(); double sum = 0; for (int i = 0; i < n; i++) { if (!intrinsicData.isDefaulted(i)) { double protLeg = intrinsicData.getLGD(i) * _pricer.protectionLeg(cds, yieldCurve, intrinsicData.getCreditCurve(i)); double annuity = _pricer.annuity(cds, yieldCurve, intrinsicData.getCreditCurve(i)); double s = protLeg / annuity; sum += intrinsicData.getWeight(i) * s; } } sum /= intrinsicData.getIndexFactor(); return(sum); }
/** * Imply a single (pseudo) credit curve for an index that will give the same index values * at a set of terms (supplied via pillarCDS) as the intrinsic value. * * @param pillarCDS Point to build the curve * @param indexCoupon The index coupon * @param yieldCurve The current yield curves * @param intrinsicData credit curves, weights and recovery rates of the intrinsic names * @return A (pseudo) credit curve for an index */ public PiecewiseconstantHazardRate impliedIndexCurve( CDS[] pillarCDS, double indexCoupon, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData) { if (intrinsicData.getNumOfDefaults() == intrinsicData.getIndexSize()) { } int n = pillarCDS.Length; double[] puf = new double[n]; double indexFactor = intrinsicData.getIndexFactor(); for (int i = 0; i < n; i++) { // PUF are always given for full index puf[i] = indexPV(pillarCDS[i], indexCoupon, yieldCurve, intrinsicData) / indexFactor; } CreditCurveCalibrator calibrator = new CreditCurveCalibrator(pillarCDS, yieldCurve); double[] coupons = new double[n]; Array.ConvertAll <double, double>(coupons, b => b = indexCoupon); return(calibrator.calibrate(coupons, puf)); }
/** * The Points-Up-Front (PUF) of an index. This is the (clean) price of a unit notional index. * The actual clean price is this multiplied by the (current) index notional * (i.e. the initial notional times the index factor). * * @param indexCDS analytic description of a CDS traded at a certain time * @param indexCoupon The coupon of the index (as a fraction) * @param yieldCurve The yield curve * @param intrinsicData credit curves, weights and recover * @return PUF of an index */ public double indexPUF( CDS indexCDS, double indexCoupon, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData) { if (intrinsicData.getNumOfDefaults() == intrinsicData.getIndexSize()) { } return(indexPV(indexCDS, indexCoupon, yieldCurve, intrinsicData) / intrinsicData.getIndexFactor()); }
/** * The intrinsic index spread. this is defined as the ratio of the intrinsic protection leg to the intrinsic annuity. * * @see #averageSpread * @param indexCDS analytic description of a CDS traded at a certain time * @param yieldCurve The yield curve * @param intrinsicData credit curves, weights and recovery rates of the intrinsic names * @return intrinsic index spread (as a fraction) */ public double intrinsicIndexSpread( CDS indexCDS, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData) { if (intrinsicData.getNumOfDefaults() == intrinsicData.getIndexSize()) { } double prot = indexProtLeg(indexCDS, yieldCurve, intrinsicData); double annuity = indexAnnuity(indexCDS, yieldCurve, intrinsicData); return(prot / annuity); }
/** * The normalised expected default settlement value paid on the exercise settlement date. * The actual default settlement is this multiplied by the (initial) index notional. * * @param timeToExpiry Time to expiry * @param intrinsicData credit curves, weights and recovery rates of the intrinsic names * @return The normalised expected default settlement value */ public double expectedDefaultSettlementValue( double timeToExpiry, IntrinsicIndexDataBundle intrinsicData) { int indexSize = intrinsicData.getIndexSize(); double d = 0.0; //computed the expected default settlement amount (paid on the expiry settlement date) for (int i = 0; i < indexSize; i++) { double qBar = intrinsicData.isDefaulted(i) ? 1.0 : 1.0 - Math.Exp(-intrinsicData.getCreditCurve(i).getRT_( timeToExpiry)); d += intrinsicData.getWeight(i) * intrinsicData.getLGD(i) * qBar; } return(d); }
/** * The intrinsic annuity of a CDS portfolio (index) for a unit (initial) notional. * The value of the premium leg is this multiplied by the <b> initial</b> notional of the index * and the index coupon (as a fraction). * * @param indexCDS representation of the index cashflows (seen from today). * @param yieldCurve The current yield curves * @param intrinsicData credit curves, weights and recovery rates of the intrinsic names * @param priceType Clean or dirty * @param valuationTime Valuation time. The leg value is calculated for today (t=0), * then rolled forward (using the risk free yield curve) to the valuation time. * This is because cash payments occur on the cash-settlement-date, which is usually * three working days after the trade date (today) * @return The intrinsic annuity of a CDS portfolio (index) */ public double indexAnnuity( CDS indexCDS, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData, CdsPriceType priceType, double valuationTime) { int n = intrinsicData.getIndexSize(); double a = 0; for (int i = 0; i < n; i++) { if (!intrinsicData.isDefaulted(i)) { a += intrinsicData.getWeight(i) * _pricer.annuity(indexCDS, yieldCurve, intrinsicData.getCreditCurve(i), priceType, 0); } } a /= Math.Exp(-yieldCurve.getRT_(valuationTime)); return(a); }
/** * The normalised intrinsic value of the protection leg of a CDS portfolio (index). * The actual value of the leg is this multiplied by the <b>initial</b> notional of the index. * * @param indexCDS representation of the index cashflows (seen from today). * @param yieldCurve The current yield curves * @param intrinsicData credit curves, weights and recovery rates of the intrinsic names * @param valuationTime Valuation time. The leg value is calculated for today (t=0), * then rolled forward (using the risk free yield curve) to the valuation time. * This is because cash payments occur on the cash-settlement-date, which is usually * three working days after the trade date (today) * @return The normalised intrinsic value of the protection leg. */ public double indexProtLeg( CDS indexCDS, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData, double valuationTime) { CDS cds = indexCDS.withRecoveryRate(0.0); int n = intrinsicData.getIndexSize(); double protLeg = 0; for (int i = 0; i < n; i++) { if (!intrinsicData.isDefaulted(i)) { protLeg += intrinsicData.getWeight(i) * intrinsicData.getLGD(i) * _pricer.protectionLeg(cds, yieldCurve, intrinsicData.getCreditCurve(i), 0); } } protLeg /= Math.Exp(-yieldCurve.getRT_(valuationTime)); return(protLeg); }
/** * Values on per-name default * @param indexCDS The CDS index * @param indexCoupon The index coupon * @param yieldCurve The yield curve * @param intrinsicData Credit curves, weights and recovery rates of the intrinsic names * @return The jump to default */ public double[] jumpToDefault( CDS indexCDS, double indexCoupon, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData) { int indexSize = intrinsicData.getIndexSize(); double[] res = new double[indexSize]; for (int i = 0; i < indexSize; ++i) { if (intrinsicData.isDefaulted(i)) { res[i] = 0.0; } else { res[i] = decomposedValueOnDefault(indexCDS, indexCoupon, yieldCurve, intrinsicData, i); } } return(res); }
/** * Sensitivity of the intrinsic value of a CDS index to intrinsic CDS recovery rates. * * @param indexCDS The CDS index * @param indexCoupon The index coupon * @param yieldCurve The yield curve * @param intrinsicData Credit curves, weights and recovery rates of the intrinsic names * @return The sensitivity */ public double[] recovery01( CDS indexCDS, double indexCoupon, YieldTermStructure yieldCurve, IntrinsicIndexDataBundle intrinsicData) { CDS zeroRR = indexCDS.withRecoveryRate(0.0); int indexSize = intrinsicData.getIndexSize(); double[] res = new double[indexSize]; for (int i = 0; i < indexSize; ++i) { if (intrinsicData.isDefaulted(i)) { res[i] = 0.0; } else { res[i] = -_pricer.protectionLeg(zeroRR, yieldCurve, intrinsicData.getCreditCurve(i)) * intrinsicData.getWeight(i); } } return(res); }