public static YieldCurveBundle createCurvesUSD() {
   final String discountingCurvename = "USD Discounting";
   final String forward3MCurveName = "Forward USDLIBOR3M";
   final String forward6MCurveName = "Forward USDLIBOR6M";
   final InterpolatedDoublesCurve dscC =
       new InterpolatedDoublesCurve(
           new double[] {0.05, 1.0, 2.0, 5.0, 10.0, 20.0},
           new double[] {0.0050, 0.0100, 0.0150, 0.0200, 0.0200, 0.0300},
           CombinedInterpolatorExtrapolatorFactory.getInterpolator(
               Interpolator1DFactory.DOUBLE_QUADRATIC, Interpolator1DFactory.LINEAR_EXTRAPOLATOR),
           true,
           discountingCurvename);
   final InterpolatedDoublesCurve fwd3C =
       new InterpolatedDoublesCurve(
           new double[] {0.05, 1.0, 2.0, 5.0, 10.0, 25.0},
           new double[] {0.0070, 0.0120, 0.0165, 0.0215, 0.0210, 0.0310},
           CombinedInterpolatorExtrapolatorFactory.getInterpolator(
               Interpolator1DFactory.DOUBLE_QUADRATIC, Interpolator1DFactory.LINEAR_EXTRAPOLATOR),
           true,
           forward3MCurveName);
   final InterpolatedDoublesCurve fwd6C =
       new InterpolatedDoublesCurve(
           new double[] {0.05, 1.0, 2.0, 5.0, 10.0, 30.0},
           new double[] {0.0075, 0.0125, 0.0170, 0.0220, 0.0212, 0.0312},
           CombinedInterpolatorExtrapolatorFactory.getInterpolator(
               Interpolator1DFactory.DOUBLE_QUADRATIC, Interpolator1DFactory.LINEAR_EXTRAPOLATOR),
           true,
           forward6MCurveName);
   final YieldCurveBundle curves = new YieldCurveBundle();
   curves.setCurve(discountingCurvename, YieldCurve.from(dscC));
   curves.setCurve(forward3MCurveName, YieldCurve.from(fwd3C));
   curves.setCurve(forward6MCurveName, YieldCurve.from(fwd6C));
   return curves;
 }
 // TODO: review
 @Override
 public Double visitForexForward(final ForexForward fx, final YieldCurveBundle curves) {
   // TODO this is not a par rate, it is a forward FX rate
   final YieldAndDiscountCurve curve1 =
       curves.getCurve(fx.getPaymentCurrency1().getFundingCurveName());
   final YieldAndDiscountCurve curve2 =
       curves.getCurve(fx.getPaymentCurrency2().getFundingCurveName());
   final double t = fx.getPaymentTime();
   return fx.getSpotForexRate() * curve2.getDiscountFactor(t) / curve1.getDiscountFactor(t);
 }
  @Override
  public DoubleMatrix2D evaluate(final DoubleMatrix1D x) {

    YieldCurveBundle curves = _curveBuilderFunction.evaluate(x);

    final YieldCurveBundle knownCurves = _data.getKnownCurves();
    // set any known (i.e. fixed) curves
    if (knownCurves != null) {
      curves.addAll(knownCurves);
    }

    final int totalNodes = _data.getTotalNodes();
    final List<String> curveNames = _data.getCurveNames();

    final double[][] res = new double[_data.getNumInstruments()][totalNodes];
    for (int i = 0; i < _data.getNumInstruments(); i++) { // loop over all instruments
      InstrumentDerivative deriv = _data.getDerivative(i);
      final Map<String, List<DoublesPair>> senseMap =
          _calculator.visit(deriv, curves).getSensitivities();
      int offset = 0;
      for (final String name : curveNames) { // loop over all curves (by name)
        if (senseMap.containsKey(name)) {
          final Curve<Double, Double> curve = curves.getCurve(name).getCurve();
          if (!(curve instanceof InterpolatedDoublesCurve)) {
            throw new IllegalArgumentException("Can only handle InterpolatedDoublesCurve");
          }
          final InterpolatedDoublesCurve interpolatedCurve = (InterpolatedDoublesCurve) curve;
          final Interpolator1DDataBundle data = interpolatedCurve.getDataBundle();
          final Interpolator1D sensitivityCalculator = _data.getInterpolatorForCurve(name);
          final List<DoublesPair> senseList = senseMap.get(name);
          if (senseList.size() != 0) {
            final double[][] sensitivity = new double[senseList.size()][];
            int k = 0;
            for (final DoublesPair timeAndDF : senseList) {
              sensitivity[k++] =
                  sensitivityCalculator.getNodeSensitivitiesForValue(
                      data, timeAndDF.getFirst(), _data.useFiniteDifferenceForNodeSensitivities());
            }
            for (int j = 0; j < sensitivity[0].length; j++) {
              double temp = 0.0;
              k = 0;
              for (final DoublesPair timeAndDF : senseList) {
                temp += timeAndDF.getSecond() * sensitivity[k++][j];
              }
              res[i][j + offset] = temp;
            }
          }
        }
        offset += _data.getCurveNodePointsForCurve(name).length;
      }
    }
    return new DoubleMatrix2D(res);
  }
  @Override
  public Map<String, List<DoublesPair>> visitCouponIborSpread(
      final CouponIborSpread payment, final YieldCurveBundle data) {
    final String fundingCurveName = payment.getFundingCurveName();
    final String liborCurveName = payment.getForwardCurveName();
    final YieldAndDiscountCurve fundCurve = data.getCurve(fundingCurveName);
    final YieldAndDiscountCurve liborCurve = data.getCurve(liborCurveName);

    final double tPay = payment.getPaymentTime();
    final double tStart = payment.getFixingPeriodStartTime();
    final double tEnd = payment.getFixingPeriodEndTime();
    final double dfPay = fundCurve.getDiscountFactor(tPay);
    final double dfStart = liborCurve.getDiscountFactor(tStart);
    final double dfEnd = liborCurve.getDiscountFactor(tEnd);
    final double forward = (dfStart / dfEnd - 1) / payment.getFixingYearFraction();
    final double notional = payment.getNotional();

    final Map<String, List<DoublesPair>> result = new HashMap<String, List<DoublesPair>>();

    List<DoublesPair> temp = new ArrayList<DoublesPair>();
    DoublesPair s;
    s =
        new DoublesPair(
            tPay,
            -tPay
                * dfPay
                * notional
                * (forward + payment.getSpread())
                * payment.getPaymentYearFraction());
    temp.add(s);

    if (!liborCurveName.equals(fundingCurveName)) {
      result.put(fundingCurveName, temp);
      temp = new ArrayList<DoublesPair>();
    }

    final double ratio =
        notional
            * dfPay
            * dfStart
            / dfEnd
            * payment.getPaymentYearFraction()
            / payment.getFixingYearFraction();
    s = new DoublesPair(tStart, -tStart * ratio);
    temp.add(s);
    s = new DoublesPair(tEnd, tEnd * ratio);
    temp.add(s);

    result.put(liborCurveName, temp);

    return result;
  }
 /**
  * Create a yield curve bundle with three curves. One called "Credit" with a constant rate of 5%,
  * one called "Discounting" with a constant rate of 4%, and one called "Forward" with a constant
  * rate of 4.5%.
  *
  * @return The yield curve bundle.
  */
 public static YieldCurveBundle createCurvesBond() {
   final String CREDIT_CURVE_NAME = "Credit";
   final String DISCOUNTING_CURVE_NAME = "Repo";
   final String FORWARD_CURVE_NAME = "Forward";
   final YieldAndDiscountCurve CURVE_5 = YieldCurve.from(ConstantDoublesCurve.from(0.05));
   final YieldAndDiscountCurve CURVE_4 = YieldCurve.from(ConstantDoublesCurve.from(0.04));
   final YieldAndDiscountCurve CURVE_45 = YieldCurve.from(ConstantDoublesCurve.from(0.045));
   final YieldCurveBundle curves = new YieldCurveBundle();
   curves.setCurve(CREDIT_CURVE_NAME, CURVE_5);
   curves.setCurve(DISCOUNTING_CURVE_NAME, CURVE_4);
   curves.setCurve(FORWARD_CURVE_NAME, CURVE_45);
   return curves;
 }
 @Override
 public Double visitCouponIborSpread(final CouponIborSpread payment, final YieldCurveBundle data) {
   final YieldAndDiscountCurve curve = data.getCurve(payment.getForwardCurveName());
   return (curve.getDiscountFactor(payment.getFixingPeriodStartTime())
               / curve.getDiscountFactor(payment.getFixingPeriodEndTime())
           - 1.0)
       / payment.getFixingAccrualFactor();
 }
 /**
  * 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 Map<String, List<DoublesPair>> visitFixedPayment(
      final PaymentFixed payment, final YieldCurveBundle data) {
    final String curveName = payment.getFundingCurveName();
    final YieldAndDiscountCurve curve = data.getCurve(curveName);
    final double t = payment.getPaymentTime();

    final DoublesPair s = new DoublesPair(t, -t * payment.getAmount() * curve.getDiscountFactor(t));
    final List<DoublesPair> list = new ArrayList<DoublesPair>();
    list.add(s);
    final Map<String, List<DoublesPair>> result = new HashMap<String, List<DoublesPair>>();
    result.put(curveName, list);
    return result;
  }
 // TODO: review
 @Override
 public Double visitCash(final Cash cash, final YieldCurveBundle curves) {
   final YieldAndDiscountCurve curve = curves.getCurve(cash.getYieldCurveName());
   final double ta = cash.getStartTime();
   final double tb = cash.getEndTime();
   final double yearFrac = cash.getAccrualFactor();
   // TODO need a getForwardRate method on YieldAndDiscountCurve
   if (yearFrac == 0.0) {
     if (!CompareUtils.closeEquals(ta, tb, 1e-16)) {
       throw new IllegalArgumentException(
           "Year fraction is zero, but payment time greater than trade time");
     }
     final double eps = 1e-8;
     final double rate = curve.getInterestRate(ta);
     final double dRate = curve.getInterestRate(ta + eps);
     return rate + ta * (dRate - rate) / eps;
   }
   return (curve.getDiscountFactor(ta) / curve.getDiscountFactor(tb) - 1) / yearFrac;
 }