ForexNonDeliverableOptionBlackSmileMethod { public MultipleCurrencyAmount presentValue(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 Function1D<BlackFunctionData, Double> func = BLACK_FUNCTION.getPriceFunction(option); final double price = func.evaluate(dataBlack) * Math.abs(optionForex.getUnderlyingNDF().getNotionalCurrency1()) * (optionForex.isLong() ? 1.0 : -1.0); final CurrencyAmount priceCurrency = CurrencyAmount.of(optionForex.getCurrency2(), price); return MultipleCurrencyAmount.of(priceCurrency); } 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 presentValue() { final MultipleCurrencyAmount pvNDO = METHOD_NDO.presentValue(NDO, SMILE_MULTICURVES); final MultipleCurrencyAmount pvFXO = METHOD_FXO.presentValue(FOREX_OPT, SMILE_MULTICURVES); assertEquals("Forex non-deliverable option: present value", pvFXO, pvNDO); }
@Test public void presentValueMethodVsCalculator() { final MultipleCurrencyAmount pvMethod = METHOD_NDO.presentValue(NDO, SMILE_MULTICURVES); final MultipleCurrencyAmount pvCalculator = NDO.accept(PVFBC, SMILE_MULTICURVES); assertEquals("Forex non-deliverable option: present value", pvMethod, pvCalculator); }