Example #1
0
/** Test. */
@Test
public class FxResetTest {

  private static final ReferenceData REF_DATA = ReferenceData.standard();
  private static final LocalDate DATE_2014_06_30 = date(2014, 6, 30);

  public void test_of() {
    FxReset test = FxReset.of(FxIndexObservation.of(EUR_GBP_ECB, DATE_2014_06_30, REF_DATA), GBP);
    assertEquals(test.getIndex(), EUR_GBP_ECB);
    assertEquals(test.getReferenceCurrency(), GBP);
  }

  public void test_invalidCurrency() {
    assertThrowsIllegalArg(
        () ->
            FxReset.meta()
                .builder()
                .set(
                    FxReset.meta().observation(),
                    FxIndexObservation.of(EUR_USD_ECB, DATE_2014_06_30, REF_DATA))
                .set(FxReset.meta().referenceCurrency(), GBP)
                .build());
    assertThrowsIllegalArg(
        () -> FxReset.of(FxIndexObservation.of(EUR_USD_ECB, DATE_2014_06_30, REF_DATA), GBP));
  }

  // -------------------------------------------------------------------------
  public void coverage() {
    FxReset test = FxReset.of(FxIndexObservation.of(EUR_GBP_ECB, DATE_2014_06_30, REF_DATA), GBP);
    coverImmutableBean(test);
    FxReset test2 =
        FxReset.of(FxIndexObservation.of(EUR_USD_ECB, date(2014, 1, 15), REF_DATA), USD);
    coverBeanEquals(test, test2);
    FxReset test3 =
        FxReset.of(FxIndexObservation.of(EUR_USD_ECB, date(2014, 1, 15), REF_DATA), EUR);
    coverBeanEquals(test2, test3);
  }

  public void test_serialization() {
    FxReset test = FxReset.of(FxIndexObservation.of(EUR_GBP_ECB, DATE_2014_06_30, REF_DATA), GBP);
    assertSerialization(test);
  }
}
Example #2
0
/** Test. */
@Test
public class ResetScheduleTest {

  private static final ReferenceData REF_DATA = ReferenceData.standard();
  private static final LocalDate DATE_01_05 = date(2014, 1, 5);
  private static final LocalDate DATE_01_06 = date(2014, 1, 6);
  private static final LocalDate DATE_02_05 = date(2014, 2, 5);
  private static final LocalDate DATE_03_05 = date(2014, 3, 5);
  private static final LocalDate DATE_04_05 = date(2014, 4, 5);
  private static final LocalDate DATE_04_07 = date(2014, 4, 7);

  // -------------------------------------------------------------------------
  public void test_builder_ensureDefaults() {
    ResetSchedule test =
        ResetSchedule.builder()
            .resetFrequency(P1M)
            .businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
            .build();
    assertEquals(test.getResetFrequency(), P1M);
    assertEquals(test.getBusinessDayAdjustment(), BusinessDayAdjustment.of(FOLLOWING, GBLO));
    assertEquals(test.getResetMethod(), UNWEIGHTED);
  }

  // -------------------------------------------------------------------------
  public void test_resolve() {
    ResetSchedule test =
        ResetSchedule.builder()
            .resetFrequency(P1M)
            .businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
            .build();
    SchedulePeriod accrualPeriod =
        SchedulePeriod.of(DATE_01_06, DATE_04_07, DATE_01_05, DATE_04_05);
    Schedule schedule = test.createSchedule(DAY_5, REF_DATA).apply(accrualPeriod);
    Schedule expected =
        Schedule.builder()
            .periods(
                SchedulePeriod.of(DATE_01_06, DATE_02_05, DATE_01_05, DATE_02_05),
                SchedulePeriod.of(DATE_02_05, DATE_03_05, DATE_02_05, DATE_03_05),
                SchedulePeriod.of(DATE_03_05, DATE_04_07, DATE_03_05, DATE_04_05))
            .frequency(P1M)
            .rollConvention(DAY_5)
            .build();
    assertEquals(schedule, expected);
  }

  // -------------------------------------------------------------------------
  public void coverage() {
    ResetSchedule test =
        ResetSchedule.builder()
            .resetFrequency(P1M)
            .businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
            .build();
    coverImmutableBean(test);
    ResetSchedule test2 =
        ResetSchedule.builder()
            .resetFrequency(P3M)
            .businessDayAdjustment(BusinessDayAdjustment.of(MODIFIED_FOLLOWING, GBLO))
            .resetMethod(WEIGHTED)
            .build();
    coverBeanEquals(test, test2);
  }

  public void test_serialization() {
    ResetSchedule test =
        ResetSchedule.builder()
            .resetFrequency(P1M)
            .businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
            .build();
    assertSerialization(test);
  }
}
/** Test {@link ThreeLegBasisSwapConvention}. */
@Test
public class ThreeLegBasisSwapConventionTest {

  private static final ReferenceData REF_DATA = ReferenceData.standard();
  private static final double NOTIONAL_2M = 2_000_000d;
  private static final BusinessDayAdjustment BDA_FOLLOW = BusinessDayAdjustment.of(FOLLOWING, EUTA);
  private static final DaysAdjustment PLUS_ONE_DAY = DaysAdjustment.ofBusinessDays(1, EUTA);

  private static final String NAME = "EUR-Swap";
  private static final FixedRateSwapLegConvention FIXED =
      FixedRateSwapLegConvention.of(EUR, THIRTY_U_360, P12M, BDA_FOLLOW);
  private static final IborRateSwapLegConvention IBOR3M =
      IborRateSwapLegConvention.of(EUR_EURIBOR_3M);
  private static final IborRateSwapLegConvention IBOR6M =
      IborRateSwapLegConvention.of(EUR_EURIBOR_6M);
  private static final IborRateSwapLegConvention IBOR12M =
      IborRateSwapLegConvention.of(EUR_EURIBOR_12M);

  // -------------------------------------------------------------------------
  public void test_of() {
    ImmutableThreeLegBasisSwapConvention test =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR6M, IBOR12M);
    assertEquals(test.getName(), NAME);
    assertEquals(test.getSpreadLeg(), FIXED);
    assertEquals(test.getSpreadFloatingLeg(), IBOR6M);
    assertEquals(test.getFlatFloatingLeg(), IBOR12M);
    assertEquals(test.getSpotDateOffset(), EUR_EURIBOR_6M.getEffectiveDateOffset());
  }

  public void test_of_spotDateOffset() {
    ImmutableThreeLegBasisSwapConvention test =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR6M, IBOR12M, PLUS_ONE_DAY);
    assertEquals(test.getName(), NAME);
    assertEquals(test.getSpreadLeg(), FIXED);
    assertEquals(test.getSpreadFloatingLeg(), IBOR6M);
    assertEquals(test.getFlatFloatingLeg(), IBOR12M);
    assertEquals(test.getSpotDateOffset(), PLUS_ONE_DAY);
  }

  public void test_builder() {
    ImmutableThreeLegBasisSwapConvention test =
        ImmutableThreeLegBasisSwapConvention.builder()
            .name(NAME)
            .spreadLeg(FIXED)
            .spreadFloatingLeg(IBOR6M)
            .flatFloatingLeg(IBOR12M)
            .spotDateOffset(PLUS_ONE_DAY)
            .build();
    assertEquals(test.getName(), NAME);
    assertEquals(test.getSpreadLeg(), FIXED);
    assertEquals(test.getSpreadFloatingLeg(), IBOR6M);
    assertEquals(test.getFlatFloatingLeg(), IBOR12M);
    assertEquals(test.getSpotDateOffset(), PLUS_ONE_DAY);
  }

  // -------------------------------------------------------------------------
  public void test_toTrade_tenor() {
    ThreeLegBasisSwapConvention base =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR6M, IBOR12M);
    LocalDate tradeDate = LocalDate.of(2015, 5, 5);
    LocalDate startDate = date(2015, 5, 7);
    LocalDate endDate = date(2025, 5, 7);
    SwapTrade test = base.createTrade(tradeDate, TENOR_10Y, BUY, NOTIONAL_2M, 0.25d, REF_DATA);
    Swap expected =
        Swap.of(
            FIXED.toLeg(startDate, endDate, PAY, NOTIONAL_2M, 0.25d),
            IBOR6M.toLeg(startDate, endDate, PAY, NOTIONAL_2M),
            IBOR12M.toLeg(startDate, endDate, RECEIVE, NOTIONAL_2M));
    assertEquals(test.getInfo().getTradeDate(), Optional.of(tradeDate));
    assertEquals(test.getProduct(), expected);
  }

  public void test_toTrade_periodTenor() {
    ThreeLegBasisSwapConvention base =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR6M, IBOR12M);
    LocalDate tradeDate = LocalDate.of(2015, 5, 5);
    LocalDate startDate = date(2015, 8, 7);
    LocalDate endDate = date(2025, 8, 7);
    SwapTrade test =
        base.createTrade(
            tradeDate, Period.ofMonths(3), TENOR_10Y, BUY, NOTIONAL_2M, 0.25d, REF_DATA);
    Swap expected =
        Swap.of(
            FIXED.toLeg(startDate, endDate, PAY, NOTIONAL_2M, 0.25d),
            IBOR6M.toLeg(startDate, endDate, PAY, NOTIONAL_2M),
            IBOR12M.toLeg(startDate, endDate, RECEIVE, NOTIONAL_2M));
    assertEquals(test.getInfo().getTradeDate(), Optional.of(tradeDate));
    assertEquals(test.getProduct(), expected);
  }

  public void test_toTrade_dates() {
    ThreeLegBasisSwapConvention base =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR6M, IBOR12M);
    LocalDate tradeDate = LocalDate.of(2015, 5, 5);
    LocalDate startDate = date(2015, 8, 5);
    LocalDate endDate = date(2015, 11, 5);
    SwapTrade test = base.toTrade(tradeDate, startDate, endDate, BUY, NOTIONAL_2M, 0.25d);
    Swap expected =
        Swap.of(
            FIXED.toLeg(startDate, endDate, PAY, NOTIONAL_2M, 0.25d),
            IBOR6M.toLeg(startDate, endDate, PAY, NOTIONAL_2M),
            IBOR12M.toLeg(startDate, endDate, RECEIVE, NOTIONAL_2M));
    assertEquals(test.getInfo().getTradeDate(), Optional.of(tradeDate));
    assertEquals(test.getProduct(), expected);
  }

  // -------------------------------------------------------------------------
  @DataProvider(name = "name")
  static Object[][] data_name() {
    return new Object[][] {
      {
        ThreeLegBasisSwapConventions.EUR_FIXED_1Y_EURIBOR_3M_EURIBOR_6M,
        "EUR-FIXED-1Y-EURIBOR-3M-EURIBOR-6M"
      },
    };
  }

  @Test(dataProvider = "name")
  public void test_name(ThreeLegBasisSwapConvention convention, String name) {
    assertEquals(convention.getName(), name);
  }

  @Test(dataProvider = "name")
  public void test_toString(ThreeLegBasisSwapConvention convention, String name) {
    assertEquals(convention.toString(), name);
  }

  @Test(dataProvider = "name")
  public void test_of_lookup(ThreeLegBasisSwapConvention convention, String name) {
    assertEquals(ThreeLegBasisSwapConvention.of(name), convention);
  }

  @Test(dataProvider = "name")
  public void test_extendedEnum(ThreeLegBasisSwapConvention convention, String name) {
    ThreeLegBasisSwapConvention.of(name); // ensures map is populated
    ImmutableMap<String, ThreeLegBasisSwapConvention> map =
        ThreeLegBasisSwapConvention.extendedEnum().lookupAll();
    assertEquals(map.get(name), convention);
  }

  public void test_of_lookup_notFound() {
    assertThrowsIllegalArg(() -> ThreeLegBasisSwapConvention.of("Rubbish"));
  }

  public void test_of_lookup_null() {
    assertThrowsIllegalArg(() -> ThreeLegBasisSwapConvention.of((String) null));
  }

  // -------------------------------------------------------------------------
  public void coverage() {
    ImmutableThreeLegBasisSwapConvention test =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR6M, IBOR12M);
    coverImmutableBean(test);
    ImmutableThreeLegBasisSwapConvention test2 =
        ImmutableThreeLegBasisSwapConvention.of("swap", FIXED, IBOR3M, IBOR6M);
    coverBeanEquals(test, test2);
    ImmutableThreeLegBasisSwapConvention test3 =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR3M, IBOR12M);
    coverBeanEquals(test, test3);
  }

  public void test_serialization() {
    ThreeLegBasisSwapConvention test =
        ImmutableThreeLegBasisSwapConvention.of(NAME, FIXED, IBOR6M, IBOR12M);
    assertSerialization(test);
  }
}
/** Test {@link SabrExtrapolationReplicationCmsTradePricer}. */
@Test
public class DiscountingCmsTradePricerTest {

  private static final ReferenceData REF_DATA = ReferenceData.standard();

  // trades
  private static final LocalDate VALUATION = LocalDate.of(2015, 8, 18);
  private static final SwapIndex INDEX = SwapIndices.EUR_EURIBOR_1100_5Y;
  private static final LocalDate START = LocalDate.of(2015, 10, 21);
  private static final LocalDate END = LocalDate.of(2020, 10, 21);
  private static final Frequency FREQUENCY = Frequency.P12M;
  private static final BusinessDayAdjustment BUSS_ADJ_EUR =
      BusinessDayAdjustment.of(BusinessDayConventions.FOLLOWING, EUTA);
  private static final PeriodicSchedule SCHEDULE_EUR =
      PeriodicSchedule.of(
          START, END, FREQUENCY, BUSS_ADJ_EUR, StubConvention.NONE, RollConventions.NONE);
  private static final double NOTIONAL_VALUE = 1.0e6;
  private static final ValueSchedule NOTIONAL = ValueSchedule.of(NOTIONAL_VALUE);
  private static final ResolvedCmsLeg CMS_LEG =
      CmsLeg.builder()
          .index(INDEX)
          .notional(NOTIONAL)
          .payReceive(RECEIVE)
          .paymentSchedule(SCHEDULE_EUR)
          .build()
          .resolve(REF_DATA);
  private static final ResolvedSwapLeg PAY_LEG =
      RateCalculationSwapLeg.builder()
          .payReceive(PAY)
          .accrualSchedule(SCHEDULE_EUR)
          .calculation(FixedRateCalculation.of(0.01, ACT_360))
          .paymentSchedule(
              PaymentSchedule.builder()
                  .paymentFrequency(FREQUENCY)
                  .paymentDateOffset(DaysAdjustment.NONE)
                  .build())
          .notionalSchedule(NotionalSchedule.of(CurrencyAmount.of(EUR, NOTIONAL_VALUE)))
          .build()
          .resolve(REF_DATA);
  private static final ResolvedCms CMS_TWO_LEGS = ResolvedCms.of(CMS_LEG, PAY_LEG);
  private static final ResolvedCms CMS_ONE_LEG = ResolvedCms.of(CMS_LEG);
  private static final Payment PREMIUM =
      Payment.of(CurrencyAmount.of(EUR, -0.03 * NOTIONAL_VALUE), VALUATION);
  private static final TradeInfo TRADE_INFO = TradeInfo.builder().tradeDate(VALUATION).build();
  private static final ResolvedCmsTrade CMS_TRADE =
      ResolvedCmsTrade.builder().product(CMS_TWO_LEGS).info(TRADE_INFO).build();
  private static final ResolvedCmsTrade CMS_TRADE_PREMIUM =
      ResolvedCmsTrade.builder().product(CMS_ONE_LEG).premium(PREMIUM).build();
  // providers
  private static final ImmutableRatesProvider RATES_PROVIDER =
      SwaptionSabrRateVolatilityDataSet.getRatesProviderEur(VALUATION);
  // providers - valuation on payment date
  private static final LocalDate FIXING =
      LocalDate.of(2016, 10, 19); // fixing for the second period.
  private static final double OBS_INDEX = 0.013;
  private static final LocalDateDoubleTimeSeries TIME_SERIES =
      LocalDateDoubleTimeSeries.of(FIXING, OBS_INDEX);
  private static final LocalDate PAYMENT =
      LocalDate.of(2017, 10, 23); // payment date of the second payment
  private static final ImmutableRatesProvider RATES_PROVIDER_ON_PAY =
      SwaptionSabrRateVolatilityDataSet.getRatesProviderEur(PAYMENT, TIME_SERIES);
  // pricers
  private static final DiscountingCmsProductPricer PRODUCT_PRICER =
      DiscountingCmsProductPricer.DEFAULT;
  private static final DiscountingPaymentPricer PREMIUM_PRICER = DiscountingPaymentPricer.DEFAULT;
  private static final DiscountingCmsTradePricer TRADE_PRICER = DiscountingCmsTradePricer.DEFAULT;
  private static final double TOL = 1.0e-13;

  public void test_presentValue() {
    MultiCurrencyAmount pv1 = TRADE_PRICER.presentValue(CMS_TRADE_PREMIUM, RATES_PROVIDER);
    MultiCurrencyAmount pv2 = TRADE_PRICER.presentValue(CMS_TRADE, RATES_PROVIDER);
    MultiCurrencyAmount pvProd1 = PRODUCT_PRICER.presentValue(CMS_ONE_LEG, RATES_PROVIDER);
    MultiCurrencyAmount pvProd2 = PRODUCT_PRICER.presentValue(CMS_TWO_LEGS, RATES_PROVIDER);
    CurrencyAmount pvPrem = PREMIUM_PRICER.presentValue(PREMIUM, RATES_PROVIDER);
    assertEquals(pv1, pvProd1.plus(pvPrem));
    assertEquals(pv2, pvProd2);
  }

  public void test_presentValueSensitivity() {
    PointSensitivities pt1 =
        TRADE_PRICER.presentValueSensitivity(CMS_TRADE_PREMIUM, RATES_PROVIDER);
    PointSensitivities pt2 = TRADE_PRICER.presentValueSensitivity(CMS_TRADE, RATES_PROVIDER);
    PointSensitivityBuilder ptProd1 =
        PRODUCT_PRICER.presentValueSensitivity(CMS_ONE_LEG, RATES_PROVIDER);
    PointSensitivityBuilder ptProd2 =
        PRODUCT_PRICER.presentValueSensitivity(CMS_TWO_LEGS, RATES_PROVIDER);
    PointSensitivityBuilder ptPrem =
        PREMIUM_PRICER.presentValueSensitivity(PREMIUM, RATES_PROVIDER);
    assertEquals(pt1, ptProd1.combinedWith(ptPrem).build());
    assertEquals(pt2, ptProd2.build());
  }

  public void test_currencyExposure() {
    MultiCurrencyAmount computed1 =
        TRADE_PRICER.currencyExposure(CMS_TRADE_PREMIUM, RATES_PROVIDER);
    MultiCurrencyAmount computed2 = TRADE_PRICER.currencyExposure(CMS_TRADE, RATES_PROVIDER);
    MultiCurrencyAmount pv1 = TRADE_PRICER.presentValue(CMS_TRADE_PREMIUM, RATES_PROVIDER);
    PointSensitivities pt1 =
        TRADE_PRICER.presentValueSensitivity(CMS_TRADE_PREMIUM, RATES_PROVIDER);
    MultiCurrencyAmount expected1 = RATES_PROVIDER.currencyExposure(pt1).plus(pv1);
    MultiCurrencyAmount pv2 = TRADE_PRICER.presentValue(CMS_TRADE, RATES_PROVIDER);
    PointSensitivities pt2 = TRADE_PRICER.presentValueSensitivity(CMS_TRADE, RATES_PROVIDER);
    MultiCurrencyAmount expected2 = RATES_PROVIDER.currencyExposure(pt2).plus(pv2);
    assertEquals(
        computed1.getAmount(EUR).getAmount(),
        expected1.getAmount(EUR).getAmount(),
        NOTIONAL_VALUE * TOL);
    assertEquals(
        computed2.getAmount(EUR).getAmount(),
        expected2.getAmount(EUR).getAmount(),
        NOTIONAL_VALUE * TOL);
  }

  public void test_currentCash() {
    MultiCurrencyAmount cc1 = TRADE_PRICER.currentCash(CMS_TRADE_PREMIUM, RATES_PROVIDER);
    MultiCurrencyAmount cc2 = TRADE_PRICER.currentCash(CMS_TRADE, RATES_PROVIDER);
    assertEquals(cc1, MultiCurrencyAmount.of(PREMIUM.getValue()));
    assertEquals(cc2, MultiCurrencyAmount.of(CurrencyAmount.zero(EUR)));
  }

  public void test_currentCash_onPay() {
    MultiCurrencyAmount cc1 = TRADE_PRICER.currentCash(CMS_TRADE_PREMIUM, RATES_PROVIDER_ON_PAY);
    MultiCurrencyAmount cc2 = TRADE_PRICER.currentCash(CMS_TRADE, RATES_PROVIDER_ON_PAY);
    MultiCurrencyAmount ccProd1 = PRODUCT_PRICER.currentCash(CMS_ONE_LEG, RATES_PROVIDER_ON_PAY);
    MultiCurrencyAmount ccProd2 = PRODUCT_PRICER.currentCash(CMS_TWO_LEGS, RATES_PROVIDER_ON_PAY);
    assertEquals(cc1, ccProd1);
    assertEquals(cc2, ccProd2);
  }
}
Example #5
0
/** Test {@link BondFutureTrade}. */
@Test
public class BondFutureTradeTest {

  private static final ReferenceData REF_DATA = ReferenceData.standard();

  // future
  private static final BondFuture FUTURE = BondFutureTest.sut();
  private static final BondFuture FUTURE2 = BondFutureTest.sut2();
  // trade
  private static final LocalDate TRADE_DATE = date(2011, 6, 20);
  private static final TradeInfo TRADE_INFO = TradeInfo.of(TRADE_DATE);
  private static final TradeInfo TRADE_INFO2 = TradeInfo.of(date(2016, 7, 1));
  private static final double QUANTITY = 1234L;
  private static final double QUANTITY2 = 100L;
  private static final double PRICE = 1.2345;
  private static final double PRICE2 = 1.3;

  // -------------------------------------------------------------------------
  public void test_builder() {
    BondFutureTrade test = sut();
    assertEquals(test.getInfo(), TRADE_INFO);
    assertEquals(test.getProduct(), FUTURE);
    assertEquals(test.getQuantity(), QUANTITY);
    assertEquals(test.getPrice(), PRICE);
  }

  // -------------------------------------------------------------------------
  public void test_resolve() {
    ResolvedBondFutureTrade expected =
        ResolvedBondFutureTrade.builder()
            .info(TRADE_INFO)
            .product(FUTURE.resolve(REF_DATA))
            .quantity(QUANTITY)
            .price(PRICE)
            .build();
    assertEquals(sut().resolve(REF_DATA), expected);
  }

  // -------------------------------------------------------------------------
  public void coverage() {
    coverImmutableBean(sut());
    coverBeanEquals(sut(), sut2());
  }

  public void test_serialization() {
    assertSerialization(sut());
  }

  static BondFutureTrade sut() {
    return BondFutureTrade.builder()
        .info(TRADE_INFO)
        .product(FUTURE)
        .quantity(QUANTITY)
        .price(PRICE)
        .build();
  }

  static BondFutureTrade sut2() {
    return BondFutureTrade.builder()
        .info(TRADE_INFO2)
        .product(FUTURE2)
        .quantity(QUANTITY2)
        .price(PRICE2)
        .build();
  }
}
  // obtains the data and calculates the grid of results
  private static void calculate(CalculationRunner runner) {
    // the trade that will have measures calculated
    List<Trade> trades = ImmutableList.of(createVanillaFixedVsLibor3mSwap());

    // the columns, specifying the measures to be calculated
    List<Column> columns =
        ImmutableList.of(
            Column.of(Measures.PRESENT_VALUE), Column.of(Measures.PV01_CALIBRATED_SUM));

    // use the built-in example market data
    ExampleMarketDataBuilder marketDataBuilder = ExampleMarketData.builder();

    // the complete set of rules for calculating measures
    LocalDate valuationDate = LocalDate.of(2014, 1, 22);
    CalculationFunctions functions = StandardComponents.calculationFunctions();
    CalculationRules rules =
        CalculationRules.of(functions, Currency.USD, marketDataBuilder.ratesLookup(valuationDate));

    // mappings that select which market data to apply perturbations to
    // this applies the perturbations above to all curves
    PerturbationMapping<Curve> mapping =
        PerturbationMapping.of(
            Curve.class,
            MarketDataFilter.ofIdType(CurveId.class),
            // no shift for the base scenario, 1bp absolute shift to calibrated curves (zeros)
            CurveParallelShifts.absolute(0, ONE_BP));

    // create a scenario definition containing the single mapping above
    // this creates two scenarios - one for each perturbation in the mapping
    ScenarioDefinition scenarioDefinition = ScenarioDefinition.ofMappings(mapping);

    // build a market data snapshot for the valuation date
    MarketData marketData = marketDataBuilder.buildSnapshot(valuationDate);

    // the reference data, such as holidays and securities
    ReferenceData refData = ReferenceData.standard();

    // calculate the results
    MarketDataRequirements reqs = MarketDataRequirements.of(rules, trades, columns, refData);
    ScenarioMarketData scenarioMarketData =
        marketDataFactory()
            .createMultiScenario(
                reqs, MarketDataConfig.empty(), marketData, refData, scenarioDefinition);
    Results results =
        runner.calculateMultiScenario(rules, trades, columns, scenarioMarketData, refData);

    // TODO Replace the results processing below with a report once the reporting framework supports
    // scenarios

    // The results are lists of currency amounts containing one value for each scenario
    ScenarioArray<?> pvList = (ScenarioArray<?>) results.get(0, 0).getValue();
    ScenarioArray<?> pv01List = (ScenarioArray<?>) results.get(0, 1).getValue();

    double pvBase = ((CurrencyAmount) pvList.get(0)).getAmount();
    double pvShifted = ((CurrencyAmount) pvList.get(1)).getAmount();
    double pv01Base = ((CurrencyAmount) pv01List.get(0)).getAmount();
    NumberFormat numberFormat =
        new DecimalFormat("###,##0.00", new DecimalFormatSymbols(Locale.ENGLISH));

    System.out.println("                         PV (base) = " + numberFormat.format(pvBase));
    System.out.println("             PV (1 bp curve shift) = " + numberFormat.format(pvShifted));
    System.out.println("PV01 (algorithmic differentiation) = " + numberFormat.format(pv01Base));
    System.out.println(
        "          PV01 (finite difference) = " + numberFormat.format(pvShifted - pvBase));
  }
/** Test {@link DiscountingBondFutureProductPricer}. */
@Test
public class DiscountingBondFutureProductPricerTest {

  private static final ReferenceData REF_DATA = ReferenceData.standard();

  // product
  private static final ResolvedBondFuture FUTURE_PRODUCT =
      BondDataSets.FUTURE_PRODUCT_USD.resolve(REF_DATA);
  private static final ResolvedFixedCouponBond BOND = BondDataSets.BOND_USD[0].resolve(REF_DATA);
  private static final Double[] CONVERSION_FACTOR = BondDataSets.CONVERSION_FACTOR_USD.clone();
  // curves
  private static final LegalEntityDiscountingProvider PROVIDER =
      LegalEntityDiscountingProviderDataSets.ISSUER_REPO_ZERO;
  private static final CurveMetadata METADATA_ISSUER =
      LegalEntityDiscountingProviderDataSets.META_ZERO_ISSUER_USD;
  private static final CurveMetadata METADATA_REPO =
      LegalEntityDiscountingProviderDataSets.META_ZERO_REPO_USD;
  // parameters
  private static final double Z_SPREAD = 0.0075;
  private static final int PERIOD_PER_YEAR = 4;
  private static final double TOL = 1.0e-12;
  private static final double EPS = 1.0e-6;
  // pricer
  private static final DiscountingBondFutureProductPricer FUTURE_PRICER =
      DiscountingBondFutureProductPricer.DEFAULT;
  private static final DiscountingFixedCouponBondProductPricer BOND_PRICER =
      DiscountingFixedCouponBondProductPricer.DEFAULT;
  private static final RatesFiniteDifferenceSensitivityCalculator FD_CAL =
      new RatesFiniteDifferenceSensitivityCalculator(EPS);

  // -------------------------------------------------------------------------
  public void test_price() {
    double computed = FUTURE_PRICER.price(FUTURE_PRODUCT, PROVIDER);
    double dirtyPrice =
        BOND_PRICER.dirtyPriceFromCurves(BOND, PROVIDER, FUTURE_PRODUCT.getLastDeliveryDate());
    double expected =
        BOND_PRICER.cleanPriceFromDirtyPrice(BOND, FUTURE_PRODUCT.getLastDeliveryDate(), dirtyPrice)
            / CONVERSION_FACTOR[0];
    assertEquals(computed, expected, TOL);
  }

  public void test_priceWithZSpread_continuous() {
    double computed =
        FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0);
    double dirtyPrice =
        BOND_PRICER.dirtyPriceFromCurvesWithZSpread(
            BOND, PROVIDER, Z_SPREAD, CONTINUOUS, 0, FUTURE_PRODUCT.getLastDeliveryDate());
    double expected =
        BOND_PRICER.cleanPriceFromDirtyPrice(BOND, FUTURE_PRODUCT.getLastDeliveryDate(), dirtyPrice)
            / CONVERSION_FACTOR[0];
    assertEquals(computed, expected, TOL);
  }

  public void test_priceWithZSpread_periodic() {
    double computed =
        FUTURE_PRICER.priceWithZSpread(
            FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
    double dirtyPrice =
        BOND_PRICER.dirtyPriceFromCurvesWithZSpread(
            BOND,
            PROVIDER,
            Z_SPREAD,
            PERIODIC,
            PERIOD_PER_YEAR,
            FUTURE_PRODUCT.getLastDeliveryDate());
    double expected =
        BOND_PRICER.cleanPriceFromDirtyPrice(BOND, FUTURE_PRODUCT.getLastDeliveryDate(), dirtyPrice)
            / CONVERSION_FACTOR[0];
    assertEquals(computed, expected, TOL);
  }

  // -------------------------------------------------------------------------
  public void test_priceSensitivity() {
    PointSensitivities point = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER);
    CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
    CurrencyParameterSensitivities expected =
        FD_CAL.sensitivity(
            PROVIDER, (p) -> CurrencyAmount.of(USD, FUTURE_PRICER.price(FUTURE_PRODUCT, (p))));
    assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
  }

  public void test_priceSensitivityWithZSpread_continuous() {
    PointSensitivities point =
        FUTURE_PRICER.priceSensitivityWithZSpread(
            FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0);
    CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
    CurrencyParameterSensitivities expected =
        FD_CAL.sensitivity(
            PROVIDER,
            (p) ->
                CurrencyAmount.of(
                    USD,
                    FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, (p), Z_SPREAD, CONTINUOUS, 0)));
    assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
  }

  public void test_priceSensitivityWithZSpread_periodic() {
    PointSensitivities point =
        FUTURE_PRICER.priceSensitivityWithZSpread(
            FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
    CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
    CurrencyParameterSensitivities expected =
        FD_CAL.sensitivity(
            PROVIDER,
            (p) ->
                CurrencyAmount.of(
                    USD,
                    FUTURE_PRICER.priceWithZSpread(
                        FUTURE_PRODUCT, (p), Z_SPREAD, PERIODIC, PERIOD_PER_YEAR)));
    assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
  }

  // -------------------------------------------------------------------------
  // regression to 2.x
  public void regression() {
    double price = FUTURE_PRICER.price(FUTURE_PRODUCT, PROVIDER);
    assertEquals(price, 1.2106928633440506, TOL);
    PointSensitivities point = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER);
    CurrencyParameterSensitivities test = PROVIDER.parameterSensitivity(point);

    DoubleArray expectedIssuer =
        DoubleArray.of(
            -3.940585873921608E-4,
            -0.004161527192990392,
            -0.014331606019672717,
            -1.0229665443857998,
            -4.220553063715371,
            0);
    DoubleArray actualIssuer =
        test.getSensitivity(METADATA_ISSUER.getCurveName(), USD).getSensitivity();
    assertTrue(actualIssuer.equalWithTolerance(expectedIssuer, TOL));

    DoubleArray expectedRepo =
        DoubleArray.of(0.14752541809405412, 0.20907575809356016, 0.0, 0.0, 0.0, 0.0);
    DoubleArray actualRepo =
        test.getSensitivity(METADATA_REPO.getCurveName(), USD).getSensitivity();
    assertTrue(actualRepo.equalWithTolerance(expectedRepo, TOL));
  }

  public void regression_withZSpread_continuous() {
    double price =
        FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0);
    assertEquals(price, 1.1718691843665354, TOL);
    // curve parameter sensitivity is not supported for continuous z-spread in 2.x.
  }

  public void regression_withZSpread_periodic() {
    double price =
        FUTURE_PRICER.priceWithZSpread(
            FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
    assertEquals(price, 1.1720190529653407, TOL);
    PointSensitivities point =
        FUTURE_PRICER.priceSensitivityWithZSpread(
            FUTURE_PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
    CurrencyParameterSensitivities test = PROVIDER.parameterSensitivity(point);

    DoubleArray expectedIssuer =
        DoubleArray.of(
            -3.9201229100932256E-4,
            -0.0041367134351306374,
            -0.014173323438217467,
            -0.9886444827927878,
            -4.07533109609094,
            0);
    DoubleArray actualIssuer =
        test.getSensitivity(METADATA_ISSUER.getCurveName(), USD).getSensitivity();
    assertTrue(actualIssuer.equalWithTolerance(expectedIssuer, TOL));

    DoubleArray expectedRepo =
        DoubleArray.of(0.1428352116441475, 0.20242871054203687, 0.0, 0.0, 0.0, 0.0);
    DoubleArray actualRepo =
        test.getSensitivity(METADATA_REPO.getCurveName(), USD).getSensitivity();
    assertTrue(actualRepo.equalWithTolerance(expectedRepo, TOL));
  }
}
/** Test {@link TermDepositCurveNode}. */
@Test
public class TermDepositCurveNodeTest {

  private static final ReferenceData REF_DATA = ReferenceData.standard();
  private static final LocalDate VAL_DATE = date(2015, 6, 30);
  private static final BusinessDayAdjustment BDA_MOD_FOLLOW =
      BusinessDayAdjustment.of(MODIFIED_FOLLOWING, EUTA);
  private static final DaysAdjustment PLUS_TWO_DAYS = DaysAdjustment.ofBusinessDays(2, EUTA);
  private static final TermDepositConvention CONVENTION = TermDepositConventions.EUR_DEPOSIT_T2;
  private static final Period DEPOSIT_PERIOD = Period.ofMonths(3);
  private static final TermDepositTemplate TEMPLATE =
      TermDepositTemplate.of(DEPOSIT_PERIOD, CONVENTION);
  private static final QuoteId QUOTE_ID = QuoteId.of(StandardId.of("OG-Ticker", "Deposit1"));
  private static final double SPREAD = 0.0015;
  private static final String LABEL = "Label";
  private static final String LABEL_AUTO = "3M";

  public void test_builder() {
    TermDepositCurveNode test =
        TermDepositCurveNode.builder()
            .label(LABEL)
            .template(TEMPLATE)
            .rateId(QUOTE_ID)
            .additionalSpread(SPREAD)
            .date(CurveNodeDate.LAST_FIXING)
            .build();
    assertEquals(test.getLabel(), LABEL);
    assertEquals(test.getRateId(), QUOTE_ID);
    assertEquals(test.getAdditionalSpread(), SPREAD);
    assertEquals(test.getTemplate(), TEMPLATE);
    assertEquals(test.getDate(), CurveNodeDate.LAST_FIXING);
  }

  public void test_builder_defaults() {
    TermDepositCurveNode test =
        TermDepositCurveNode.builder()
            .label(LABEL)
            .template(TEMPLATE)
            .rateId(QUOTE_ID)
            .additionalSpread(SPREAD)
            .build();
    assertEquals(test.getLabel(), LABEL);
    assertEquals(test.getRateId(), QUOTE_ID);
    assertEquals(test.getAdditionalSpread(), SPREAD);
    assertEquals(test.getTemplate(), TEMPLATE);
    assertEquals(test.getDate(), CurveNodeDate.END);
  }

  public void test_of_noSpread() {
    TermDepositCurveNode test = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID);
    assertEquals(test.getLabel(), LABEL_AUTO);
    assertEquals(test.getRateId(), QUOTE_ID);
    assertEquals(test.getAdditionalSpread(), 0.0d);
    assertEquals(test.getTemplate(), TEMPLATE);
  }

  public void test_of_withSpread() {
    TermDepositCurveNode test = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    assertEquals(test.getLabel(), LABEL_AUTO);
    assertEquals(test.getRateId(), QUOTE_ID);
    assertEquals(test.getAdditionalSpread(), SPREAD);
    assertEquals(test.getTemplate(), TEMPLATE);
  }

  public void test_of_withSpreadAndLabel() {
    TermDepositCurveNode test = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD, LABEL);
    assertEquals(test.getLabel(), LABEL);
    assertEquals(test.getRateId(), QUOTE_ID);
    assertEquals(test.getAdditionalSpread(), SPREAD);
    assertEquals(test.getTemplate(), TEMPLATE);
  }

  public void test_requirements() {
    TermDepositCurveNode test = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    Set<ObservableId> set = test.requirements();
    Iterator<ObservableId> itr = set.iterator();
    assertEquals(itr.next(), QUOTE_ID);
    assertFalse(itr.hasNext());
  }

  public void test_trade() {
    TermDepositCurveNode node = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    double rate = 0.035;
    MarketData marketData = ImmutableMarketData.builder(VAL_DATE).addValue(QUOTE_ID, rate).build();
    TermDepositTrade trade = node.trade(1d, marketData, REF_DATA);
    LocalDate startDateExpected = PLUS_TWO_DAYS.adjust(VAL_DATE, REF_DATA);
    LocalDate endDateExpected = startDateExpected.plus(DEPOSIT_PERIOD);
    TermDeposit depositExpected =
        TermDeposit.builder()
            .buySell(BuySell.BUY)
            .currency(EUR)
            .dayCount(ACT_360)
            .startDate(startDateExpected)
            .endDate(endDateExpected)
            .notional(1.0d)
            .businessDayAdjustment(BDA_MOD_FOLLOW)
            .rate(rate + SPREAD)
            .build();
    TradeInfo tradeInfoExpected = TradeInfo.builder().tradeDate(VAL_DATE).build();
    assertEquals(trade.getProduct(), depositExpected);
    assertEquals(trade.getInfo(), tradeInfoExpected);
  }

  public void test_trade_noMarketData() {
    TermDepositCurveNode node = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    LocalDate valuationDate = LocalDate.of(2015, 1, 22);
    MarketData marketData = MarketData.empty(valuationDate);
    assertThrows(() -> node.trade(1d, marketData, REF_DATA), MarketDataNotFoundException.class);
  }

  public void test_initialGuess() {
    TermDepositCurveNode node = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    double rate = 0.035;
    MarketData marketData = ImmutableMarketData.builder(VAL_DATE).addValue(QUOTE_ID, rate).build();
    assertEquals(node.initialGuess(marketData, ValueType.ZERO_RATE), rate);
    assertEquals(node.initialGuess(marketData, ValueType.FORWARD_RATE), rate);
    assertEquals(
        node.initialGuess(marketData, ValueType.DISCOUNT_FACTOR), Math.exp(-rate * 0.25), 1.0e-12);
  }

  public void test_metadata_end() {
    TermDepositCurveNode node = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    LocalDate valuationDate = LocalDate.of(2015, 1, 22);
    ParameterMetadata metadata = node.metadata(valuationDate, REF_DATA);
    assertEquals(((TenorDateParameterMetadata) metadata).getDate(), LocalDate.of(2015, 4, 27));
    assertEquals(((TenorDateParameterMetadata) metadata).getTenor(), Tenor.TENOR_3M);
  }

  public void test_metadata_fixed() {
    LocalDate nodeDate = VAL_DATE.plusMonths(1);
    TermDepositCurveNode node =
        TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD).withDate(CurveNodeDate.of(nodeDate));
    LocalDate valuationDate = LocalDate.of(2015, 1, 22);
    DatedParameterMetadata metadata = node.metadata(valuationDate, REF_DATA);
    assertEquals(metadata.getDate(), nodeDate);
    assertEquals(metadata.getLabel(), node.getLabel());
  }

  public void test_metadata_last_fixing() {
    TermDepositCurveNode node =
        TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD).withDate(CurveNodeDate.LAST_FIXING);
    assertThrowsWithCause(
        () -> node.metadata(VAL_DATE, REF_DATA), UnsupportedOperationException.class);
  }

  // -------------------------------------------------------------------------
  public void coverage() {
    TermDepositCurveNode test = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    coverImmutableBean(test);
    TermDepositCurveNode test2 =
        TermDepositCurveNode.of(
            TermDepositTemplate.of(Period.ofMonths(1), CONVENTION),
            QuoteId.of(StandardId.of("OG-Ticker", "Deposit2")));
    coverBeanEquals(test, test2);
  }

  public void test_serialization() {
    TermDepositCurveNode test = TermDepositCurveNode.of(TEMPLATE, QUOTE_ID, SPREAD);
    assertSerialization(test);
  }
}