/** * 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)); }
public static PiecewiseconstantHazardRate[] buildCreditCurves(DateTime tradeDate, double[,] parSpreads, double[] recoveryRates, int[] tenors, YieldTermStructure yieldCurve) { CdsAnalyticFactory factory = new CdsAnalyticFactory(0.0); CDS[] pillarCDS = factory.makeImmCds(tradeDate, CDX_HY_TENORS); int indexSize = parSpreads.GetLength(0); PiecewiseconstantHazardRate[] creditCurves = new PiecewiseconstantHazardRate[indexSize]; //this section of code is hugely wasteful. If we do this for real (i.e. not just in a test), must improve for (int i = 0; i < indexSize; i++) { int m = parSpreads.GetLength(1); double[] spreads = new double[m]; for (int j = 0; j < m; j++) { spreads[j] = parSpreads[i, j]; } int nPillars = spreads.Length; CDS[] tempCDS = new CDS[nPillars]; double[] tempSpreads = new double[nPillars]; int count = 0; for (int j = 0; j < nPillars; j++) { if (!double.IsNaN(parSpreads[i, j])) { tempCDS[count] = pillarCDS[j].withRecoveryRate(recoveryRates[i]); tempSpreads[count] = spreads[j]; count++; } } CDS[] calCDS = null; double[] calSpreads = null; if (count == nPillars) { calCDS = tempCDS; calSpreads = tempSpreads; } else { calCDS = new CDS[count]; calSpreads = new double[count]; Array.Copy(tempCDS, 0, calCDS, 0, count); Array.Copy(tempSpreads, 0, calSpreads, 0, count); } CreditCurveCalibrator calibrator = new CreditCurveCalibrator(calCDS, yieldCurve); creditCurves[i] = calibrator.calibrate(calSpreads); } return(creditCurves); }