@Test
 /** Tests put call parity. */
 public void presentValuePutCallParity() {
   final double strike = 1.45;
   final boolean isCall = true;
   final boolean isLong = true;
   final double notional = 100000000;
   final ZonedDateTime payDate =
       ScheduleCalculator.getAdjustedDate(
           REFERENCE_DATE, Period.ofMonths(9), BUSINESS_DAY, CALENDAR);
   final ZonedDateTime expDate =
       ScheduleCalculator.getAdjustedDate(payDate, -SETTLEMENT_DAYS, CALENDAR);
   final ForexDefinition forexUnderlyingDefinition =
       new ForexDefinition(EUR, USD, payDate, notional, strike);
   final ForexOptionDigitalDefinition callDefinition =
       new ForexOptionDigitalDefinition(forexUnderlyingDefinition, expDate, isCall, isLong);
   final ForexOptionDigitalDefinition putDefinition =
       new ForexOptionDigitalDefinition(forexUnderlyingDefinition, expDate, !isCall, isLong);
   final ForexOptionDigital call = callDefinition.toDerivative(REFERENCE_DATE, CURVES_NAME);
   final ForexOptionDigital put = putDefinition.toDerivative(REFERENCE_DATE, CURVES_NAME);
   final MultipleCurrencyAmount pvCall = METHOD_DIGITAL_SPREAD.presentValue(call, SMILE_BUNDLE);
   final MultipleCurrencyAmount pvPut = METHOD_DIGITAL_SPREAD.presentValue(put, SMILE_BUNDLE);
   final Double pvCash = PVC.visit(put.getUnderlyingForex().getPaymentCurrency2(), CURVES);
   assertEquals(
       "Forex Digital option: call spread method - present value",
       pvCall.getAmount(USD) + pvPut.getAmount(USD),
       Math.abs(pvCash),
       TOLERANCE_PRICE_FLAT);
 }
 @Test
 /** Tests the present value long/short parity. */
 public void presentValueLongShort() {
   final ForexOptionDigitalDefinition forexOptionShortDefinition =
       new ForexOptionDigitalDefinition(FOREX_DEFINITION, OPTION_EXP_DATE, IS_CALL, !IS_LONG);
   final InstrumentDerivative forexOptionShort =
       forexOptionShortDefinition.toDerivative(REFERENCE_DATE, CURVES_NAME);
   final MultipleCurrencyAmount pvShort =
       METHOD_DIGITAL_SPREAD.presentValue(forexOptionShort, SMILE_BUNDLE);
   final MultipleCurrencyAmount pvLong =
       METHOD_DIGITAL_SPREAD.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: present value long/short parity",
       pvLong.getAmount(USD),
       -pvShort.getAmount(USD),
       1E-2);
   final MultipleCurrencyAmount ceShort =
       METHOD_DIGITAL_SPREAD.currencyExposure(forexOptionShort, SMILE_BUNDLE);
   final MultipleCurrencyAmount ceLong =
       METHOD_DIGITAL_SPREAD.currencyExposure(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: currency exposure long/short parity",
       ceLong.getAmount(USD),
       -ceShort.getAmount(USD),
       1E-2);
   assertEquals(
       "Forex Digital option: currency exposure long/short parity",
       ceLong.getAmount(EUR),
       -ceShort.getAmount(EUR),
       1E-2);
 }
 @Override
 protected Set<ComputedValue> getResult(
     final ForexDerivative fxOption,
     final SmileDeltaTermStructureDataBundle data,
     final FunctionInputs inputs,
     final ComputationTarget target) {
   final MultipleCurrencyAmount result = CALCULATOR.visit(fxOption, data);
   final int n = result.size();
   final Currency[] keys = new Currency[n];
   final double[] values = new double[n];
   int i = 0;
   for (final CurrencyAmount ca : result) {
     keys[i] = ca.getCurrency();
     values[i++] = ca.getAmount();
   }
   final ValueProperties properties =
       createValueProperties()
           .with(ValuePropertyNames.PAY_CURVE, getPutCurveName())
           .with(ValuePropertyNames.RECEIVE_CURVE, getCallCurveName())
           .with(ValuePropertyNames.SURFACE, getSurfaceName())
           .get();
   final ValueSpecification spec =
       new ValueSpecification(getValueRequirementName(), target.toSpecification(), properties);
   return Collections.singleton(
       new ComputedValue(spec, new CurrencyLabelledMatrix1D(keys, values)));
 }
 @Test
 /** Tests the present value. */
 public void presentValueNoNotional() {
   final MultipleCurrencyAmount pv = METHOD.presentValue(ZERO_COUPON_CAP, BLACK_INFLATION);
   final double timeToMaturity =
       ZERO_COUPON_CAP.getReferenceEndTime() - ZERO_COUPON_CAP.getLastKnownFixingTime();
   final double df =
       MARKET
           .getCurve(ZERO_COUPON_CAP.getCurrency())
           .getDiscountFactor(ZERO_COUPON_CAP.getPaymentTime());
   final double finalIndex =
       MARKET.getCurve(PRICE_INDEX_EUR).getPriceIndex(ZERO_COUPON_CAP.getReferenceEndTime());
   final double forward = finalIndex / INDEX_1MAY_2008;
   final EuropeanVanillaOption option =
       new EuropeanVanillaOption(
           Math.pow(1 + ZERO_COUPON_CAP.getStrike(), ZERO_COUPON_CAP.getMaturity()),
           timeToMaturity,
           ZERO_COUPON_CAP.isCap());
   final double volatility =
       BLACK_INFLATION
           .getBlackParameters()
           .getVolatility(ZERO_COUPON_CAP.getReferenceEndTime(), ZERO_COUPON_CAP.getStrike());
   final BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatility);
   final Function1D<BlackFunctionData, Double> func = BLACK_FUNCTION.getPriceFunction(option);
   final double pvExpected =
       df
           * func.evaluate(dataBlack)
           * ZERO_COUPON_CAP.getNotional()
           * ZERO_COUPON_CAP.getPaymentYearFraction();
   assertEquals(
       "Zero-coupon inflation DiscountingMethod: Present value",
       pvExpected,
       pv.getAmount(ZERO_COUPON_CAP.getCurrency()),
       TOLERANCE_PV);
 }
 @Test
 /** Tests the Black volatility sensitivity (vega). */
 public void presentValueBlackNodeSensitivity() {
   final double shift = 1.0E-6;
   final PresentValueBlackSwaptionSensitivity pvbvs =
       METHOD_BLACK.presentValueBlackSensitivity(SWAPTION_LONG_REC, BLACK_MULTICURVES);
   final PresentValueBlackSwaptionSensitivity pvbns =
       BSSNC.calculateNodeSensitivities(pvbvs, BLACK);
   final double[] x =
       ((InterpolatedDoublesSurface) BLACK.getVolatilitySurface()).getXDataAsPrimitive();
   final double[] y =
       ((InterpolatedDoublesSurface) BLACK.getVolatilitySurface()).getYDataAsPrimitive();
   for (int loopindex = 0; loopindex < x.length; loopindex++) {
     final BlackFlatSwaptionParameters BlackP =
         BlackDataSets.createBlackSwaptionEUR6Shift(loopindex, shift);
     final BlackSwaptionFlatProviderDiscount curvesBlackP =
         new BlackSwaptionFlatProviderDiscount(MULTICURVES, BlackP);
     final MultipleCurrencyAmount pvP = METHOD_BLACK.presentValue(SWAPTION_LONG_REC, curvesBlackP);
     final BlackFlatSwaptionParameters BlackM =
         BlackDataSets.createBlackSwaptionEUR6Shift(loopindex, -shift);
     final BlackSwaptionFlatProviderDiscount curvesBlackM =
         new BlackSwaptionFlatProviderDiscount(MULTICURVES, BlackM);
     final MultipleCurrencyAmount pvM = METHOD_BLACK.presentValue(SWAPTION_LONG_REC, curvesBlackM);
     assertEquals(
         "Swaption Black method: present value volatility sensitivity",
         (pvP.getAmount(EUR) - pvM.getAmount(EUR)) / (2 * shift),
         pvbns.getSensitivity().getMap().get(new DoublesPair(x[loopindex], y[loopindex])),
         TOLERANCE_PV_DELTA);
   }
 }
 @Test
 /** Test the present value. */
 public void presentValueExplicit() {
   final MultipleCurrencyAmount pv = METHOD_HW.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final double timeToExpiry = SWAPTION_LONG_PAYER.getTimeToExpiry();
   final AnnuityPaymentFixed cfe =
       CFEC.visitSwap(SWAPTION_LONG_PAYER.getUnderlyingSwap(), MULTICURVES);
   final int numberOfPayments = cfe.getNumberOfPayments();
   final double alpha[] = new double[numberOfPayments];
   final double disccf[] = new double[numberOfPayments];
   for (int loopcf = 0; loopcf < numberOfPayments; loopcf++) {
     alpha[loopcf] =
         MODEL.alpha(
             HW_PARAMETERS,
             0.0,
             timeToExpiry,
             timeToExpiry,
             cfe.getNthPayment(loopcf).getPaymentTime());
     disccf[loopcf] =
         MULTICURVES.getDiscountFactor(EUR, cfe.getNthPayment(loopcf).getPaymentTime())
             * cfe.getNthPayment(loopcf).getAmount();
   }
   final double kappa = MODEL.kappa(disccf, alpha);
   double pvExpected = 0.0;
   for (int loopcf = 0; loopcf < numberOfPayments; loopcf++) {
     pvExpected += disccf[loopcf] * NORMAL.getCDF(-kappa - alpha[loopcf]);
   }
   assertEquals(
       "Swaption physical - Hull-White - present value", pvExpected, pv.getAmount(EUR), 1E-2);
   final MultipleCurrencyAmount pv2 =
       METHOD_HW.presentValue(SWAPTION_LONG_PAYER, cfe, HW_MULTICURVES);
   assertEquals("Swaption physical - Hull-White - present value", pv, pv2);
 }
 /**
  * Returns a copy of this {@code MultipleCurrencyAmount} with the specified amount added.
  *
  * <p>This adds the specified amount to this monetary amount, returning a new object. If the
  * currency is already present, the amount is added to the existing amount. If the currency is not
  * yet present, the currency-amount is added to the map. The addition simply uses standard {@code
  * double} arithmetic.
  *
  * <p>This instance is immutable and unaffected by this method.
  *
  * @param multipleCurrencyAmountToAdd the currency to add to, not null
  * @return an amount based on this with the specified amount added, not null
  */
 public MultipleCurrencyAmount plus(final MultipleCurrencyAmount multipleCurrencyAmountToAdd) {
   ArgumentChecker.notNull(multipleCurrencyAmountToAdd, "multipleCurrencyAmountToAdd");
   MultipleCurrencyAmount result = this;
   for (CurrencyAmount currencyAmount : multipleCurrencyAmountToAdd) {
     result = result.plus(currencyAmount);
   }
   return result;
 }
 @Test
 public void presentValueMethodVsCalculator() {
   final MultipleCurrencyAmount pvMethod = METHOD_CPN_IBOR.presentValue(CPN_IBOR, MULTICURVES);
   final MultipleCurrencyAmount pvCalculator = CPN_IBOR.accept(PVDC, MULTICURVES);
   assertEquals(
       "CouponFixedDiscountingMarketMethod: present value",
       pvMethod.getAmount(EUR),
       pvCalculator.getAmount(EUR),
       TOLERANCE_PV);
 }
 @Test
 /** Compare the method figures to the Calculator figures. */
 public void presentValueMethodVsCalculator() {
   final MultipleCurrencyAmount pvMethod =
       METHOD_BLACK.presentValue(SWAPTION_LONG_REC, BLACK_MULTICURVES);
   final MultipleCurrencyAmount pvCalculator = SWAPTION_LONG_REC.accept(PVBSC, BLACK_MULTICURVES);
   assertEquals(
       "Swaption Black method: present value",
       pvCalculator.getAmount(EUR),
       pvMethod.getAmount(EUR),
       TOLERANCE_PV);
 }
 @Test
 /** Tests the currency exposure against the present value. */
 public void currencyExposureVsPresentValue() {
   MultipleCurrencyAmount pv = METHOD_DIGITAL_SPREAD.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE);
   MultipleCurrencyAmount ce =
       METHOD_DIGITAL_SPREAD.currencyExposure(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: call spread method - currency exposure vs present value",
       ce.getAmount(USD) + ce.getAmount(EUR) * SPOT,
       pv.getAmount(USD),
       TOLERANCE_PRICE);
 }
 @Test
 /** Tests the present value in a flat smile case. */
 public void presentValueFlat() {
   MultipleCurrencyAmount pvSpread =
       METHOD_DIGITAL_SPREAD.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE_FLAT);
   MultipleCurrencyAmount pvBlack =
       METHOD_DIGITAL_BLACK.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE_FLAT);
   assertEquals(
       "Forex Digital option: call spread method - present value",
       pvBlack.getAmount(USD),
       pvSpread.getAmount(USD),
       TOLERANCE_PRICE_FLAT);
 }
 @Test
 /** Tests long/short parity. */
 public void longShortParityExplicit() {
   final MultipleCurrencyAmount pvLong =
       METHOD_HW.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final MultipleCurrencyAmount pvShort =
       METHOD_HW.presentValue(SWAPTION_SHORT_PAYER, HW_MULTICURVES);
   assertEquals(
       "Swaption physical - Hull-White - present value - long/short parity",
       pvLong.getAmount(EUR),
       -pvShort.getAmount(EUR),
       TOLERANCE_PV);
 }
 @Test
 /** Tests the present value with an explicit computation. */
 public void presentValue() {
   double strikeM = STRIKE * (1 - STANDARD_SPREAD);
   double strikeP = STRIKE * (1 + STANDARD_SPREAD);
   Forex forexM =
       new Forex(
           FOREX.getPaymentCurrency1().withAmount(1.0),
           FOREX.getPaymentCurrency2().withAmount(-strikeM));
   Forex forexP =
       new Forex(
           FOREX.getPaymentCurrency1().withAmount(1.0),
           FOREX.getPaymentCurrency2().withAmount(-strikeP));
   ForexOptionVanilla vanillaM =
       new ForexOptionVanilla(forexM, FOREX_CALL_OPTION.getExpirationTime(), IS_CALL, IS_LONG);
   ForexOptionVanilla vanillaP =
       new ForexOptionVanilla(forexP, FOREX_CALL_OPTION.getExpirationTime(), IS_CALL, IS_LONG);
   MultipleCurrencyAmount pvP = METHOD_VANILLA_BLACK.presentValue(vanillaP, SMILE_BUNDLE);
   MultipleCurrencyAmount pvM = METHOD_VANILLA_BLACK.presentValue(vanillaM, SMILE_BUNDLE);
   MultipleCurrencyAmount pvExpected =
       pvM.plus(pvP.multipliedBy(-1.0))
           .multipliedBy(
               1.0 / (strikeP - strikeM) * Math.abs(FOREX.getPaymentCurrency2().getAmount()));
   MultipleCurrencyAmount pvComputed =
       METHOD_DIGITAL_SPREAD.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: call spread method - present value",
       pvExpected.getAmount(USD),
       pvComputed.getAmount(USD),
       TOLERANCE_PRICE);
 }
 @Test
 /** Tests the present value. Method vs Calculator. */
 public void presentValueMethodVCalculator() {
   MultipleCurrencyAmount pv1 =
       METHOD_DIGITAL_SPREAD.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE);
   PresentValueCallSpreadBlackForexCalculator calculator =
       new PresentValueCallSpreadBlackForexCalculator(STANDARD_SPREAD);
   MultipleCurrencyAmount pvCalculator = calculator.visit(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: call spread method - present value",
       pv1.getAmount(USD),
       pvCalculator.getAmount(USD),
       TOLERANCE_PRICE);
 }
 /**
  * Returns a copy of this {@code MultipleCurrencyAmount} with all the amounts multiplied by the
  * factor.
  *
  * <p>This instance is immutable and unaffected by this method.
  *
  * @param factor The multiplicative factor.
  * @return An amount based on this with all the amounts multiplied by the factor. Not null
  */
 public MultipleCurrencyAmount multipliedBy(final double factor) {
   TreeMap<Currency, Double> map = new TreeMap<Currency, Double>();
   for (CurrencyAmount currencyAmount : this) {
     map.put(currencyAmount.getCurrency(), currencyAmount.getAmount() * factor);
   }
   return MultipleCurrencyAmount.of(map);
 }
 @Test
 /** Check the conversion of a multiple currency amount. */
 public void convert() {
   final FXMatrix fxMatrix = new FXMatrix();
   fxMatrix.addCurrency(EUR, USD, EUR_USD);
   fxMatrix.addCurrency(GBP, EUR, GBP_EUR);
   final double amountGBP = 1.0;
   final double amountEUR = 2.0;
   final double amountUSD = 3.0;
   MultipleCurrencyAmount amount = MultipleCurrencyAmount.of(GBP, amountGBP);
   amount = amount.plus(EUR, amountEUR);
   amount = amount.plus(USD, amountUSD);
   final CurrencyAmount totalUSDCalculated = fxMatrix.convert(amount, USD);
   final double totalUSDExpected = amountUSD + amountEUR * EUR_USD + amountGBP * GBP_EUR * EUR_USD;
   assertEquals("FXMatrix - convert", totalUSDExpected, totalUSDCalculated.getAmount(), 1.0E-10);
   assertEquals("FXMatrix - convert", USD, totalUSDCalculated.getCurrency());
 }
  @Test(enabled = false)
  /** Tests of performance. "enabled = false" for the standard testing. */
  public void performanceCurveSensitivity() {
    long startTime, endTime;
    final int nbTest = 25;
    MultipleCurrencyAmount pvMC = MultipleCurrencyAmount.of(EUR, 0.0);
    final MultipleCurrencyMulticurveSensitivity pvcsExplicit =
        METHOD_HW.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES);
    MultipleCurrencyMulticurveSensitivity pvcsMC = pvcsExplicit;
    final HullWhiteMonteCarloMethod methodMC =
        new HullWhiteMonteCarloMethod(
            new NormalRandomNumberGenerator(0.0, 1.0, new MersenneTwister()), NB_PATH);

    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvMC = METHOD_HW_MONTECARLO.presentValue(SWAPTION_LONG_PAYER, EUR, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest
            + " swaption Hull-White Monte Carlo method ("
            + NB_PATH
            + " paths): "
            + (endTime - startTime)
            + " ms / price:"
            + pvMC.toString());
    // Performance note: HW approximation: 03-Dec-2012: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 250
    // ms for 25 swaptions (12500 paths).
    startTime = System.currentTimeMillis();
    for (int looptest = 0; looptest < nbTest; looptest++) {
      pvcsMC = methodMC.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, EUR, HW_MULTICURVES);
    }
    endTime = System.currentTimeMillis();
    System.out.println(
        nbTest
            + " curve sensitivity swaption Hull-White MC method: ("
            + NB_PATH
            + " paths) "
            + (endTime - startTime)
            + " ms / risk:"
            + pvcsMC.toString());
    // Performance note: curve sensitivity (40): 03-Dec-2012: On Mac Pro 3.2 GHz Quad-Core Intel
    // Xeon: 600 ms for 25 swaptions (12500 paths).

  }
 @Test
 public void presentValueMarketDiscount() {
   final MultipleCurrencyAmount pvComputed = METHOD_CPN_IBOR.presentValue(CPN_IBOR, MULTICURVES);
   final double forward =
       MULTICURVES.getForwardRate(
           EURIBOR3M,
           CPN_IBOR.getFixingPeriodStartTime(),
           CPN_IBOR.getFixingPeriodEndTime(),
           CPN_IBOR.getFixingAccrualFactor());
   final double df =
       MULTICURVES.getDiscountFactor(EURIBOR3M.getCurrency(), CPN_IBOR.getPaymentTime());
   final double pvExpected = NOTIONAL * ACCRUAL_FACTOR * forward * df;
   assertEquals(
       "CouponIborDiscountingMarketMethod: present value",
       pvExpected,
       pvComputed.getAmount(EURIBOR3M.getCurrency()),
       TOLERANCE_PV);
 }
 /**
  * Compute the the present value of a fixed payment by discounting to a parallel curve movement.
  *
  * @param payment The payment.
  * @param multicurves The multi-curve provider.
  * @return The present value.
  */
 public MultipleCurrencyAmount presentValue(
     final PaymentFixed payment, final MulticurveProviderInterface multicurves) {
   ArgumentChecker.notNull(payment, "Payment");
   ArgumentChecker.notNull(multicurves, "Multi-curves");
   final double pv =
       payment.getAmount()
           * multicurves.getDiscountFactor(payment.getCurrency(), payment.getPaymentTime());
   return MultipleCurrencyAmount.of(payment.getCurrency(), pv);
 }
 @Test
 public void testNormalPresentValue() {
   Result<MultipleCurrencyAmount> result =
       _functionRunner.runFunction(
           ARGS,
           createSuppliedData(),
           new Function<Environment, Result<MultipleCurrencyAmount>>() {
             @Override
             public Result<MultipleCurrencyAmount> apply(Environment env) {
               return _normalIRFutureOptionFn.calculatePV(env, _irFutureOptionTrade);
             }
           });
   assertSuccess(result);
   MultipleCurrencyAmount mca = result.getValue();
   assertThat(
       mca.getCurrencyAmount(Currency.USD).getAmount(),
       is(closeTo(-902.7156551, STD_TOLERANCE_PV)));
 }
 @Test
 public void presentValue() {
   final MultipleCurrencyAmount pvMethod =
       METHOD_BLACK.presentValue(SWAPTION_LONG_REC, BLACK_MULTICURVES);
   final double forward = SWAPTION_LONG_REC.getUnderlyingSwap().accept(PRDC, MULTICURVES);
   final double pvbp =
       METHOD_SWAP.presentValueBasisPoint(SWAPTION_LONG_REC.getUnderlyingSwap(), MULTICURVES);
   final double volatility =
       BLACK.getVolatility(
           SWAPTION_LONG_REC.getTimeToExpiry(), SWAPTION_LONG_REC.getMaturityTime());
   final BlackPriceFunction blackFunction = new BlackPriceFunction();
   final BlackFunctionData dataBlack = new BlackFunctionData(forward, pvbp, volatility);
   final Function1D<BlackFunctionData, Double> func =
       blackFunction.getPriceFunction(SWAPTION_LONG_REC);
   final double pvExpected = func.evaluate(dataBlack);
   assertEquals(
       "Swaption Black method: present value", pvExpected, pvMethod.getAmount(EUR), TOLERANCE_PV);
 }
 /**
  * Compute the present value of a commodity cash settle forward by discounting.
  *
  * @param forward The forward.
  * @param multicurve The commodity multi-curve provider.
  * @return The present value.
  */
 public MultipleCurrencyAmount presentValue(
     final ForwardCommodityCashSettle forward, final CommodityProviderInterface multicurve) {
   ArgumentChecker.notNull(forward, "Forward");
   ArgumentChecker.notNull(multicurve, "Multi-curves provider");
   final double fwd =
       multicurve.getForwardValue(forward.getUnderlying(), forward.getSettlementTime());
   final double df = multicurve.getDiscountFactor(forward.getCurrency(), forward.getPaymentTime());
   final double pv = forward.getNotional() * (fwd - forward.getRate()) * df;
   return MultipleCurrencyAmount.of(forward.getCurrency(), pv);
 }
 @Test
 /** Compare explicit formula with approximated formula. */
 public void presentValueApproximation() {
   final BlackImpliedVolatilityFormula implied = new BlackImpliedVolatilityFormula();
   final double forward =
       SWAPTION_LONG_PAYER
           .getUnderlyingSwap()
           .accept(ParRateDiscountingCalculator.getInstance(), MULTICURVES);
   final double pvbp =
       METHOD_SWAP.presentValueBasisPoint(SWAPTION_LONG_PAYER.getUnderlyingSwap(), MULTICURVES);
   final MultipleCurrencyAmount pvPayerLongExplicit =
       METHOD_HW.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final MultipleCurrencyAmount pvPayerLongApproximation =
       METHOD_HW_APPROXIMATION.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final BlackFunctionData data = new BlackFunctionData(forward, pvbp, 0.20);
   final double volExplicit =
       implied.getImpliedVolatility(data, SWAPTION_LONG_PAYER, pvPayerLongExplicit.getAmount(EUR));
   final double volApprox =
       implied.getImpliedVolatility(
           data, SWAPTION_LONG_PAYER, pvPayerLongApproximation.getAmount(EUR));
   assertEquals(
       "Swaption physical - Hull-White - present value - explicit/approximation",
       pvPayerLongExplicit.getAmount(EUR),
       pvPayerLongApproximation.getAmount(EUR),
       5.0E+2);
   assertEquals(
       "Swaption physical - Hull-White - present value - explicit/approximation",
       volExplicit,
       volApprox,
       2.5E-4); // 0.025%
   final MultipleCurrencyAmount pvReceiverLongExplicit =
       METHOD_HW.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   final MultipleCurrencyAmount pvReceiverLongApproximation =
       METHOD_HW_APPROXIMATION.presentValue(SWAPTION_LONG_PAYER, HW_MULTICURVES);
   assertEquals(
       "Swaption physical - Hull-White - present value - explicit/numerical integration",
       pvReceiverLongExplicit.getAmount(EUR),
       pvReceiverLongApproximation.getAmount(EUR),
       5.0E+2);
 }
 @Test
 /** Tests the Black volatility sensitivity (vega). */
 public void presentValueBlackSensitivity() {
   final double shift = 1.0E-6;
   final PresentValueBlackSwaptionSensitivity pvbvs =
       METHOD_BLACK.presentValueBlackSensitivity(SWAPTION_LONG_REC, BLACK_MULTICURVES);
   final BlackFlatSwaptionParameters BlackP = BlackDataSets.createBlackSwaptionEUR6Shift(shift);
   final BlackSwaptionFlatProviderDiscount curvesBlackP =
       new BlackSwaptionFlatProviderDiscount(MULTICURVES, BlackP);
   final MultipleCurrencyAmount pvP = METHOD_BLACK.presentValue(SWAPTION_LONG_REC, curvesBlackP);
   final BlackFlatSwaptionParameters BlackM = BlackDataSets.createBlackSwaptionEUR6Shift(-shift);
   final BlackSwaptionFlatProviderDiscount curvesBlackM =
       new BlackSwaptionFlatProviderDiscount(MULTICURVES, BlackM);
   final MultipleCurrencyAmount pvM = METHOD_BLACK.presentValue(SWAPTION_LONG_REC, curvesBlackM);
   final DoublesPair point =
       new DoublesPair(SWAPTION_LONG_REC.getTimeToExpiry(), SWAPTION_LONG_REC.getMaturityTime());
   assertEquals(
       "Swaption Black method: present value volatility sensitivity",
       (pvP.getAmount(EUR) - pvM.getAmount(EUR)) / (2 * shift),
       pvbvs.getSensitivity().getMap().get(point),
       TOLERANCE_PV_DELTA);
 }
Example #25
0
 public static CurrencyLabelledMatrix1D getMultipleCurrencyAmountAsMatrix(
     final MultipleCurrencyAmount mca) {
   ArgumentChecker.notNull(mca, "multiple currency amount");
   final int n = mca.size();
   final Currency[] keys = new Currency[n];
   final double[] values = new double[n];
   int i = 0;
   for (final CurrencyAmount ca : mca) {
     keys[i] = ca.getCurrency();
     values[i++] = ca.getAmount();
   }
   return new CurrencyLabelledMatrix1D(keys, values);
 }
 @Test
 /** Tests the present value. Spread change. */
 public void presentValueSpreadChange() {
   double spread1 = 0.0001;
   double spread2 = 0.0002;
   ForexOptionDigitalCallSpreadBlackMethod methodCallSpreadBlack1 =
       new ForexOptionDigitalCallSpreadBlackMethod(spread1);
   ForexOptionDigitalCallSpreadBlackMethod methodCallSpreadBlack2 =
       new ForexOptionDigitalCallSpreadBlackMethod(spread2);
   MultipleCurrencyAmount pv1 =
       methodCallSpreadBlack1.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE);
   MultipleCurrencyAmount pv2 =
       methodCallSpreadBlack2.presentValue(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: call spread method - present value",
       pv1.getAmount(USD),
       pv2.getAmount(USD),
       10.0);
   //    MultipleCurrencyAmount pvBlack = METHOD_DIGITAL_BLACK.presentValue(FOREX_CALL_OPTION,
   // SMILE_BUNDLE);
   //    assertEquals("Forex Digital option: call spread method - present value",
   // pvBlack.getAmount(USD), pv2.getAmount(USD), 10.0); // Should fail
 }
 @Test
 /** Tests the currency exposure with an explicit computation. */
 public void currencyExposure() {
   double spread = 0.0001; // Relative spread.
   double strikeM = STRIKE * (1 - spread);
   double strikeP = STRIKE * (1 + spread);
   Forex forexM =
       new Forex(
           FOREX.getPaymentCurrency1().withAmount(1.0),
           FOREX.getPaymentCurrency2().withAmount(-strikeM));
   Forex forexP =
       new Forex(
           FOREX.getPaymentCurrency1().withAmount(1.0),
           FOREX.getPaymentCurrency2().withAmount(-strikeP));
   ForexOptionVanilla vanillaM =
       new ForexOptionVanilla(forexM, FOREX_CALL_OPTION.getExpirationTime(), IS_CALL, IS_LONG);
   ForexOptionVanilla vanillaP =
       new ForexOptionVanilla(forexP, FOREX_CALL_OPTION.getExpirationTime(), IS_CALL, IS_LONG);
   MultipleCurrencyAmount ceP = METHOD_VANILLA_BLACK.currencyExposure(vanillaP, SMILE_BUNDLE);
   MultipleCurrencyAmount ceM = METHOD_VANILLA_BLACK.currencyExposure(vanillaM, SMILE_BUNDLE);
   MultipleCurrencyAmount ceExpected =
       ceM.plus(ceP.multipliedBy(-1.0))
           .multipliedBy(
               1.0 / (strikeP - strikeM) * Math.abs(FOREX.getPaymentCurrency2().getAmount()));
   MultipleCurrencyAmount ceComputed =
       METHOD_DIGITAL_SPREAD.currencyExposure(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: call spread method - currency exposure",
       ceExpected.getAmount(USD),
       ceComputed.getAmount(USD),
       TOLERANCE_PRICE);
   assertEquals(
       "Forex Digital option: call spread method - currency exposure",
       ceExpected.getAmount(EUR),
       ceComputed.getAmount(EUR),
       TOLERANCE_PRICE);
 }
 @Test
 public void testMultipleCashFlowsNoNetting() {
   for (final InstrumentDefinition<?> definition : NO_NETTING_MULTIPLE_CASHFLOWS) {
     final TreeMap<LocalDate, MultipleCurrencyAmount> pay =
         new TreeMap<LocalDate, MultipleCurrencyAmount>(
             definition.accept(PAY_CASH_FLOWS, IBOR_FIXING_SERIES));
     final TreeMap<LocalDate, MultipleCurrencyAmount> receive =
         new TreeMap<LocalDate, MultipleCurrencyAmount>(
             definition.accept(RECEIVE_CASH_FLOWS, IBOR_FIXING_SERIES));
     final TreeMap<LocalDate, MultipleCurrencyAmount> netted =
         new TreeMap<LocalDate, MultipleCurrencyAmount>(
             definition.accept(VISITOR, IBOR_FIXING_SERIES));
     final Set<LocalDate> combinedDates = new HashSet<LocalDate>();
     combinedDates.addAll(pay.keySet());
     combinedDates.addAll(receive.keySet());
     assertEquals(combinedDates.size(), netted.size());
     for (final Map.Entry<LocalDate, MultipleCurrencyAmount> entry : netted.entrySet()) {
       final LocalDate date = entry.getKey();
       final MultipleCurrencyAmount payAmount = pay.get(date);
       final MultipleCurrencyAmount receiveAmount = receive.get(date);
       MultipleCurrencyAmount combinedAmountForDate = null;
       if (payAmount != null) {
         combinedAmountForDate = payAmount.multipliedBy(-1);
         if (receiveAmount != null) {
           combinedAmountForDate = combinedAmountForDate.plus(receiveAmount);
         }
       } else {
         if (receiveAmount != null) {
           combinedAmountForDate = receiveAmount;
         }
       }
       assertNotNull(combinedAmountForDate);
       assertEquals(combinedAmountForDate, entry.getValue());
     }
   }
 }
 @Test
 public void presentValueDiscountingCalculator() {
   final MultipleCurrencyAmount pvSwap = SWAP_MULTI_LEG.accept(PVDC, MULTICURVES);
   MultipleCurrencyAmount pvLegs = MultipleCurrencyAmount.of(EUR, 0.0);
   for (int loopleg = 0; loopleg < NB_LEGS; loopleg++) {
     pvLegs = pvLegs.plus(SWAP_MULTI_LEG.getLegs()[loopleg].accept(PVDC, MULTICURVES));
   }
   assertEquals(
       "SwapMultileg: presentValueDiscountingCalculator",
       pvSwap.getAmount(EUR),
       pvLegs.getAmount(EUR),
       TOLERANCE_PV);
 }
 @Test
 /** Tests payer/receiver/swap parity. */
 public void payerReceiverParityExplicit() {
   final MultipleCurrencyAmount pvReceiverLong =
       METHOD_HW.presentValue(SWAPTION_LONG_RECEIVER, HW_MULTICURVES);
   final MultipleCurrencyAmount pvPayerShort =
       METHOD_HW.presentValue(SWAPTION_SHORT_PAYER, HW_MULTICURVES);
   final MultipleCurrencyAmount pvSwap = SWAP_RECEIVER.accept(PVDC, MULTICURVES);
   assertEquals(
       "Swaption physical - Hull-White - present value - payer/receiver/swap parity",
       pvReceiverLong.getAmount(EUR) + pvPayerShort.getAmount(EUR),
       pvSwap.getAmount(EUR),
       TOLERANCE_PV);
 }