assertEquals("FRA discounting: present value - buy/sell parity", pvSell.getAmount(), -pvBuy.getAmount(), 1.0E-2);
}
@Test
public void sensitivity() {
final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1();
// Par rate sensitivity
InterestRateCurveSensitivity prsFra = FRA_METHOD.parRateCurveSensitivity(FRA, curves);
final InterestRateCurveSensitivity pvsFra = FRA_METHOD.presentValueCurveSensitivity(FRA, curves);
prsFra = prsFra.cleaned();
final double deltaTolerancePrice = 1.0E+2;
final double deltaToleranceRate = 1.0E-7;
//Testing note: Sensitivity is for a movement of 1. 1E+2 = 1 cent for a 1 bp move. Tolerance increased to cope with numerical imprecision of finite difference.
final double deltaShift = 1.0E-8;
final double forward = FRA_METHOD.parRate(FRA, curves);
final double pv = FRA_METHOD.presentValue(FRA, curves).getAmount();
// 1. Forward curve sensitivity
final String bumpedCurveName = "Bumped Curve";
final String[] bumpedCurvesForwardName = {CURVE_NAME_1[0], bumpedCurveName };
final ForwardRateAgreement fraBumpedForward = (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName);
final YieldAndDiscountCurve curveForward = curves.getCurve(CURVE_NAME_1[1]);
final double[] timeForward = new double[2];
timeForward[0] = FRA.getFixingPeriodStartTime();
timeForward[1] = FRA.getFixingPeriodEndTime();
final int nbForwardDate = timeForward.length;
final double[] yieldsForward = new double[nbForwardDate + 1];
final double[] nodeTimesForward = new double[nbForwardDate + 1];
yieldsForward[0] = curveForward.getInterestRate(0.0);
for (int i = 0; i < nbForwardDate; i++) {
nodeTimesForward[i + 1] = timeForward[i];
yieldsForward[i + 1] = curveForward.getInterestRate(nodeTimesForward[i + 1]);
}
final YieldAndDiscountCurve tempCurveForward = YieldCurve.from(InterpolatedDoublesCurve.fromSorted(nodeTimesForward, yieldsForward, new LinearInterpolator1D()));
final List<DoublesPair> sensiForwardForward = prsFra.getSensitivities().get(CURVE_NAME_1[1]);
final List<DoublesPair> sensiPvForward = pvsFra.getSensitivities().get(CURVE_NAME_1[1]);
final double[] sensiForwardForwardFD = new double[nbForwardDate];
final double[] sensiPvForwardFD = new double[nbForwardDate];
for (int i = 0; i < nbForwardDate; i++) {
final YieldAndDiscountCurve bumpedCurveForward = tempCurveForward.withSingleShift(nodeTimesForward[i + 1], deltaShift);
final YieldCurveBundle curvesBumpedForward = new YieldCurveBundle();
curvesBumpedForward.addAll(curves);
curvesBumpedForward.setCurve("Bumped Curve", bumpedCurveForward);
final double bumpedForward = FRA_METHOD.parRate(fraBumpedForward, curvesBumpedForward);
final double bumpedPv = FRA_METHOD.presentValue(fraBumpedForward, curvesBumpedForward).getAmount();
sensiForwardForwardFD[i] = (bumpedForward - forward) / deltaShift;
sensiPvForwardFD[i] = (bumpedPv - pv) / deltaShift;
final DoublesPair pairForward = sensiForwardForward.get(i);
final DoublesPair pairPv = sensiPvForward.get(i);
assertEquals("Sensitivity forward to forward curve: Node " + i, nodeTimesForward[i + 1], pairForward.getFirst(), 1E-8);
assertEquals("Sensitivity forward to forward curve: Node " + i, sensiForwardForwardFD[i], pairForward.getSecond(), deltaToleranceRate);
assertEquals("Sensitivity pv to forward curve: Node " + i, nodeTimesForward[i + 1], pairPv.getFirst(), 1E-8);
assertEquals("Sensitivity pv to forward curve: Node " + i, sensiPvForwardFD[i], pairPv.getSecond(), deltaTolerancePrice);
}
// 2. Funding curve sensitivity
final String[] bumpedCurvesFundingName = {bumpedCurveName, CURVE_NAME_1[1] };
final ForwardRateAgreement fraBumped = (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesFundingName);
final YieldAndDiscountCurve curveFunding = curves.getCurve(CURVE_NAME_1[0]);
final double[] yieldsFunding = new double[2];
final double[] nodeTimesFunding = new double[2];
yieldsFunding[0] = curveFunding.getInterestRate(0.0);
nodeTimesFunding[1] = FRA.getPaymentTime();
yieldsFunding[1] = curveFunding.getInterestRate(nodeTimesFunding[1]);
final YieldAndDiscountCurve tempCurveFunding = YieldCurve.from(InterpolatedDoublesCurve.fromSorted(nodeTimesFunding, yieldsFunding, new LinearInterpolator1D()));
final List<DoublesPair> tempFunding = pvsFra.getSensitivities().get(CURVE_NAME_1[0]);
final YieldAndDiscountCurve bumpedCurve = tempCurveFunding.withSingleShift(nodeTimesFunding[1], deltaShift);
final YieldCurveBundle curvesBumped = new YieldCurveBundle();
curvesBumped.addAll(curves);
curvesBumped.setCurve("Bumped Curve", bumpedCurve);
final double bumpedPvDsc = FRA_METHOD.presentValue(fraBumped, curvesBumped).getAmount();
final double resDsc = (bumpedPvDsc - pv) / deltaShift;
final DoublesPair pair = tempFunding.get(0);
assertEquals("Sensitivity pv to discounting curve:", nodeTimesFunding[1], pair.getFirst(), 1E-8);
assertEquals("Sensitivity pv to discounting curve:", resDsc, pair.getSecond(), deltaTolerancePrice);