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 annuity with respect to the forward.
final double pvbpDf = METHOD_SWAP.getAnnuityCashDerivative(swaption.getUnderlyingSwap(), forward);
final double discountFactorSettle = multicurves.getDiscountFactor(ccy, swaption.getSettlementTime());
final double maturity = annuityFixed.getNthPayment(annuityFixed.getNumberOfPayments() - 1).getPaymentTime() - swaption.getSettlementTime();
// Implementation note: option required to pass the strike (in case the swap has non-constant coupon).
final double dfDr = -swaption.getSettlementTime() * discountFactorSettle;
final List<DoublesPair> list = new ArrayList<>();
list.add(new DoublesPair(swaption.getSettlementTime(), dfDr));
final Map<String, List<DoublesPair>> resultMap = new HashMap<>();
resultMap.put(multicurves.getName(ccy), list);
MulticurveSensitivity result = MulticurveSensitivity.ofYieldDiscounting(resultMap);
final DoublesPair expiryMaturity = new DoublesPair(swaption.getTimeToExpiry(), maturity);
final double alpha = sabrData.getSABRParameter().getAlpha(expiryMaturity);
final double beta = sabrData.getSABRParameter().getBeta(expiryMaturity);
final double rho = sabrData.getSABRParameter().getRho(expiryMaturity);
final double nu = sabrData.getSABRParameter().getNu(expiryMaturity);
final SABRFormulaData sabrParam = new SABRFormulaData(alpha, beta, rho, nu);
final SABRExtrapolationRightFunction sabrExtrapolation = new SABRExtrapolationRightFunction(forward, sabrParam, _cutOffStrike, swaption.getTimeToExpiry(), _mu);
final double price = sabrExtrapolation.price(swaption);
result = result.multipliedBy(pvbp * price);
result = result.plus(forwardDr.multipliedBy(discountFactorSettle * (pvbpDf * price + pvbp * sabrExtrapolation.priceDerivativeForward(swaption))));
if (!swaption.isLong()) {
result = result.multipliedBy(-1);
}
return MultipleCurrencyMulticurveSensitivity.of(ccy, result);
}