@Override
 public Map<String, List<DoublesPair>> visitForwardRateAgreement(
     final ForwardRateAgreement fra, final YieldCurveBundle curves) {
   final ForwardRateAgreementDiscountingMethod method =
       ForwardRateAgreementDiscountingMethod.getInstance();
   return method.presentValueCurveSensitivity(fra, curves).getSensitivities();
 }
 /**
  * For ForwardRateAgreement the ParSpread is the spread to be added to the fixed rate to obtain a
  * present value of zero.
  *
  * @param fra The forward rate agreement.
  * @param curves The yield curve bundle.
  * @return The par spread.
  */
 @Override
 public Double visitForwardRateAgreement(
     final ForwardRateAgreement fra, final YieldCurveBundle curves) {
   Validate.notNull(curves);
   Validate.notNull(fra);
   return METHOD_FRA.parSpread(fra, curves);
 }
/**
 * Compute the spread to be added to the rate of the instrument for which the present value of the
 * instrument is zero. The "rate" can be a "rate" or a "yield" and will depend of each instrument.
 *
 * @deprecated {@link YieldCurveBundle} is deprecated
 */
@Deprecated
public final class ParSpreadRateCalculator
    extends InstrumentDerivativeVisitorAdapter<YieldCurveBundle, Double> {

  /** The unique instance of the calculator. */
  private static final ParSpreadRateCalculator INSTANCE = new ParSpreadRateCalculator();

  /**
   * Gets the calculator instance.
   *
   * @return The calculator.
   */
  public static ParSpreadRateCalculator getInstance() {
    return INSTANCE;
  }

  /** Constructor. */
  private ParSpreadRateCalculator() {}

  /** The methods and calculators. */
  private static final PresentValueMCACalculator PVMCC = PresentValueMCACalculator.getInstance();

  private static final PresentValueBasisPointCalculator PVBPC =
      PresentValueBasisPointCalculator.getInstance();
  private static final CashDiscountingMethod METHOD_DEPOSIT = CashDiscountingMethod.getInstance();
  private static final DepositZeroDiscountingMethod METHOD_DEPOSIT_ZERO =
      DepositZeroDiscountingMethod.getInstance();
  private static final ForwardRateAgreementDiscountingMethod METHOD_FRA =
      ForwardRateAgreementDiscountingMethod.getInstance();
  //  private static final InterestRateFutureTransactionDiscountingMethod
  // METHOD_IR_FUTURES_TRANSACTION = InterestRateFutureTransactionDiscountingMethod.getInstance();
  private static final InterestRateFutureSecurityDiscountingMethod METHOD_IR_FUTURES_SECURITY =
      InterestRateFutureSecurityDiscountingMethod.getInstance();

  @Override
  public Double visitCash(final Cash deposit, final YieldCurveBundle curves) {
    return METHOD_DEPOSIT.parSpread(deposit, curves);
  }

  @Override
  public Double visitDepositZero(final DepositZero deposit, final YieldCurveBundle curves) {
    return METHOD_DEPOSIT_ZERO.parSpread(deposit, curves);
  }

  /**
   * For swaps the ParSpread is the spread to be added on each coupon of the first leg to obtain a
   * present value of zero. It is computed as the opposite of the present value of the swap divided
   * by the present value of a basis point of the first leg (as computed by the
   * PresentValueBasisPointCalculator).
   *
   * @param swap The swap.
   * @param curves The yield curve bundle.
   * @return The par spread.
   */
  @Override
  public Double visitSwap(final Swap<?, ?> swap, final YieldCurveBundle curves) {
    Validate.notNull(curves);
    Validate.notNull(swap);
    return -curves
            .getFxRates()
            .convert(swap.accept(PVMCC, curves), swap.getFirstLeg().getCurrency())
            .getAmount()
        / swap.getFirstLeg().accept(PVBPC, curves);
  }

  @Override
  public Double visitFixedCouponSwap(final SwapFixedCoupon<?> swap, final YieldCurveBundle curves) {
    return visitSwap(swap, curves);
  }

  /**
   * For ForwardRateAgreement the ParSpread is the spread to be added to the fixed rate to obtain a
   * present value of zero.
   *
   * @param fra The forward rate agreement.
   * @param curves The yield curve bundle.
   * @return The par spread.
   */
  @Override
  public Double visitForwardRateAgreement(
      final ForwardRateAgreement fra, final YieldCurveBundle curves) {
    Validate.notNull(curves);
    Validate.notNull(fra);
    return METHOD_FRA.parSpread(fra, curves);
  }

  /**
   * For InterestRateFutures the ParSpread is the spread to be added to the reference price to
   * obtain a present value of zero.
   *
   * @param future The futures.
   * @param curves The yield curve bundle.
   * @return The par spread.
   */
  @Override
  public Double visitInterestRateFutureTransaction(
      final InterestRateFutureTransaction future, final YieldCurveBundle curves) {
    return -(METHOD_IR_FUTURES_SECURITY.price(future.getUnderlying(), curves)
        - future.getReferencePrice());
  }

  //  /**
  //   * For InterestRateFutures the ParSpread is the spread to be added to the reference price to
  // obtain a present value of zero.
  //   * @param future The futures.
  //   * @param curves The yield curve bundle.
  //   * @return The par spread.
  //   */
  //  @Override
  //  public Double visitInterestRateFutureSecurity(final InterestRateFutureSecurity future, final
  // YieldCurveBundle curves) {
  //    return -(METHOD_IR_FUTURES_SECURITY.presentValue(future, curves).getAmount());
  //  }
}
  @Test
  public void curveSensitivityFRA() {
    final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1();
    final double deltaShift = 1.0E-8;
    final double pv = FRA_METHOD.presentValue(FRA, curves).getAmount();
    // 1. Forward curve sensitivity
    final String bumpedCurveName = "Bumped Curve";
    final String[] bumpedCurvesForwardName = {FUNDING_CURVE_NAME, bumpedCurveName};
    final ForwardRateAgreement fraBumpedForward =
        (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName);
    final YieldAndDiscountCurve curveForward = curves.getCurve(FORWARD_CURVE_NAME);
    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 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 bumpedPv =
          FRA_METHOD.presentValue(fraBumpedForward, curvesBumpedForward).getAmount();
      sensiPvForwardFD[i] = (bumpedPv - pv) / deltaShift;
    }

    final double[] nodeTimesForwardMethod =
        new double[] {FRA.getFixingPeriodStartTime(), FRA.getFixingPeriodEndTime()};
    final double[] sensiForwardMethod =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumpedForward,
            curves,
            pv,
            FORWARD_CURVE_NAME,
            bumpedCurveName,
            nodeTimesForwardMethod,
            deltaShift,
            FRA_METHOD);
    assertEquals(
        "Sensitivity finite difference method: number of node", 2, sensiForwardMethod.length);
    for (int loopnode = 0; loopnode < sensiForwardMethod.length; loopnode++) {
      assertEquals(
          "Sensitivity finite difference method: node sensitivity",
          sensiPvForwardFD[loopnode],
          sensiForwardMethod[loopnode]);
    }

    // 2. Funding curve sensitivity
    final String[] bumpedCurvesFundingName = {bumpedCurveName, FORWARD_CURVE_NAME};
    final ForwardRateAgreement fraBumped =
        (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesFundingName);
    final YieldAndDiscountCurve curveFunding = curves.getCurve(FUNDING_CURVE_NAME);
    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 YieldAndDiscountCurve bumpedCurve =
        tempCurveFunding.withSingleShift(nodeTimesFunding[1], deltaShift);
    final YieldCurveBundle curvesBumped = new YieldCurveBundle();
    curvesBumped.addAll(curves);
    curvesBumped.replaceCurve("Bumped Curve", bumpedCurve);
    final double bumpedPvDsc = FRA_METHOD.presentValue(fraBumped, curvesBumped).getAmount();
    final double[] resDsc = new double[1];
    resDsc[0] = (bumpedPvDsc - pv) / deltaShift;

    final double[] nodeTimesFundingMethod = new double[] {FRA.getPaymentTime()};
    final double[] sensiFundingMethod =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumped,
            curves,
            pv,
            FUNDING_CURVE_NAME,
            bumpedCurveName,
            nodeTimesFundingMethod,
            deltaShift,
            FRA_METHOD);
    assertEquals(
        "Sensitivity finite difference method: number of node", 1, sensiFundingMethod.length);
    for (int loopnode = 0; loopnode < sensiFundingMethod.length; loopnode++) {
      assertEquals(
          "Sensitivity finite difference method: node sensitivity",
          resDsc[loopnode],
          sensiFundingMethod[loopnode]);
    }
  }
/** Tests finite difference computation of curve sensitivity. */
public class SensitivityFiniteDifferenceTest {
  // Index
  private static final Period TENOR = Period.ofMonths(3);
  private static final int SETTLEMENT_DAYS = 2;
  private static final Calendar CALENDAR = new MondayToFridayCalendar("A");
  private static final DayCount DAY_COUNT_INDEX =
      DayCountFactory.INSTANCE.getDayCount("Actual/360");
  private static final BusinessDayConvention BUSINESS_DAY =
      BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following");
  private static final boolean IS_EOM = true;
  private static final Currency CUR = Currency.USD;
  private static final IborIndex INDEX =
      new IborIndex(CUR, TENOR, SETTLEMENT_DAYS, CALENDAR, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM);
  // Dates : The above dates are not standard but selected for insure correct testing.
  private static final ZonedDateTime FIXING_DATE = DateUtils.getUTCDate(2011, 1, 3);
  private static final ZonedDateTime ACCRUAL_START_DATE = DateUtils.getUTCDate(2011, 1, 6);
  private static final ZonedDateTime ACCRUAL_END_DATE = DateUtils.getUTCDate(2011, 4, 4);
  private static final ZonedDateTime PAYMENT_DATE = DateUtils.getUTCDate(2011, 1, 7);
  private static final DayCount DAY_COUNT_PAYMENT =
      DayCountFactory.INSTANCE.getDayCount("Actual/365");
  private static final double ACCRUAL_FACTOR_PAYMENT =
      DAY_COUNT_PAYMENT.getDayCountFraction(ACCRUAL_START_DATE, ACCRUAL_END_DATE);
  private static final double FRA_RATE = 0.05;
  private static final double NOTIONAL = 1000000; // 1m
  // Coupon with specific payment and accrual dates.
  private static final ForwardRateAgreementDefinition FRA_DEFINITION =
      new ForwardRateAgreementDefinition(
          CUR,
          PAYMENT_DATE,
          ACCRUAL_START_DATE,
          ACCRUAL_END_DATE,
          ACCRUAL_FACTOR_PAYMENT,
          NOTIONAL,
          FIXING_DATE,
          INDEX,
          FRA_RATE);
  // To derivatives
  private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2009, 8, 18);
  private static final String FUNDING_CURVE_NAME = "Funding";
  private static final String FORWARD_CURVE_NAME = "Forward";
  private static final String[] CURVES = {FUNDING_CURVE_NAME, FORWARD_CURVE_NAME};
  private static final ForwardRateAgreement FRA =
      (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, CURVES);
  private static final ForwardRateAgreementDiscountingMethod FRA_METHOD =
      ForwardRateAgreementDiscountingMethod.getInstance();

  @Test
  public void curveSensitivityFRA() {
    final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1();
    final double deltaShift = 1.0E-8;
    final double pv = FRA_METHOD.presentValue(FRA, curves).getAmount();
    // 1. Forward curve sensitivity
    final String bumpedCurveName = "Bumped Curve";
    final String[] bumpedCurvesForwardName = {FUNDING_CURVE_NAME, bumpedCurveName};
    final ForwardRateAgreement fraBumpedForward =
        (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName);
    final YieldAndDiscountCurve curveForward = curves.getCurve(FORWARD_CURVE_NAME);
    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 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 bumpedPv =
          FRA_METHOD.presentValue(fraBumpedForward, curvesBumpedForward).getAmount();
      sensiPvForwardFD[i] = (bumpedPv - pv) / deltaShift;
    }

    final double[] nodeTimesForwardMethod =
        new double[] {FRA.getFixingPeriodStartTime(), FRA.getFixingPeriodEndTime()};
    final double[] sensiForwardMethod =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumpedForward,
            curves,
            pv,
            FORWARD_CURVE_NAME,
            bumpedCurveName,
            nodeTimesForwardMethod,
            deltaShift,
            FRA_METHOD);
    assertEquals(
        "Sensitivity finite difference method: number of node", 2, sensiForwardMethod.length);
    for (int loopnode = 0; loopnode < sensiForwardMethod.length; loopnode++) {
      assertEquals(
          "Sensitivity finite difference method: node sensitivity",
          sensiPvForwardFD[loopnode],
          sensiForwardMethod[loopnode]);
    }

    // 2. Funding curve sensitivity
    final String[] bumpedCurvesFundingName = {bumpedCurveName, FORWARD_CURVE_NAME};
    final ForwardRateAgreement fraBumped =
        (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesFundingName);
    final YieldAndDiscountCurve curveFunding = curves.getCurve(FUNDING_CURVE_NAME);
    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 YieldAndDiscountCurve bumpedCurve =
        tempCurveFunding.withSingleShift(nodeTimesFunding[1], deltaShift);
    final YieldCurveBundle curvesBumped = new YieldCurveBundle();
    curvesBumped.addAll(curves);
    curvesBumped.replaceCurve("Bumped Curve", bumpedCurve);
    final double bumpedPvDsc = FRA_METHOD.presentValue(fraBumped, curvesBumped).getAmount();
    final double[] resDsc = new double[1];
    resDsc[0] = (bumpedPvDsc - pv) / deltaShift;

    final double[] nodeTimesFundingMethod = new double[] {FRA.getPaymentTime()};
    final double[] sensiFundingMethod =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumped,
            curves,
            pv,
            FUNDING_CURVE_NAME,
            bumpedCurveName,
            nodeTimesFundingMethod,
            deltaShift,
            FRA_METHOD);
    assertEquals(
        "Sensitivity finite difference method: number of node", 1, sensiFundingMethod.length);
    for (int loopnode = 0; loopnode < sensiFundingMethod.length; loopnode++) {
      assertEquals(
          "Sensitivity finite difference method: node sensitivity",
          resDsc[loopnode],
          sensiFundingMethod[loopnode]);
    }
  }

  @Test
  public void curveSensitivityCentered() {
    final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1();
    final double deltaShift = 1.0E-8;
    final double pv = FRA_METHOD.presentValue(FRA, curves).getAmount();
    // 1. Forward curve sensitivity
    final String bumpedCurveName = "Bumped Curve";
    final String[] bumpedCurvesForwardName = {FUNDING_CURVE_NAME, bumpedCurveName};
    final ForwardRateAgreement fraBumpedForward =
        (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName);
    final double[] nodeTimesForwardMethod =
        new double[] {FRA.getFixingPeriodStartTime(), FRA.getFixingPeriodEndTime()};
    final double[] sensiForward =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumpedForward,
            curves,
            pv,
            FORWARD_CURVE_NAME,
            bumpedCurveName,
            nodeTimesForwardMethod,
            deltaShift,
            FRA_METHOD);
    final double[] sensiForwardCentered =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumpedForward,
            curves,
            pv,
            FORWARD_CURVE_NAME,
            bumpedCurveName,
            nodeTimesForwardMethod,
            deltaShift,
            FRA_METHOD,
            FiniteDifferenceType.CENTRAL);
    final double[] sensiForwardCentered2 =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumpedForward,
            curves,
            FORWARD_CURVE_NAME,
            bumpedCurveName,
            nodeTimesForwardMethod,
            deltaShift,
            FRA_METHOD);
    final double[] sensiForwardForward =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumpedForward,
            curves,
            pv,
            FORWARD_CURVE_NAME,
            bumpedCurveName,
            nodeTimesForwardMethod,
            deltaShift,
            FRA_METHOD,
            FiniteDifferenceType.FORWARD);
    final double[] sensiForwardBackward =
        SensitivityFiniteDifference.curveSensitivity(
            fraBumpedForward,
            curves,
            pv,
            FORWARD_CURVE_NAME,
            bumpedCurveName,
            nodeTimesForwardMethod,
            deltaShift,
            FRA_METHOD,
            FiniteDifferenceType.BACKWARD);
    assertEquals("Sensitivity finite difference method: number of node", 2, sensiForward.length);
    assertEquals(
        "Sensitivity finite difference method: number of node", 2, sensiForwardCentered.length);
    assertEquals(
        "Sensitivity finite difference method: number of node", 2, sensiForwardCentered2.length);
    assertEquals(
        "Sensitivity finite difference method: number of node", 2, sensiForwardForward.length);
    assertEquals(
        "Sensitivity finite difference method: number of node", 2, sensiForwardBackward.length);
    for (int loopnode = 0; loopnode < sensiForward.length; loopnode++) {
      assertEquals(
          "Sensitivity finite difference method: centered vs non-centered",
          sensiForward[loopnode],
          sensiForwardForward[loopnode],
          1.0E-10);
      assertEquals(
          "Sensitivity finite difference method: centered vs non-centered",
          sensiForwardForward[loopnode],
          sensiForwardCentered[loopnode],
          1.0E-1);
      assertEquals(
          "Sensitivity finite difference method: centered vs non-centered",
          sensiForwardBackward[loopnode],
          sensiForwardCentered[loopnode],
          1.0E-1);
      assertEquals(
          "Sensitivity finite difference method: centered vs non-centered",
          sensiForwardCentered[loopnode],
          sensiForwardCentered2[loopnode],
          1.0E-10);
    }
  }
}
 @Test
 public void curveSensitivityCentered() {
   final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1();
   final double deltaShift = 1.0E-8;
   final double pv = FRA_METHOD.presentValue(FRA, curves).getAmount();
   // 1. Forward curve sensitivity
   final String bumpedCurveName = "Bumped Curve";
   final String[] bumpedCurvesForwardName = {FUNDING_CURVE_NAME, bumpedCurveName};
   final ForwardRateAgreement fraBumpedForward =
       (ForwardRateAgreement) FRA_DEFINITION.toDerivative(REFERENCE_DATE, bumpedCurvesForwardName);
   final double[] nodeTimesForwardMethod =
       new double[] {FRA.getFixingPeriodStartTime(), FRA.getFixingPeriodEndTime()};
   final double[] sensiForward =
       SensitivityFiniteDifference.curveSensitivity(
           fraBumpedForward,
           curves,
           pv,
           FORWARD_CURVE_NAME,
           bumpedCurveName,
           nodeTimesForwardMethod,
           deltaShift,
           FRA_METHOD);
   final double[] sensiForwardCentered =
       SensitivityFiniteDifference.curveSensitivity(
           fraBumpedForward,
           curves,
           pv,
           FORWARD_CURVE_NAME,
           bumpedCurveName,
           nodeTimesForwardMethod,
           deltaShift,
           FRA_METHOD,
           FiniteDifferenceType.CENTRAL);
   final double[] sensiForwardCentered2 =
       SensitivityFiniteDifference.curveSensitivity(
           fraBumpedForward,
           curves,
           FORWARD_CURVE_NAME,
           bumpedCurveName,
           nodeTimesForwardMethod,
           deltaShift,
           FRA_METHOD);
   final double[] sensiForwardForward =
       SensitivityFiniteDifference.curveSensitivity(
           fraBumpedForward,
           curves,
           pv,
           FORWARD_CURVE_NAME,
           bumpedCurveName,
           nodeTimesForwardMethod,
           deltaShift,
           FRA_METHOD,
           FiniteDifferenceType.FORWARD);
   final double[] sensiForwardBackward =
       SensitivityFiniteDifference.curveSensitivity(
           fraBumpedForward,
           curves,
           pv,
           FORWARD_CURVE_NAME,
           bumpedCurveName,
           nodeTimesForwardMethod,
           deltaShift,
           FRA_METHOD,
           FiniteDifferenceType.BACKWARD);
   assertEquals("Sensitivity finite difference method: number of node", 2, sensiForward.length);
   assertEquals(
       "Sensitivity finite difference method: number of node", 2, sensiForwardCentered.length);
   assertEquals(
       "Sensitivity finite difference method: number of node", 2, sensiForwardCentered2.length);
   assertEquals(
       "Sensitivity finite difference method: number of node", 2, sensiForwardForward.length);
   assertEquals(
       "Sensitivity finite difference method: number of node", 2, sensiForwardBackward.length);
   for (int loopnode = 0; loopnode < sensiForward.length; loopnode++) {
     assertEquals(
         "Sensitivity finite difference method: centered vs non-centered",
         sensiForward[loopnode],
         sensiForwardForward[loopnode],
         1.0E-10);
     assertEquals(
         "Sensitivity finite difference method: centered vs non-centered",
         sensiForwardForward[loopnode],
         sensiForwardCentered[loopnode],
         1.0E-1);
     assertEquals(
         "Sensitivity finite difference method: centered vs non-centered",
         sensiForwardBackward[loopnode],
         sensiForwardCentered[loopnode],
         1.0E-1);
     assertEquals(
         "Sensitivity finite difference method: centered vs non-centered",
         sensiForwardCentered[loopnode],
         sensiForwardCentered2[loopnode],
         1.0E-10);
   }
 }