public void test_cashFlowEquivalent_compounding() {
   RatePaymentPeriod iborCmp =
       RatePaymentPeriod.builder()
           .paymentDate(PAYMENT2)
           .accrualPeriods(IBOR1, IBOR2)
           .dayCount(ACT_365F)
           .currency(GBP)
           .notional(-NOTIONAL)
           .build();
   ExpandedSwapLeg iborLegCmp =
       ExpandedSwapLeg.builder().type(IBOR).payReceive(PAY).paymentPeriods(iborCmp).build();
   Swap swap1 = Swap.builder().legs(iborLegCmp, FIXED_LEG).build();
   assertThrowsIllegalArg(
       () -> CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap1.expand(), PROVIDER));
   RatePaymentPeriod fixedCmp =
       RatePaymentPeriod.builder()
           .paymentDate(PAYMENT2)
           .accrualPeriods(FIXED1, FIXED2)
           .dayCount(ACT_365F)
           .currency(GBP)
           .notional(NOTIONAL)
           .build();
   ExpandedSwapLeg fixedLegCmp =
       ExpandedSwapLeg.builder().type(FIXED).payReceive(RECEIVE).paymentPeriods(fixedCmp).build();
   Swap swap2 = Swap.builder().legs(IBOR_LEG, fixedLegCmp).build();
   assertThrowsIllegalArg(
       () -> CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap2.expand(), PROVIDER));
 }
 public void test_cashFlowEquivalent_wrongSwap() {
   Swap swap1 = Swap.builder().legs(IBOR_LEG, FIXED_LEG, IBOR_LEG).build();
   assertThrowsIllegalArg(
       () -> CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap1.expand(), PROVIDER));
   Swap swap2 = Swap.builder().legs(FIXED_LEG, FIXED_LEG).build();
   assertThrowsIllegalArg(
       () -> CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap2.expand(), PROVIDER));
   Swap swap3 =
       Swap.builder()
           .legs(
               FIXED_LEG,
               CashFlowEquivalentCalculator.cashFlowEquivalentIborLeg(IBOR_LEG, PROVIDER))
           .build();
   assertThrowsIllegalArg(
       () -> CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap3.expand(), PROVIDER));
 }
 public void test_cashFlowEquivalent_pv() {
   Swap swap = Swap.builder().legs(IBOR_LEG, FIXED_LEG).build();
   ExpandedSwapLeg cfe =
       CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), PROVIDER);
   DiscountingSwapLegPricer pricerLeg = DiscountingSwapLegPricer.DEFAULT;
   DiscountingSwapProductPricer pricerSwap = DiscountingSwapProductPricer.DEFAULT;
   CurrencyAmount pvCfe = pricerLeg.presentValue(cfe, PROVIDER);
   MultiCurrencyAmount pvSwap = pricerSwap.presentValue(swap, PROVIDER);
   assertEquals(pvCfe.getAmount(), pvSwap.getAmount(GBP).getAmount(), TOLERANCE_PV);
 }
  // -------------------------------------------------------------------------
  public void test_cashFlowEquivalentAndSensitivity() {
    Swap swap = Swap.builder().legs(IBOR_LEG, FIXED_LEG).build();
    ImmutableMap<NotionalExchange, PointSensitivityBuilder> computedFull =
        CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivitySwap(swap.expand(), PROVIDER);
    ImmutableList<NotionalExchange> keyComputedFull = computedFull.keySet().asList();
    ImmutableList<PointSensitivityBuilder> valueComputedFull = computedFull.values().asList();
    ImmutableMap<NotionalExchange, PointSensitivityBuilder> computedIborLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivityIborLeg(
            IBOR_LEG.expand(), PROVIDER);
    ImmutableMap<NotionalExchange, PointSensitivityBuilder> computedFixedLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivityFixedLeg(
            FIXED_LEG.expand(), PROVIDER);
    assertEquals(computedFixedLeg.keySet().asList(), keyComputedFull.subList(0, 2));
    assertEquals(computedIborLeg.keySet().asList(), keyComputedFull.subList(2, 6));
    assertEquals(computedFixedLeg.values().asList(), valueComputedFull.subList(0, 2));
    assertEquals(computedIborLeg.values().asList(), valueComputedFull.subList(2, 6));

    double eps = 1.0e-7;
    RatesFiniteDifferenceSensitivityCalculator calc =
        new RatesFiniteDifferenceSensitivityCalculator(eps);
    int size = keyComputedFull.size();
    for (int i = 0; i < size; ++i) {
      final int index = i;
      CurveCurrencyParameterSensitivities expected =
          calc.sensitivity(
              PROVIDER,
              p ->
                  ((NotionalExchange)
                          CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), p)
                              .getPaymentEvents()
                              .get(index))
                      .getPaymentAmount());
      PointSensitivityBuilder point =
          computedFull.get(
              CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), PROVIDER)
                  .getPaymentEvents()
                  .get(index));
      CurveCurrencyParameterSensitivities computed =
          PROVIDER.curveParameterSensitivity(point.build());
      assertTrue(computed.equalWithTolerance(expected, eps * NOTIONAL));
    }
  }
  public void test_cashFlowEquivalent() {
    Swap swap = Swap.builder().legs(IBOR_LEG, FIXED_LEG).build();
    ExpandedSwapLeg computed =
        CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), PROVIDER);
    ExpandedSwapLeg computedIborLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentIborLeg(IBOR_LEG.expand(), PROVIDER);
    ExpandedSwapLeg computedFixedLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentFixedLeg(FIXED_LEG.expand(), PROVIDER);
    assertEquals(computedFixedLeg.getPaymentEvents(), computed.getPaymentEvents().subList(0, 2));
    assertEquals(computedIborLeg.getPaymentEvents(), computed.getPaymentEvents().subList(2, 6));

    // expected payments from fixed leg
    NotionalExchange fixedPayment1 =
        NotionalExchange.of(PAYMENT1, CurrencyAmount.of(GBP, NOTIONAL * RATE * PAY_YC1));
    NotionalExchange fixedPayment2 =
        NotionalExchange.of(PAYMENT2, CurrencyAmount.of(GBP, NOTIONAL * RATE * PAY_YC2));
    // expected payments from ibor leg
    LocalDate fixingSTART1 = GBP_LIBOR_3M.calculateEffectiveFromFixing(FIXING1);
    double fixedYearFraction1 =
        GBP_LIBOR_3M
            .getDayCount()
            .relativeYearFraction(
                fixingSTART1, GBP_LIBOR_3M.calculateMaturityFromEffective(fixingSTART1));
    double beta1 =
        (1d + fixedYearFraction1 * PROVIDER.iborIndexRates(GBP_LIBOR_3M).rate(FIXING1))
            * PROVIDER.discountFactor(GBP, PAYMENT1)
            / PROVIDER.discountFactor(GBP, fixingSTART1);
    NotionalExchange iborPayment11 =
        NotionalExchange.of(
            fixingSTART1, CurrencyAmount.of(GBP, -NOTIONAL * beta1 * PAY_YC1 / fixedYearFraction1));
    NotionalExchange iborPayment12 =
        NotionalExchange.of(
            PAYMENT1, CurrencyAmount.of(GBP, NOTIONAL * PAY_YC1 / fixedYearFraction1));
    LocalDate fixingSTART2 = GBP_LIBOR_3M.calculateEffectiveFromFixing(FIXING2);
    double fixedYearFraction2 =
        GBP_LIBOR_3M
            .getDayCount()
            .relativeYearFraction(
                fixingSTART2, GBP_LIBOR_3M.calculateMaturityFromEffective(fixingSTART2));
    double beta2 =
        (1d + fixedYearFraction2 * PROVIDER.iborIndexRates(GBP_LIBOR_3M).rate(FIXING2))
            * PROVIDER.discountFactor(GBP, PAYMENT2)
            / PROVIDER.discountFactor(GBP, fixingSTART2);
    NotionalExchange iborPayment21 =
        NotionalExchange.of(
            fixingSTART2, CurrencyAmount.of(GBP, -NOTIONAL * beta2 * PAY_YC2 / fixedYearFraction2));
    NotionalExchange iborPayment22 =
        NotionalExchange.of(
            PAYMENT2, CurrencyAmount.of(GBP, NOTIONAL * PAY_YC2 / fixedYearFraction2));

    ExpandedSwapLeg expected =
        ExpandedSwapLeg.builder()
            .type(OTHER)
            .payReceive(RECEIVE)
            .paymentEvents(
                fixedPayment1,
                fixedPayment2,
                iborPayment11,
                iborPayment12,
                iborPayment21,
                iborPayment22)
            .build();

    double eps = 1.0e-12;
    assertEquals(computed.getPaymentEvents().size(), expected.getPaymentEvents().size());
    for (int i = 0; i < 6; ++i) {
      NotionalExchange payCmp = (NotionalExchange) computed.getPaymentEvents().get(i);
      NotionalExchange payExp = (NotionalExchange) expected.getPaymentEvents().get(i);
      assertEquals(payCmp.getCurrency(), payExp.getCurrency());
      assertEquals(payCmp.getPaymentDate(), payExp.getPaymentDate());
      assertTrue(
          DoubleMath.fuzzyEquals(
              payCmp.getPaymentAmount().getAmount(),
              payExp.getPaymentAmount().getAmount(),
              NOTIONAL * eps));
    }
  }