CapFloorIborBlackSmileMethod { public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CapFloorIbor cap, final BlackSmileCapProviderInterface black) { ArgumentChecker.notNull(cap, "The cap/floor shoud not be null"); ArgumentChecker.notNull(black, "Black provider"); final MulticurveProviderInterface multicurve = black.getMulticurveProvider(); final EuropeanVanillaOption option = new EuropeanVanillaOption(cap.getStrike(), cap.getFixingTime(), cap.isCap()); final double forward = multicurve.getSimplyCompoundForwardRate(cap.getIndex(), cap.getFixingPeriodStartTime(), cap.getFixingPeriodEndTime(), cap.getFixingAccrualFactor()); final double df = multicurve.getDiscountFactor(cap.getCurrency(), cap.getPaymentTime()); final MulticurveSensitivity forwardDr = MulticurveSensitivity.ofForward(multicurve.getName(cap.getIndex()), new SimplyCompoundedForwardSensitivity(cap.getFixingPeriodStartTime(), cap.getFixingPeriodEndTime(), cap.getFixingAccrualFactor(), 1.0)); final double dfDr = -cap.getPaymentTime() * df; final double volatility = black.getBlackParameters().getVolatility(cap.getFixingTime(), cap.getStrike()); final BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatility); final double[] bsAdjoint = BLACK_FUNCTION.getPriceAdjoint(option, dataBlack); final List<DoublesPair> list = new ArrayList<>(); list.add(DoublesPair.of(cap.getPaymentTime(), dfDr)); final Map<String, List<DoublesPair>> resultMap = new HashMap<>(); resultMap.put(multicurve.getName(cap.getCurrency()), list); MulticurveSensitivity result = MulticurveSensitivity.ofYieldDiscounting(resultMap); result = result.multipliedBy(bsAdjoint[0]); result = result.plus(forwardDr.multipliedBy(df * bsAdjoint[1])); result = result.multipliedBy(cap.getNotional() * cap.getPaymentYearFraction()); return MultipleCurrencyMulticurveSensitivity.of(cap.getCurrency(), result); } private  CapFloorIborBlackSmileMethod(); static CapFloorIborBlackSmileMethod getInstance(); MultipleCurrencyAmount presentValue(final CapFloorIbor cap, final BlackSmileCapProviderInterface black); MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CapFloorIbor cap, final BlackSmileCapProviderInterface black);  }
@Test public void presentValueCurveSensitivityMethodVsCalculator() { final MultipleCurrencyMulticurveSensitivity pvcsMethod = METHOD_CAP_BLACK.presentValueCurveSensitivity(CAP_LONG, BLACK_MULTICURVES); final MultipleCurrencyMulticurveSensitivity pvcsCalculator = CAP_LONG.accept(PVCSBSCC, BLACK_MULTICURVES); assertEquals("Cap/floor SABR: Present value SABR sensitivity: method vs calculator", pvcsMethod, pvcsCalculator); }