*/
public void presentValueCurveSensitivityCurveUpCap() {
final YieldCurveBundle curvesUp = TestsDataSetsSABR.createCurves2();
final SABRInterestRateDataBundle sabrBundleCurveUp = new SABRInterestRateDataBundle(SABR_PARAMETERS, curvesUp);
final String[] curvesUpName = TestsDataSetsSABR.curves2Names();
final CapFloorCMSSpread cmsCapSpread = (CapFloorCMSSpread) CMS_CAP_SPREAD_DEFINITION.toDerivative(REFERENCE_DATE, new String[] {curvesUpName[0], curvesUpName[1] });
InterestRateCurveSensitivity pvcsCap = METHOD_CMS_SPREAD.presentValueCurveSensitivity(cmsCapSpread, sabrBundleCurveUp);
pvcsCap = pvcsCap.cleaned();
final double deltaToleranceRelative = 3.0E-4; // Numerical imprecision, reduce to E-6 when nbInteration = 1000;
final double deltaShift = 1.0E-6;
final String bumpedCurveName = "Bumped Curve";
// 1. Forward curve sensitivity
final String[] CurveNameBumpedForward = {curvesUpName[0], 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, sabrBundleCurveUp, curvesUpName[1], bumpedCurveName, nodeTimesForward, deltaShift,
METHOD_CMS_SPREAD);
final List<DoublesPair> sensiPvForward = pvcsCap.getSensitivities().get(curvesUpName[1]);
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, curvesUpName[1] };
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++) {