CapFloorCMSSABRReplicationMethod extends CapFloorCMSSABRReplicationAbstractMethod { @Override public MultipleCurrencyAmount presentValue(final CapFloorCMS cmsCapFloor, final SABRSwaptionProviderInterface sabrData) { ArgumentChecker.notNull(cmsCapFloor, "CMA cap/floor"); ArgumentChecker.notNull(sabrData, "SABR swaption provider"); final Currency ccy = cmsCapFloor.getCurrency(); final SABRInterestRateParameters sabrParameter = sabrData.getSABRParameter(); final SwapFixedCoupon<? extends Payment> underlyingSwap = cmsCapFloor.getUnderlyingSwap(); final double forward = underlyingSwap.accept(PRDC, sabrData.getMulticurveProvider()); final double discountFactor = sabrData.getMulticurveProvider().getDiscountFactor(ccy, cmsCapFloor.getPaymentTime()); final CMSIntegrant integrant = new CMSIntegrant(cmsCapFloor, sabrParameter, forward); final double strike = cmsCapFloor.getStrike(); final double strikePart = discountFactor * integrant.g(forward) / integrant.h(forward) * integrant.k(strike) * integrant.bs(strike); final double absoluteTolerance = 0.1 / (discountFactor * Math.abs(cmsCapFloor.getNotional()) * cmsCapFloor.getPaymentYearFraction()); final double relativeTolerance = 1.0E-6; final RungeKuttaIntegrator1D integrator = new RungeKuttaIntegrator1D(absoluteTolerance, relativeTolerance, getNbIteration()); double integralPart; try { if (cmsCapFloor.isCap()) { integralPart = discountFactor * integrator.integrate(integrant, strike, strike + getIntegrationInterval()); } else { integralPart = discountFactor * integrator.integrate(integrant, 0.0, strike); } } catch (final Exception e) { throw new MathException(e); } final double priceCMS = (strikePart + integralPart) * cmsCapFloor.getNotional() * cmsCapFloor.getPaymentYearFraction(); return MultipleCurrencyAmount.of(cmsCapFloor.getCurrency(), priceCMS); } private  CapFloorCMSSABRReplicationMethod();  CapFloorCMSSABRReplicationMethod(final double integrationInterval); static CapFloorCMSSABRReplicationMethod getDefaultInstance(); @Override MultipleCurrencyAmount presentValue(final CapFloorCMS cmsCapFloor, final SABRSwaptionProviderInterface sabrData); @Override @SuppressWarnings("synthetic-access") MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CapFloorCMS cmsCapFloor, final SABRSwaptionProviderInterface sabrData); @Override PresentValueSABRSensitivityDataBundle presentValueSABRSensitivity(final CapFloorCMS cmsCapFloor, final SABRSwaptionProviderInterface sabrData); @Override double presentValueStrikeSensitivity(final CapFloorCMS cmsCapFloor, final SABRSwaptionProviderInterface sabrData);  }
@Test public void presentValueMethodVsCalculator() { final double pvMethod = METHOD_CAP_CMS_SABR.presentValue(CMS_CAP, SABR_MULTICURVES).getAmount(EUR); final double pvCalculator = PVSSC.visit(CMS_CAP, SABR_MULTICURVES).getAmount(EUR); assertEquals("CMS cap/floor SABR: Present value : method vs calculator", pvMethod, pvCalculator, TOLERANCE_PV); }