//Testing note: Sensitivity is for a movement of 1. 1E+2 = 1 cent for a 1 bp move.
final double deltaShift = 1.0E-6;
final String bumpedCurveName = "Bumped Curve";
// 1. Forward curve sensitivity
final String[] CurveNameBumpedForward = {FUNDING_CURVE_NAME, bumpedCurveName };
final CapFloorCMS capBumpedForward = (CapFloorCMS) CMS_FLOOR_DEFINITION.toDerivative(REFERENCE_DATE, CurveNameBumpedForward);
final DoubleAVLTreeSet forwardTime = new DoubleAVLTreeSet();
for (int loopcpn = 0; loopcpn < CMS_FLOOR.getUnderlyingSwap().getSecondLeg().getNumberOfPayments(); loopcpn++) {
final CouponIbor cpn = (CouponIbor) CMS_FLOOR.getUnderlyingSwap().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);
assertEquals("Sensitivity finite difference method: number of node", nodeTimesForward.length, sensiForwardMethod.length);
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, pairPv.second, sensiForwardMethod[loopnode], deltaTolerancePrice);
}
// 2. Discounting curve sensitivity
final String[] CurveNameBumpedDisc = {bumpedCurveName, FORWARD_CURVE_NAME };
final CapFloorCMS capBumpedDisc = (CapFloorCMS) CMS_FLOOR_DEFINITION.toDerivative(REFERENCE_DATE, CurveNameBumpedDisc);
final DoubleAVLTreeSet discTime = new DoubleAVLTreeSet();
discTime.add(capBumpedDisc.getPaymentTime());
for (int loopcpn = 0; loopcpn < CMS_FLOOR.getUnderlyingSwap().getSecondLeg().getNumberOfPayments(); loopcpn++) {
final CouponIbor cpn = (CouponIbor) CMS_FLOOR.getUnderlyingSwap().getSecondLeg().getNthPayment(loopcpn);
discTime.add(cpn.getPaymentTime());
}
final double[] nodeTimesDisc = discTime.toDoubleArray();