final MulticurveProviderInterface multicurves = sabrData.getMulticurveProvider();
final Currency ccy = swaption.getCurrency();
final AnnuityCouponFixed annuityFixed = swaption.getUnderlyingSwap().getFixedLeg();
final double forward = swaption.getUnderlyingSwap().accept(PRDC, multicurves);
// Derivative of the forward with respect to the rates.
final MulticurveSensitivity forwardDr = swaption.getUnderlyingSwap().accept(PRCSDC, multicurves);
final double pvbp = METHOD_SWAP.getAnnuityCash(swaption.getUnderlyingSwap(), forward);
// Derivative of the cash annuity with respect to the forward.
final double pvbpDf = METHOD_SWAP.getAnnuityCashDerivative(swaption.getUnderlyingSwap(), forward);
// Implementation note: strictly speaking, the strike equivalent is curve dependent; that dependency is ignored.
final double maturity = annuityFixed.getNthPayment(annuityFixed.getNumberOfPayments() - 1).getPaymentTime() - swaption.getSettlementTime();
final BlackPriceFunction blackFunction = new BlackPriceFunction();
final double[] volatilityAdjoint = sabrData.getSABRParameter().getVolatilityAdjoint(swaption.getTimeToExpiry(), maturity, swaption.getStrike(), forward);
final double discountFactorSettle = multicurves.getDiscountFactor(ccy, swaption.getSettlementTime());
final BlackFunctionData dataBlack = new BlackFunctionData(forward, 1.0, volatilityAdjoint[0]);
final double[] bsAdjoint = blackFunction.getPriceAdjoint(swaption, dataBlack);
final double sensiDF = -swaption.getSettlementTime() * discountFactorSettle * pvbp * bsAdjoint[0];
final List<DoublesPair> list = new ArrayList<>();
list.add(new DoublesPair(swaption.getSettlementTime(), sensiDF));
final Map<String, List<DoublesPair>> resultMap = new HashMap<>();
resultMap.put(multicurves.getName(ccy), list);
MulticurveSensitivity result = MulticurveSensitivity.ofYieldDiscounting(resultMap);
result = result.plus(forwardDr.multipliedBy(discountFactorSettle * (pvbpDf * bsAdjoint[0] + pvbp * (bsAdjoint[1] + bsAdjoint[2] * volatilityAdjoint[1]))));
if (!swaption.isLong()) {
result = result.multipliedBy(-1);
}
return MultipleCurrencyMulticurveSensitivity.of(ccy, result);
}