ArgumentChecker.notNull(swaption, "Swaption");
ArgumentChecker.notNull(sabrData, "SABR swaption provider");
final Currency ccy = swaption.getCurrency();
final MulticurveProviderInterface multicurves = sabrData.getMulticurveProvider();
//TODO: Create a way to chose the LMM base parameters (displacement, mean reversion, volatility).
final LiborMarketModelDisplacedDiffusionParameters lmmParameters = LiborMarketModelDisplacedDiffusionParameters.from(swaption, DEFAULT_DISPLACEMENT, DEFAULT_MEAN_REVERSION, new VolatilityLMMAngle(
DEFAULT_ANGLE, DEFAULT_DISPLACEMENT));
final SuccessiveRootFinderLMMDDCalibrationObjective objective = new SuccessiveRootFinderLMMDDCalibrationObjective(lmmParameters, ccy);
final SuccessiveRootFinderLMMDDCalibrationEngine<SABRSwaptionProviderInterface> calibrationEngine = new SuccessiveRootFinderLMMDDCalibrationEngine<>(objective);
final SwaptionPhysicalFixedIbor[] swaptionCalibration = METHOD_BASKET.calibrationBasketFixedLegPeriod(swaption);
calibrationEngine.addInstrument(swaptionCalibration, PVSSC);
calibrationEngine.calibrate(sabrData);
final LiborMarketModelDisplacedDiffusionProviderInterface lmm = new LiborMarketModelDisplacedDiffusionProvider(multicurves, lmmParameters, ccy);
// Risks
final int nbCal = swaptionCalibration.length;
final int nbFact = lmmParameters.getNbFactor();
final List<Integer> instrumentIndex = calibrationEngine.getInstrumentIndex();
final double[] dPvAmdLambda = new double[nbCal];
final double[][][] dPvCaldGamma = new double[nbCal][][];
final double[][] dPvCaldLambda = new double[nbCal][nbCal];
final PresentValueSABRSensitivityDataBundle[] dPvCaldSABR = new PresentValueSABRSensitivityDataBundle[nbCal];
MultipleCurrencyMulticurveSensitivity pvcsCal = METHOD_SWAPTION_LMM.presentValueCurveSensitivity(swaption, lmm);
pvcsCal = pvcsCal.cleaned();
final double[][] dPvAmdGamma = METHOD_SWAPTION_LMM.presentValueLMMSensitivity(swaption, lmm);
for (int loopcal = 0; loopcal < nbCal; loopcal++) {
dPvCaldGamma[loopcal] = METHOD_SWAPTION_LMM.presentValueLMMSensitivity(swaptionCalibration[loopcal], lmm);
}
// Multiplicative-factor sensitivity
for (int loopcal = 0; loopcal < nbCal; loopcal++) {
for (int loopperiod = instrumentIndex.get(loopcal); loopperiod < instrumentIndex.get(loopcal + 1); loopperiod++) {
for (int loopfact = 0; loopfact < nbFact; loopfact++) {
dPvAmdLambda[loopcal] += dPvAmdGamma[loopperiod][loopfact] * lmmParameters.getVolatility()[loopperiod][loopfact];
}
}
}
for (int loopcal1 = 0; loopcal1 < nbCal; loopcal1++) {
for (int loopcal2 = 0; loopcal2 < nbCal; loopcal2++) {
for (int loopperiod = instrumentIndex.get(loopcal2); loopperiod < instrumentIndex.get(loopcal2 + 1); loopperiod++) {
for (int loopfact = 0; loopfact < nbFact; loopfact++) {
dPvCaldLambda[loopcal1][loopcal2] += dPvCaldGamma[loopcal1][loopperiod][loopfact] * lmmParameters.getVolatility()[loopperiod][loopfact];
}
}
}
}
final MultipleCurrencyMulticurveSensitivity[] pvcsCalBase = new MultipleCurrencyMulticurveSensitivity[nbCal];