@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);
 }
 @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 put/call parity currency exposure. */
 public void currencyExposurePutCallParity() {
   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 forexOptionDefinitionCall =
       new ForexOptionDigitalDefinition(forexUnderlyingDefinition, expDate, isCall, isLong);
   final ForexOptionDigitalDefinition forexOptionDefinitionPut =
       new ForexOptionDigitalDefinition(forexUnderlyingDefinition, expDate, !isCall, isLong);
   final ForexOptionDigital forexOptionCall =
       forexOptionDefinitionCall.toDerivative(REFERENCE_DATE, CURVES_NAME);
   final ForexOptionDigital forexOptionPut =
       forexOptionDefinitionPut.toDerivative(REFERENCE_DATE, CURVES_NAME);
   final MultipleCurrencyAmount currencyExposureCall =
       METHOD_DIGITAL_SPREAD.currencyExposure(forexOptionCall, SMILE_BUNDLE);
   final MultipleCurrencyAmount currencyExposurePut =
       METHOD_DIGITAL_SPREAD.currencyExposure(forexOptionPut, SMILE_BUNDLE);
   final Double pvCash =
       PVC.visit(forexOptionPut.getUnderlyingForex().getPaymentCurrency2(), CURVES);
   assertEquals(
       "Forex Digital option: currency exposure put/call parity foreign",
       0,
       currencyExposureCall.getAmount(EUR) + currencyExposurePut.getAmount(EUR),
       TOLERANCE_PRICE);
   assertEquals(
       "Forex Digital option: currency exposure put/call parity domestic",
       Math.abs(pvCash),
       currencyExposureCall.getAmount(USD) + currencyExposurePut.getAmount(USD),
       TOLERANCE_PRICE);
 }
 @Test
 /** Tests the currency exposure in a flat smile case. */
 public void currencyExposureFlat() {
   MultipleCurrencyAmount ceSpread =
       METHOD_DIGITAL_SPREAD.currencyExposure(FOREX_CALL_OPTION, SMILE_BUNDLE_FLAT);
   MultipleCurrencyAmount ceBlack =
       METHOD_DIGITAL_BLACK.currencyExposure(FOREX_CALL_OPTION, SMILE_BUNDLE_FLAT);
   assertEquals(
       "Forex Digital option: call spread method - currency exposure",
       ceBlack.getAmount(USD),
       ceSpread.getAmount(USD),
       TOLERANCE_CE_FLAT);
   assertEquals(
       "Forex Digital option: call spread method - currency exposure",
       ceBlack.getAmount(EUR),
       ceSpread.getAmount(EUR),
       TOLERANCE_CE_FLAT);
 }
 @Test
 /** Tests the currency exposure. Method vs Calculator. */
 public void currencyExposureMethodVCalculator() {
   MultipleCurrencyAmount ceMethod =
       METHOD_DIGITAL_SPREAD.currencyExposure(FOREX_CALL_OPTION, SMILE_BUNDLE);
   CurrencyExposureCallSpreadBlackForexCalculator calculator =
       new CurrencyExposureCallSpreadBlackForexCalculator(STANDARD_SPREAD);
   MultipleCurrencyAmount ceCalculator = calculator.visit(FOREX_CALL_OPTION, SMILE_BUNDLE);
   assertEquals(
       "Forex Digital option: call spread method - currency exposure",
       ceMethod.getAmount(USD),
       ceCalculator.getAmount(USD),
       TOLERANCE_PRICE);
   assertEquals(
       "Forex Digital option: call spread method - currency exposure",
       ceMethod.getAmount(EUR),
       ceCalculator.getAmount(EUR),
       TOLERANCE_PRICE);
 }
 @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);
 }