CouponIborCompoundingSpreadDiscountingMethod { public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CouponIborCompoundingSpread coupon, final MulticurveProviderInterface multicurve) { ArgumentChecker.notNull(coupon, "Coupon"); ArgumentChecker.notNull(multicurve, "Multi-curve provider"); final int nbSubPeriod = coupon.getFixingTimes().length; double notionalAccrued = coupon.getNotionalAccrued(); final double[] forward = new double[nbSubPeriod]; final double[] investFactor = new double[nbSubPeriod]; for (int loopsub = 0; loopsub < nbSubPeriod; loopsub++) { forward[loopsub] = multicurve.getSimplyCompoundForwardRate(coupon.getIndex(), coupon.getFixingPeriodStartTimes()[loopsub], coupon.getFixingPeriodEndTimes()[loopsub], coupon.getFixingPeriodAccrualFactors()[loopsub]); investFactor[loopsub] = 1.0 + coupon.getPaymentAccrualFactors()[loopsub] * (forward[loopsub] + coupon.getSpread()); notionalAccrued *= investFactor[loopsub]; } final double dfPayment = multicurve.getDiscountFactor(coupon.getCurrency(), coupon.getPaymentTime()); final double pvBar = 1.0; final double dfPaymentBar = (notionalAccrued - coupon.getNotional()) * pvBar; final double notionalAccruedBar = dfPayment * pvBar; final double[] investFactorBar = new double[nbSubPeriod]; final double[] forwardBar = new double[nbSubPeriod]; for (int loopsub = 0; loopsub < nbSubPeriod; loopsub++) { investFactorBar[loopsub] = notionalAccrued / investFactor[loopsub] * notionalAccruedBar; forwardBar[loopsub] = coupon.getPaymentAccrualFactors()[loopsub] * investFactorBar[loopsub]; } final Map<String, List<DoublesPair>> mapDsc = new HashMap<>(); final List<DoublesPair> listDiscounting = new ArrayList<>(); listDiscounting.add(DoublesPair.of(coupon.getPaymentTime(), -coupon.getPaymentTime() * dfPayment * dfPaymentBar)); 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  CouponIborCompoundingSpreadDiscountingMethod(); static CouponIborCompoundingSpreadDiscountingMethod getInstance(); MultipleCurrencyAmount presentValue(final CouponIborCompoundingSpread coupon, final MulticurveProviderInterface multicurve); MultipleCurrencyAmount presentValue(
      final CouponIborCompoundingSpread coupon,
      final MulticurveProviderInterface multicurve,
      final ForwardRateProvider<IborIndex> forwardRateProvider); MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CouponIborCompoundingSpread 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("CashDiscountingProviderMethod: 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("CouponIborCompoundedDiscounting: Present value curve sensitivity", pvcsMethod, pvcsCalculator, TOLERANCE_PV_DELTA); }