//------------------------------------------------------------------------- /** * The sensitivity of the PV of a CDS to the zero hazard rates at the knots of the credit curve. * * @param cds the CDS * @param coupon the coupon * @param creditCurve the credit Curve * @param yieldCurve the yield curve * @return vector of sensitivities */ public double[] getCurveSensitivities( CDS cds, double coupon, PiecewiseconstantHazardRate creditCurve, YieldTermStructure yieldCurve) { int n = creditCurve.getNumberOfKnots(); double[] CurveSen = new double[n]; for (int i = 0; i < n; i++) { CurveSen[i] = _pricer.pvCreditSensitivity(cds, yieldCurve, creditCurve, coupon, i); } return(CurveSen); }
/** * The sensitivity of a set of CDSs to the zero hazard rates at the knots of the credit curve. * The element (i,j) is the sensitivity of the PV of the jth CDS to the ith knot. * * @param cds the set of CDSs * @param coupons the coupons of the CDSs * @param creditCurve the credit Curve * @param yieldCurve the yield curve * @return matrix of sensitivities */ public double[,] getCurveSensitivities( CDS[] cds, double[] coupons, PiecewiseconstantHazardRate creditCurve, YieldTermStructure yieldCurve) { int nCDS = cds.Length; int nKnots = creditCurve.getNumberOfKnots(); double[,] sense = new double[nKnots, nCDS]; for (int i = 0; i < nCDS; i++) { for (int j = 0; j < nKnots; j++) { sense[j, i] = _pricer.pvCreditSensitivity(cds[i], yieldCurve, creditCurve, coupons[i], j); } } return(sense); }
/** * The sensitivity of the PV of the protection leg to the zero rate of a given node (knot) of the yield curve. * * @param cds the analytic description of a CDS traded at a certain time * @param yieldCurve the yield (or discount) curve * @param creditCurve the credit (or survival) curve * @param yieldCurveNode the yield curve node * @return the sensitivity (on a unit notional) */ public double protectionLegYieldSensitivity( CDS cds, YieldTermStructure yieldCurve, PiecewiseconstantHazardRate creditCurve, int yieldCurveNode) { if ((yieldCurveNode != 0 && cds.getProtectionEnd() <= yieldCurve.t[yieldCurveNode - 1]) || (yieldCurveNode != creditCurve.getNumberOfKnots() - 1 && cds.getEffectiveProtectionStart() >= yieldCurve.t[yieldCurveNode + 1])) { return(0.0); // can't have any sensitivity in this case } if (cds.getProtectionEnd() <= 0.0) { //short cut already expired CDSs return(0.0); } double[] integrationSchedule = DoublesScheduleGenerator.getIntegrationsPoints( cds.getEffectiveProtectionStart(), cds.getProtectionEnd(), yieldCurve, creditCurve); double t = integrationSchedule[0]; double ht0 = creditCurve.getRT_(t); double rt0 = yieldCurve.getRT_(t); double dpdr0 = yieldCurve.getSingleNodeDiscountFactorSensitivity(t, yieldCurveNode); double q0 = Math.Exp(-ht0); double p0 = Math.Exp(-rt0); double pvSense = 0.0; int n = integrationSchedule.Length; for (int i = 1; i < n; ++i) { t = integrationSchedule[i]; double ht1 = creditCurve.getRT_(t); double dpdr1 = yieldCurve.getSingleNodeDiscountFactorSensitivity(t, yieldCurveNode); double rt1 = yieldCurve.getRT_(t); double q1 = Math.Exp(-ht1); double p1 = Math.Exp(-rt1); if (dpdr0 == 0.0 && dpdr1 == 0.0) { ht0 = ht1; rt0 = rt1; p0 = p1; q0 = q1; continue; } double hBar = ht1 - ht0; double fBar = rt1 - rt0; double fhBar = hBar + fBar; double dPVSense; double e = Maths.Epsilon.epsilon(-fhBar); double eP = Maths.Epsilon.epsilonP(-fhBar); double dPVdp0 = q0 * hBar * (e - eP); double dPVdp1 = hBar * p0 * q0 / p1 * eP; dPVSense = dPVdp0 * dpdr0 + dPVdp1 * dpdr1; pvSense += dPVSense; ht0 = ht1; dpdr0 = dpdr1; rt0 = rt1; p0 = p1; q0 = q1; } pvSense *= cds.getLGD(); // Compute the discount factor discounting the upfront payment made on the cash settlement date back to the valuation date double df = Math.Exp(-yieldCurve.getRT_(cds.getCashSettleTime())); pvSense /= df; //TODO this was put in quickly the get the right sensitivity to the first node double dfSense = yieldCurve.getSingleNodeDiscountFactorSensitivity(cds.getCashSettleTime(), yieldCurveNode); if (dfSense != 0.0) { double pro = protectionLeg(cds, yieldCurve, creditCurve); pvSense -= pro / df * dfSense; } return(pvSense); }