CouponONArithmeticAverageDiscountingMethod { public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CouponONArithmeticAverage coupon, final MulticurveProviderInterface multicurve) { ArgumentChecker.notNull(coupon, "Coupon"); ArgumentChecker.notNull(multicurve, "Multi-curve provider"); final double[] delta = coupon.getFixingPeriodAccrualFactors(); final double[] startTimes = coupon.getFixingPeriodStartTimes(); final double[] endTimes = coupon.getFixingPeriodEndTimes(); ; final int nbFwd = delta.length; final double[] forwardON = new double[nbFwd]; double rateAccrued = coupon.getRateAccrued(); for (int loopfwd = 0; loopfwd < nbFwd; loopfwd++) { forwardON[loopfwd] = multicurve.getSimplyCompoundForwardRate(coupon.getIndex(), startTimes[loopfwd], endTimes[loopfwd], delta[loopfwd]); rateAccrued += forwardON[loopfwd] * delta[loopfwd]; } final double df = multicurve.getDiscountFactor(coupon.getCurrency(), coupon.getPaymentTime()); final double pvBar = 1.0; final double dfBar = rateAccrued * coupon.getNotional() * pvBar; final double rateAccruedBar = df * coupon.getNotional() * pvBar; final double[] forwardONBar = new double[nbFwd]; for (int loopfwd = 0; loopfwd < nbFwd; loopfwd++) { forwardONBar[loopfwd] = delta[loopfwd] * rateAccruedBar; } final Map<String, List<DoublesPair>> mapDsc = new HashMap<>(); final List<DoublesPair> listDiscounting = new ArrayList<>(); listDiscounting.add(DoublesPair.of(coupon.getPaymentTime(), -coupon.getPaymentTime() * df * dfBar)); mapDsc.put(multicurve.getName(coupon.getCurrency()), listDiscounting); final Map<String, List<ForwardSensitivity>> mapFwd = new HashMap<>(); final List<ForwardSensitivity> listForward = new ArrayList<>(); for (int loopfwd = 0; loopfwd < nbFwd; loopfwd++) { listForward.add(new SimplyCompoundedForwardSensitivity(startTimes[loopfwd], endTimes[loopfwd], delta[loopfwd], forwardONBar[loopfwd])); } mapFwd.put(multicurve.getName(coupon.getIndex()), listForward); final MultipleCurrencyMulticurveSensitivity result = MultipleCurrencyMulticurveSensitivity.of(coupon.getCurrency(), MulticurveSensitivity.of(mapDsc, mapFwd)); return result; } private  CouponONArithmeticAverageDiscountingMethod(); static CouponONArithmeticAverageDiscountingMethod getInstance(); MultipleCurrencyAmount presentValue(final CouponONArithmeticAverage coupon, final MulticurveProviderInterface multicurve); MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CouponONArithmeticAverage coupon, final MulticurveProviderInterface multicurve);  }
@Test public void presentValueCurveSensitivityApproxMethodVsCalculator() { final MultipleCurrencyMulticurveSensitivity pvcs3MMethod = METHOD_FF_APPRO.presentValueCurveSensitivity(FEDFUND_CPN_3M, MULTICURVES); final MultipleCurrencyMulticurveSensitivity pvcs3MCalc = FEDFUND_CPN_3M.accept(PVCSDC, MULTICURVES); AssertSensitivityObjects.assertEquals("CouponArithmeticAverageONDiscountingMethod: present value", pvcs3MMethod, pvcs3MCalc, TOLERANCE_PV_DELTA); }