/** * The bucked CS01 (or credit DV01) by shifting each implied par-spread in turn. This takes an * extraneous yield curve and a credit curve and a set of bucket CDSs (CDSs with maturities equal * to the bucket points). Par-spreads at the bucket maturities are implied from the credit curve. * These spreads form pseudo market spreads to bootstraps a new credit (hazard) curve - the target * CDS is then priced with this credit curve. This is then repeated with each spreads bumped in * turn. The result is the vector of differences (bumped minus base price) divided by the bump * amount. * * @param cds analytic description of a CDS traded at a certain time * @param cdsCoupon The <b>fraction</b> spread of the CDS * @param bucketCDSs these are the reference instruments that correspond to maturity buckets * @param yieldCurve The yield (or discount) curve * @param creditCurve the credit curve * @param fracBumpAmount The fraction bump amount, so a 1pb bump is 1e-4 * @return The credit DV01 */ public double[] bucketedCS01FromCreditCurve( CdsAnalytic cds, double cdsCoupon, CdsAnalytic[] bucketCDSs, IsdaCompliantYieldCurve yieldCurve, IsdaCompliantCreditCurve creditCurve, double fracBumpAmount) { ArgChecker.notNull(cds, "cds"); ArgChecker.noNulls(bucketCDSs, "bucketCDSs"); ArgChecker.notNull(creditCurve, "creditCurve"); ArgChecker.notNull(yieldCurve, "yieldCurve"); ArgChecker.isTrue(Math.abs(fracBumpAmount) > 1e-10, "bump amount too small"); int n = bucketCDSs.length; double[] impSpreads = new double[n]; double[] t = new double[n]; for (int i = 0; i < n; i++) { impSpreads[i] = _pricer.parSpread(bucketCDSs[i], yieldCurve, creditCurve); t[i] = bucketCDSs[i].getProtectionEnd(); if (i > 0) { ArgChecker.isTrue(t[i] > t[i - 1], "buckets must be assending"); } } int index = Arrays.binarySearch(t, cds.getProtectionEnd()); if (index < 0) { index = -1 - index; } index = Math.min(index, n - 1); IsdaCompliantCreditCurve baseCurve = _curveBuilder.calibrateCreditCurve(bucketCDSs, impSpreads, yieldCurve); double basePrice = _pricer.pv(cds, yieldCurve, baseCurve, cdsCoupon); double[] res = new double[n]; for (int i = 0; i <= index; i++) { // don't bother calculating where there is no sensitivity double[] bumpedSpreads = makeBumpedSpreads(impSpreads, fracBumpAmount, ShiftType.ABSOLUTE, i); IsdaCompliantCreditCurve bumpedCurve = _curveBuilder.calibrateCreditCurve(bucketCDSs, bumpedSpreads, yieldCurve); double price = _pricer.pv(cds, yieldCurve, bumpedCurve, cdsCoupon); res[i] = (price - basePrice) / fracBumpAmount; } return res; }
public double parallelCS01FromCreditCurve( CdsAnalytic cds, double cdsCoupon, CdsAnalytic[] pillarCDSs, IsdaCompliantYieldCurve yieldCurve, IsdaCompliantCreditCurve creditCurve, double fracBumpAmount) { ArgChecker.notNull(cds, "cds"); ArgChecker.noNulls(pillarCDSs, "pillarCDSs"); ArgChecker.notNull(creditCurve, "creditCurve"); ArgChecker.notNull(yieldCurve, "yieldCurve"); ArgChecker.isTrue(Math.abs(fracBumpAmount) > 1e-10, "bump amount too small"); int n = pillarCDSs.length; double[] impSpreads = new double[n]; double[] t = new double[n]; for (int i = 0; i < n; i++) { impSpreads[i] = _pricer.parSpread(pillarCDSs[i], yieldCurve, creditCurve); t[i] = pillarCDSs[i].getProtectionEnd(); if (i > 0) { ArgChecker.isTrue(t[i] > t[i - 1], "pillars must be assending"); } } IsdaCompliantCreditCurve baseCurve = _curveBuilder.calibrateCreditCurve(pillarCDSs, impSpreads, yieldCurve); double basePrice = _pricer.pv(cds, yieldCurve, baseCurve, cdsCoupon); double[] bumpedSpreads = makeBumpedSpreads(impSpreads, fracBumpAmount, ShiftType.ABSOLUTE); IsdaCompliantCreditCurve bumpedCurve = _curveBuilder.calibrateCreditCurve(pillarCDSs, bumpedSpreads, yieldCurve); double price = _pricer.pv(cds, yieldCurve, bumpedCurve, cdsCoupon); double res = (price - basePrice) / fracBumpAmount; return res; }