SwaptionPhysicalFixedIborHullWhiteMethod { public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final SwaptionPhysicalFixedIbor swaption, final HullWhiteOneFactorProviderInterface hullWhite) { ArgumentChecker.notNull(swaption, "Swaption"); ArgumentChecker.notNull(hullWhite, "Hull-White provider"); final Currency ccy = swaption.getCurrency(); final int nbSigma = hullWhite.getHullWhiteParameters().getVolatility().length; final AnnuityPaymentFixed cfe = swaption.getUnderlyingSwap().accept(CFEC, hullWhite.getMulticurveProvider()); final double expiryTime = swaption.getTimeToExpiry(); final double[] alpha = new double[cfe.getNumberOfPayments()]; final double[][] alphaDerivatives = new double[cfe.getNumberOfPayments()][nbSigma]; final double[] df = new double[cfe.getNumberOfPayments()]; final double[] discountedCashFlow = new double[cfe.getNumberOfPayments()]; for (int loopcf = 0; loopcf < cfe.getNumberOfPayments(); loopcf++) { alpha[loopcf] = MODEL.alpha(hullWhite.getHullWhiteParameters(), 0.0, expiryTime, expiryTime, cfe.getNthPayment(loopcf).getPaymentTime(), alphaDerivatives[loopcf]); df[loopcf] = hullWhite.getMulticurveProvider().getDiscountFactor(swaption.getCurrency(), cfe.getNthPayment(loopcf).getPaymentTime()); discountedCashFlow[loopcf] = df[loopcf] * cfe.getNthPayment(loopcf).getAmount(); } final double kappa = MODEL.kappa(discountedCashFlow, alpha); final double omega = (swaption.getUnderlyingSwap().getFixedLeg().isPayer() ? -1.0 : 1.0); final double[] ncdf = new double[cfe.getNumberOfPayments()]; for (int loopcf = 0; loopcf < cfe.getNumberOfPayments(); loopcf++) { ncdf[loopcf] = NORMAL.getCDF(omega * (kappa + alpha[loopcf])); } final double pvBar = 1.0; final double[] discountedCashFlowBar = new double[cfe.getNumberOfPayments()]; final double[] dfBar = new double[cfe.getNumberOfPayments()]; final double[] cfeAmountBar = new double[cfe.getNumberOfPayments()]; final List<DoublesPair> listDfSensi = new ArrayList<>(); for (int loopcf = 0; loopcf < cfe.getNumberOfPayments(); loopcf++) { discountedCashFlowBar[loopcf] = ncdf[loopcf] * pvBar; dfBar[loopcf] = cfe.getNthPayment(loopcf).getAmount() * discountedCashFlowBar[loopcf]; cfeAmountBar[loopcf] = df[loopcf] * discountedCashFlowBar[loopcf]; final DoublesPair dfSensi = DoublesPair.of(cfe.getNthPayment(loopcf).getPaymentTime(), -cfe.getNthPayment(loopcf).getPaymentTime() * df[loopcf] * dfBar[loopcf]); listDfSensi.add(dfSensi); } final Map<String, List<DoublesPair>> pvsDF = new HashMap<>(); pvsDF.put(hullWhite.getMulticurveProvider().getName(ccy), listDfSensi); MulticurveSensitivity sensitivity = MulticurveSensitivity.ofYieldDiscounting(pvsDF); final Map<Double, MulticurveSensitivity> cfeCurveSensi = swaption.getUnderlyingSwap().accept(CFECSC, hullWhite.getMulticurveProvider()); for (int loopcf = 0; loopcf < cfe.getNumberOfPayments(); loopcf++) { final MulticurveSensitivity sensiCfe = cfeCurveSensi.get(cfe.getNthPayment(loopcf).getPaymentTime()); if (!(sensiCfe == null)) { sensitivity = sensitivity.plus(sensiCfe.multipliedBy(cfeAmountBar[loopcf])); } } if (!swaption.isLong()) { return MultipleCurrencyMulticurveSensitivity.of(ccy, sensitivity.multipliedBy(-1.0)); } return MultipleCurrencyMulticurveSensitivity.of(ccy, sensitivity); } private  SwaptionPhysicalFixedIborHullWhiteMethod(); static SwaptionPhysicalFixedIborHullWhiteMethod getInstance(); MultipleCurrencyAmount presentValue(final SwaptionPhysicalFixedIbor swaption, final HullWhiteOneFactorProviderInterface hullWhite); MultipleCurrencyAmount presentValue(final SwaptionPhysicalFixedIbor swaption, final AnnuityPaymentFixed cfe, final HullWhiteOneFactorProviderInterface hullWhite); double[] presentValueHullWhiteSensitivity(final SwaptionPhysicalFixedIbor swaption, final HullWhiteOneFactorProviderInterface hullWhite); MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final SwaptionPhysicalFixedIbor swaption, final HullWhiteOneFactorProviderInterface hullWhite);  }
@Test public void presentValueCurveSensitivity() { final MultipleCurrencyParameterSensitivity pvpsExact = PS_HW_C.calculateSensitivity(SWAPTION_SHORT_RECEIVER, HW_MULTICURVES, HW_MULTICURVES.getMulticurveProvider().getAllNames()); final MultipleCurrencyParameterSensitivity pvpsFD = PS_HW_FDC.calculateSensitivity(SWAPTION_SHORT_RECEIVER, HW_MULTICURVES); AssertSensitivityObjects.assertEquals("SwaptionPhysicalFixedIborSABRMethod: presentValueCurveSensitivity ", pvpsExact, pvpsFD, TOLERANCE_PV_DELTA); }
@Test public void presentValueCurveSensitivityLongShortParityExplicit() { final MultipleCurrencyMulticurveSensitivity pvhwsLong = METHOD_HW.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES); final MultipleCurrencyMulticurveSensitivity pvhwsShort = METHOD_HW.presentValueCurveSensitivity(SWAPTION_SHORT_PAYER, HW_MULTICURVES); AssertSensitivityObjects.assertEquals("Swaption physical - Hull-White - presentValueCurveSensitivity - long/short parity", pvhwsLong, pvhwsShort.multipliedBy(-1.0), TOLERANCE_PV_DELTA); }
@Test public void presentValueCurveSensitivityPayerReceiverParityExplicit() { final MultipleCurrencyMulticurveSensitivity pvhwsReceiverLong = METHOD_HW.presentValueCurveSensitivity(SWAPTION_LONG_RECEIVER, HW_MULTICURVES); final MultipleCurrencyMulticurveSensitivity pvhwsPayerShort = METHOD_HW.presentValueCurveSensitivity(SWAPTION_SHORT_PAYER, HW_MULTICURVES); final MultipleCurrencyMulticurveSensitivity pvSwap = SWAP_RECEIVER.accept(PVCSDC, MULTICURVES); AssertSensitivityObjects.assertEquals("Swaption physical - Hull-White - presentValueCurveSensitivity - payer/receiver/swap parity", pvSwap.cleaned(TOLERANCE_PV_DELTA), pvhwsReceiverLong.plus(pvhwsPayerShort).cleaned(TOLERANCE_PV_DELTA), TOLERANCE_PV_DELTA); }
@Test public void presentValueCurveSensitivityMonteCarlo() { final double toleranceDelta = 1.0E+6; final MultipleCurrencyMulticurveSensitivity pvcsExplicit = METHOD_HW.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, HW_MULTICURVES).cleaned(TOLERANCE_PV_DELTA); final HullWhiteMonteCarloMethod methodMC = new HullWhiteMonteCarloMethod(new NormalRandomNumberGenerator(0.0, 1.0, new MersenneTwister()), NB_PATH); final MultipleCurrencyMulticurveSensitivity pvcsMC = methodMC.presentValueCurveSensitivity(SWAPTION_LONG_PAYER, EUR, HW_MULTICURVES).cleaned(TOLERANCE_PV_DELTA); AssertSensitivityObjects.assertEquals("Swaption physical - Hull-White - presentValueCurveSensitivity - payer/receiver/swap parity", pvcsExplicit, pvcsMC, toleranceDelta); }