// 1. Forward curve sensitivity
final String[] CurveNameBumpedForward = {FUNDING_CURVE_NAME, bumpedCurveName };
final CapFloorCMSSpread capBumpedForward = (CapFloorCMSSpread) CMS_CAP_SPREAD_DEFINITION.toDerivative(REFERENCE_DATE, CurveNameBumpedForward);
final DoubleAVLTreeSet forwardTime = new DoubleAVLTreeSet();
for (int loopcpn = 0; loopcpn < CMS_CAP_SPREAD.getUnderlyingSwap1().getSecondLeg().getNumberOfPayments(); loopcpn++) {
final CouponIbor cpn = (CouponIbor) CMS_CAP_SPREAD.getUnderlyingSwap1().getSecondLeg().getNthPayment(loopcpn);
forwardTime.add(cpn.getFixingPeriodStartTime());
forwardTime.add(cpn.getFixingPeriodEndTime());
}
for (int loopcpn = 0; loopcpn < CMS_CAP_SPREAD.getUnderlyingSwap2().getSecondLeg().getNumberOfPayments(); loopcpn++) {
final CouponIbor cpn = (CouponIbor) CMS_CAP_SPREAD.getUnderlyingSwap2().getSecondLeg().getNthPayment(loopcpn);
forwardTime.add(cpn.getFixingPeriodStartTime());
forwardTime.add(cpn.getFixingPeriodEndTime());
}
final double[] nodeTimesForward = forwardTime.toDoubleArray();
final double[] sensiForwardMethod = SensitivityFiniteDifference.curveSensitivity(capBumpedForward, SABR_BUNDLE, FORWARD_CURVE_NAME, bumpedCurveName, nodeTimesForward, deltaShift,
METHOD_CMS_SPREAD_EXTRAPOLATION);
final List<DoublesPair> sensiPvForward = pvcsCap.getSensitivities().get(FORWARD_CURVE_NAME);
for (int loopnode = 0; loopnode < sensiForwardMethod.length; loopnode++) {
final DoublesPair pairPv = sensiPvForward.get(loopnode);
assertEquals("Sensitivity CMS cap/floor pv to forward curve: Node " + loopnode, nodeTimesForward[loopnode], pairPv.getFirst(), 1E-8);
assertEquals("Sensitivity finite difference method: node sensitivity " + loopnode + " - Difference " + (sensiForwardMethod[loopnode] - pairPv.second), 0,
(sensiForwardMethod[loopnode] - pairPv.second) / pairPv.second, deltaToleranceRelative);
}
// 2. Discounting curve sensitivity
final String[] CurveNameBumpedDisc = {bumpedCurveName, FORWARD_CURVE_NAME };
final CapFloorCMSSpread capBumpedDisc = (CapFloorCMSSpread) CMS_CAP_SPREAD_DEFINITION.toDerivative(REFERENCE_DATE, CurveNameBumpedDisc);
final DoubleAVLTreeSet discTime = new DoubleAVLTreeSet();
discTime.add(capBumpedDisc.getPaymentTime());
for (int loopcpn = 0; loopcpn < CMS_CAP_SPREAD.getUnderlyingSwap1().getSecondLeg().getNumberOfPayments(); loopcpn++) {
final CouponIbor cpn = (CouponIbor) CMS_CAP_SPREAD.getUnderlyingSwap1().getSecondLeg().getNthPayment(loopcpn);
discTime.add(cpn.getPaymentTime());
}
for (int loopcpn = 0; loopcpn < CMS_CAP_SPREAD.getUnderlyingSwap2().getSecondLeg().getNumberOfPayments(); loopcpn++) {
final CouponIbor cpn = (CouponIbor) CMS_CAP_SPREAD.getUnderlyingSwap2().getSecondLeg().getNthPayment(loopcpn);
discTime.add(cpn.getPaymentTime());
}
final double[] nodeTimesDisc = discTime.toDoubleArray();
final double[] sensiDiscMethod = SensitivityFiniteDifference
.curveSensitivity(capBumpedDisc, SABR_BUNDLE, FUNDING_CURVE_NAME, bumpedCurveName, nodeTimesDisc, deltaShift, METHOD_CMS_SPREAD_EXTRAPOLATION);
final List<DoublesPair> sensiPvDisc = pvcsCap.getSensitivities().get(FUNDING_CURVE_NAME);