ForexNonDeliverableOptionBlackSmileMethod { public MultipleCurrencyAmount currencyExposure(final ForexNonDeliverableOption optionForex, final BlackForexSmileProviderInterface smileMulticurves) { Validate.notNull(optionForex, "Forex option"); Validate.notNull(smileMulticurves, "Smile"); Validate.isTrue(smileMulticurves.checkCurrencies(optionForex.getCurrency1(), optionForex.getCurrency2()), "Option currencies not compatible with smile data"); final MulticurveProviderInterface multicurves = smileMulticurves.getMulticurveProvider(); final double paymentTime = optionForex.getUnderlyingNDF().getPaymentTime(); final double expiryTime = optionForex.getExpiryTime(); final double strike = 1.0 / optionForex.getStrike(); final double dfDelivery = multicurves.getDiscountFactor(optionForex.getCurrency2(), paymentTime); final double dfNonDelivery = multicurves.getDiscountFactor(optionForex.getCurrency1(), paymentTime); final double spot = multicurves.getFxRate(optionForex.getCurrency1(), optionForex.getCurrency2()); final double forward = spot * dfNonDelivery / dfDelivery; final double volatility = smileMulticurves.getVolatility(optionForex.getCurrency1(), optionForex.getCurrency2(), expiryTime, strike, forward); final BlackFunctionData dataBlack = new BlackFunctionData(forward, dfDelivery, volatility); final EuropeanVanillaOption option = new EuropeanVanillaOption(strike, expiryTime, !optionForex.isCall()); final double[] priceAdjoint = BLACK_FUNCTION.getPriceAdjoint(option, dataBlack); final double sign = (optionForex.isLong() ? 1.0 : -1.0); final double price = priceAdjoint[0] * Math.abs(optionForex.getUnderlyingNDF().getNotionalCurrency1()) * sign; final double deltaSpot = priceAdjoint[1] * dfNonDelivery / dfDelivery; final CurrencyAmount[] currencyExposure = new CurrencyAmount[2]; currencyExposure[0] = CurrencyAmount.of(optionForex.getCurrency1(), deltaSpot * Math.abs(optionForex.getUnderlyingNDF().getNotionalCurrency1()) * sign); currencyExposure[1] = CurrencyAmount.of(optionForex.getCurrency2(), -deltaSpot * Math.abs(optionForex.getUnderlyingNDF().getNotionalCurrency1()) * spot * sign + price); return MultipleCurrencyAmount.of(currencyExposure); } private  ForexNonDeliverableOptionBlackSmileMethod(); static ForexNonDeliverableOptionBlackSmileMethod getInstance(); MultipleCurrencyAmount presentValue(final ForexNonDeliverableOption optionForex, final BlackForexSmileProviderInterface smileMulticurves); MultipleCurrencyAmount currencyExposure(final ForexNonDeliverableOption optionForex, final BlackForexSmileProviderInterface smileMulticurves); double forwardForexRate(final ForexNonDeliverableOption ndo, final MulticurveProviderInterface multicurves); MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final ForexNonDeliverableOption optionForex, final BlackForexSmileProviderInterface smileMulticurves); PresentValueForexBlackVolatilitySensitivity presentValueBlackVolatilitySensitivity(final ForexNonDeliverableOption optionForex, final BlackForexSmileProviderInterface smileMulticurves); PresentValueForexBlackVolatilityNodeSensitivityDataBundle presentValueVolatilityNodeSensitivity(final ForexNonDeliverableOption optionForex,
      final BlackForexSmileProviderInterface smileMulticurves);  }
@Test public void currencyExposureMethodVsCalculator() { final MultipleCurrencyAmount ceMethod = METHOD_NDO.currencyExposure(NDO, SMILE_MULTICURVES); final MultipleCurrencyAmount ceCalculator = NDO.accept(CEFBC, SMILE_MULTICURVES); assertEquals("Forex non-deliverable option: currency exposure", ceMethod, ceCalculator); }