CouponIborCompoundingFlatSpreadDiscountingMethod { public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CouponIborCompoundingFlatSpread coupon, final MulticurveProviderInterface multicurve) { ArgumentChecker.notNull(coupon, "Coupon"); ArgumentChecker.notNull(multicurve, "Multi-curve provider"); final int nbSubPeriod = coupon.getFixingTimes().length; final double[] cpa = new double[nbSubPeriod + 1]; final double[] cpaAccumulated = new double[nbSubPeriod + 1]; final double[] forward = new double[nbSubPeriod]; cpa[0] = coupon.getCompoundingPeriodAmountAccumulated(); cpaAccumulated[0] = coupon.getCompoundingPeriodAmountAccumulated(); for (int loopsub = 0; loopsub < nbSubPeriod; loopsub++) { forward[loopsub] = multicurve.getSimplyCompoundForwardRate(coupon.getIndex(), coupon.getFixingPeriodStartTimes()[loopsub], coupon.getFixingPeriodEndTimes()[loopsub], coupon.getFixingPeriodAccrualFactors()[loopsub]); cpa[loopsub + 1] += coupon.getNotional() * (forward[loopsub] + coupon.getSpread()) * coupon.getSubperiodsAccrualFactors()[loopsub]; cpa[loopsub + 1] += cpaAccumulated[loopsub] * forward[loopsub] * coupon.getSubperiodsAccrualFactors()[loopsub]; cpaAccumulated[loopsub + 1] = cpaAccumulated[loopsub] + cpa[loopsub + 1]; } final double df = multicurve.getDiscountFactor(coupon.getCurrency(), coupon.getPaymentTime()); final double pvBar = 1.0; final double dfBar = cpaAccumulated[nbSubPeriod] * pvBar; final double[] cpaAccumulatedBar = new double[nbSubPeriod + 1]; cpaAccumulatedBar[nbSubPeriod] = df * pvBar; final double[] cpaBar = new double[nbSubPeriod + 1]; final double[] forwardBar = new double[nbSubPeriod]; for (int loopsub = nbSubPeriod - 1; loopsub >= 0; loopsub--) { cpaAccumulatedBar[loopsub] = cpaAccumulatedBar[loopsub + 1]; cpaBar[loopsub + 1] += cpaAccumulatedBar[loopsub + 1]; cpaAccumulatedBar[loopsub] += forward[loopsub] * coupon.getSubperiodsAccrualFactors()[loopsub] * cpaBar[loopsub + 1]; forwardBar[loopsub] += cpaAccumulated[loopsub] * coupon.getSubperiodsAccrualFactors()[loopsub] * cpaBar[loopsub + 1]; forwardBar[loopsub] += coupon.getNotional() * coupon.getSubperiodsAccrualFactors()[loopsub] * cpaBar[loopsub + 1]; } 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 loopsub = 0; loopsub < nbSubPeriod; loopsub++) { listForward.add(new SimplyCompoundedForwardSensitivity(coupon.getFixingPeriodStartTimes()[loopsub], coupon.getFixingPeriodEndTimes()[loopsub], coupon.getFixingPeriodAccrualFactors()[loopsub], forwardBar[loopsub])); } mapFwd.put(multicurve.getName(coupon.getIndex()), listForward); return MultipleCurrencyMulticurveSensitivity.of(coupon.getCurrency(), MulticurveSensitivity.of(mapDsc, mapFwd)); } private  CouponIborCompoundingFlatSpreadDiscountingMethod(); static CouponIborCompoundingFlatSpreadDiscountingMethod getInstance(); MultipleCurrencyAmount presentValue(final CouponIborCompoundingFlatSpread coupon, final MulticurveProviderInterface multicurve); MultipleCurrencyAmount presentValue(
      final CouponIborCompoundingFlatSpread coupon,
      final MulticurveProviderInterface multicurve,
      final ForwardRateProvider<IborIndex> forwardRateProvider); double presentValueSpreadSensitivity(final CouponIborCompoundingFlatSpread coupon, final MulticurveProviderInterface multicurve); MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CouponIborCompoundingFlatSpread coupon, final MulticurveProviderInterface multicurve);  }
@Test public void presentValueCurveSensitivity() { final MultipleCurrencyParameterSensitivity pvpsDepositExact = PS_PV_C.calculateSensitivity(CPN_BEFORE, MULTICURVES, MULTICURVES.getAllNames()); final MultipleCurrencyParameterSensitivity pvpsDepositFD = PS_PV_FDC.calculateSensitivity(CPN_BEFORE, MULTICURVES); AssertSensitivityObjects.assertEquals("CouponIborCompoundingFlatSpreadDiscountingMethod: presentValueCurveSensitivity ", pvpsDepositExact, pvpsDepositFD, TOLERANCE_PV_DELTA); }
@Test public void presentValueCurveSensitivityMethodVsCalculator() { final MultipleCurrencyMulticurveSensitivity pvcsMethod = METHOD_COMPOUNDED.presentValueCurveSensitivity(CPN_BEFORE, MULTICURVES); final MultipleCurrencyMulticurveSensitivity pvcsCalculator = CPN_BEFORE.accept(PVCSDC, MULTICURVES); AssertSensitivityObjects.assertEquals("CouponIborCompoundingFlatSpreadDiscountingMethod: Present value curve sensitivity", pvcsMethod, pvcsCalculator, TOLERANCE_PV_DELTA); }