/** 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); } }
/** 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); } }
/** 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); } }