ForexNonDeliverableOptionBlackSmileMethod { public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(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 sign = (optionForex.isLong() ? 1.0 : -1.0); 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, 1.0, volatility); final EuropeanVanillaOption option = new EuropeanVanillaOption(strike, expiryTime, !optionForex.isCall()); final double[] priceAdjoint = BLACK_FUNCTION.getPriceAdjoint(option, dataBlack); final double priceBar = sign; final double forwardBar = priceAdjoint[1] * dfDelivery * priceBar; final double dfNonDeliveryBar = spot / dfDelivery * forwardBar; final double dfDeliveryBar = -spot / (dfDelivery * dfDelivery) * dfNonDelivery * forwardBar + priceAdjoint[0] * priceBar; final double rNonDeliveryBar = -paymentTime * dfNonDelivery * dfNonDeliveryBar; final double rDeliveryBar = -paymentTime * dfDelivery * dfDeliveryBar; final Map<String, List<DoublesPair>> resultMap = new HashMap<>(); final List<DoublesPair> listNonDelivery = new ArrayList<>(); listNonDelivery.add(DoublesPair.of(paymentTime, rNonDeliveryBar * Math.abs(optionForex.getUnderlyingNDF().getNotionalCurrency1()))); resultMap.put(multicurves.getName(optionForex.getCurrency1()), listNonDelivery); final List<DoublesPair> listDelivery = new ArrayList<>(); listDelivery.add(DoublesPair.of(paymentTime, rDeliveryBar * Math.abs(optionForex.getUnderlyingNDF().getNotionalCurrency1()))); resultMap.put(multicurves.getName(optionForex.getCurrency2()), listDelivery); final MulticurveSensitivity result = MulticurveSensitivity.ofYieldDiscounting(resultMap); return MultipleCurrencyMulticurveSensitivity.of(optionForex.getCurrency2(), result); } 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 presentValueCurveSensitivity() { final double tolerance = 1.0E-2; final MultipleCurrencyMulticurveSensitivity pvcsNDO = METHOD_NDO.presentValueCurveSensitivity(NDO, SMILE_MULTICURVES).cleaned(); final MultipleCurrencyMulticurveSensitivity pvcsFXO = METHOD_FXO.presentValueCurveSensitivity(FOREX_OPT, SMILE_MULTICURVES).cleaned(); AssertSensitivityObjects.assertEquals("Forex non-deliverable option: present value curve sensitivity", pvcsFXO, pvcsNDO, tolerance); }