/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.irfuture; import static com.opengamma.sesame.config.ConfigBuilder.argument; import static com.opengamma.sesame.config.ConfigBuilder.arguments; import static com.opengamma.sesame.config.ConfigBuilder.config; import static com.opengamma.sesame.config.ConfigBuilder.function; import static com.opengamma.sesame.config.ConfigBuilder.implementations; import static com.opengamma.util.result.ResultTestUtils.assertSuccess; import java.io.IOException; import java.math.BigDecimal; import java.util.Map; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.threeten.bp.Instant; import org.threeten.bp.LocalDate; import org.threeten.bp.LocalTime; import org.threeten.bp.OffsetTime; import org.threeten.bp.Period; import org.threeten.bp.ZoneOffset; import org.threeten.bp.ZonedDateTime; import com.google.common.collect.ImmutableMap; import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesSource; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.core.link.ConfigLink; import com.opengamma.core.position.Counterparty; import com.opengamma.core.position.impl.SimpleCounterparty; import com.opengamma.core.position.impl.SimpleTrade; import com.opengamma.financial.analytics.curve.ConfigDBCurveConstructionConfigurationSource; import com.opengamma.financial.analytics.curve.CurveConstructionConfigurationSource; import com.opengamma.financial.analytics.model.fixedincome.BucketedCurveSensitivities; import com.opengamma.financial.security.future.InterestRateFutureSecurity; import com.opengamma.id.ExternalId; import com.opengamma.service.ServiceContext; import com.opengamma.service.ThreadLocalServiceContext; import com.opengamma.service.VersionCorrectionProvider; import com.opengamma.sesame.CurveDefinitionCurveLabellingFn; import com.opengamma.sesame.CurveDefinitionFn; import com.opengamma.sesame.CurveLabellingFn; import com.opengamma.sesame.CurveNodeConverterFn; import com.opengamma.sesame.CurveSpecificationFn; import com.opengamma.sesame.CurveSpecificationMarketDataFn; import com.opengamma.sesame.DefaultCurveDefinitionFn; import com.opengamma.sesame.DefaultCurveNodeConverterFn; import com.opengamma.sesame.DefaultCurveSpecificationFn; import com.opengamma.sesame.DefaultCurveSpecificationMarketDataFn; import com.opengamma.sesame.DefaultDiscountingMulticurveBundleFn; import com.opengamma.sesame.DefaultDiscountingMulticurveBundleResolverFn; import com.opengamma.sesame.DefaultFXMatrixFn; import com.opengamma.sesame.DefaultFixingsFn; import com.opengamma.sesame.DiscountingMulticurveBundleFn; import com.opengamma.sesame.DiscountingMulticurveBundleResolverFn; import com.opengamma.sesame.DiscountingMulticurveCombinerFn; import com.opengamma.sesame.Environment; import com.opengamma.sesame.ExposureFunctionsDiscountingMulticurveCombinerFn; import com.opengamma.sesame.FXMatrixFn; import com.opengamma.sesame.FixingsFn; import com.opengamma.sesame.MarketExposureSelector; import com.opengamma.sesame.RootFinderConfiguration; import com.opengamma.sesame.SimpleEnvironment; import com.opengamma.sesame.component.RetrievalPeriod; import com.opengamma.sesame.component.StringSet; import com.opengamma.sesame.config.FunctionModelConfig; import com.opengamma.sesame.engine.ComponentMap; import com.opengamma.sesame.engine.FixedInstantVersionCorrectionProvider; import com.opengamma.sesame.graph.FunctionModel; import com.opengamma.sesame.interestrate.InterestRateMockSources; import com.opengamma.sesame.marketdata.DefaultHistoricalMarketDataFn; import com.opengamma.sesame.marketdata.DefaultMarketDataFn; import com.opengamma.sesame.marketdata.HistoricalMarketDataFn; import com.opengamma.sesame.marketdata.MapMarketDataBundle; import com.opengamma.sesame.marketdata.MarketDataBundle; import com.opengamma.sesame.marketdata.MarketDataEnvironmentBuilder; import com.opengamma.sesame.marketdata.MarketDataFn; import com.opengamma.sesame.marketdata.RawId; import com.opengamma.sesame.trade.InterestRateFutureTrade; import com.opengamma.timeseries.date.localdate.ImmutableLocalDateDoubleTimeSeries; import com.opengamma.timeseries.date.localdate.LocalDateDoubleTimeSeries; import com.opengamma.util.money.Currency; import com.opengamma.util.money.MultipleCurrencyAmount; import com.opengamma.util.result.Result; import com.opengamma.util.test.TestGroup; import com.opengamma.util.time.DateUtils; import com.opengamma.util.time.Expiry; /** * Tests the interest rate future analytics functions using the discounting calculator. */ @Test(groups = TestGroup.UNIT) public class InterestRateFutureFnTest { private static final InterestRateFutureTrade TRADE = createIRFutureTrade(); private static final ZonedDateTime VALUATION_TIME = DateUtils.getUTCDate(2014, 1, 22); private static final Environment ENV = new SimpleEnvironment(VALUATION_TIME, createMarketDataBundle()); private InterestRateFutureFn _irFutureFn; private static MarketDataBundle createMarketDataBundle() { LocalDate dataDate = LocalDate.of(2014, 2, 18); MarketDataEnvironmentBuilder builder = InterestRateMockSources.createMarketDataEnvironment(dataDate).toBuilder(); LocalDate valuationDate = VALUATION_TIME.toLocalDate(); LocalDateDoubleTimeSeries priceSeries = ImmutableLocalDateDoubleTimeSeries.of(valuationDate, 0.975); RawId<Double> id = RawId.of(TRADE.getTrade().getSecurity().getExternalIdBundle()); builder.add(id, priceSeries); return new MapMarketDataBundle(builder.build()); } @BeforeClass public void setUpClass() throws IOException { FunctionModelConfig config = config( arguments( function( MarketExposureSelector.class, argument("exposureFunctions", ConfigLink.resolved(InterestRateMockSources.mockExposureFunctions()))), function( RootFinderConfiguration.class, argument("rootFinderAbsoluteTolerance", 1e-9), argument("rootFinderRelativeTolerance", 1e-9), argument("rootFinderMaxIterations", 1000)), function( DefaultDiscountingMulticurveBundleFn.class, argument("impliedCurveNames", StringSet.of())), function( DefaultCurveNodeConverterFn.class, argument("timeSeriesDuration", RetrievalPeriod.of(Period.ofYears(1))))), implementations( InterestRateFutureFn.class, DefaultInterestRateFutureFn.class, InterestRateFutureCalculatorFactory.class, InterestRateFutureDiscountingCalculatorFactory.class, CurveSpecificationMarketDataFn.class, DefaultCurveSpecificationMarketDataFn.class, CurveNodeConverterFn.class, DefaultCurveNodeConverterFn.class, FXMatrixFn.class, DefaultFXMatrixFn.class, DiscountingMulticurveCombinerFn.class, ExposureFunctionsDiscountingMulticurveCombinerFn.class, CurveDefinitionFn.class, DefaultCurveDefinitionFn.class, CurveLabellingFn.class, CurveDefinitionCurveLabellingFn.class, DiscountingMulticurveBundleFn.class, DefaultDiscountingMulticurveBundleFn.class, DiscountingMulticurveBundleResolverFn.class, DefaultDiscountingMulticurveBundleResolverFn.class, CurveSpecificationFn.class, DefaultCurveSpecificationFn.class, CurveConstructionConfigurationSource.class, ConfigDBCurveConstructionConfigurationSource.class, FixingsFn.class, DefaultFixingsFn.class, HistoricalMarketDataFn.class, DefaultHistoricalMarketDataFn.class, MarketDataFn.class, DefaultMarketDataFn.class)); ImmutableMap<Class<?>, Object> components = generateComponents(); VersionCorrectionProvider vcProvider = new FixedInstantVersionCorrectionProvider(Instant.now()); ServiceContext serviceContext = ServiceContext.of(components).with(VersionCorrectionProvider.class, vcProvider); ThreadLocalServiceContext.init(serviceContext); _irFutureFn = FunctionModel.build(InterestRateFutureFn.class, config, ComponentMap.of(components)); } private ImmutableMap<Class<?>, Object> generateComponents() { ImmutableMap.Builder<Class<?>, Object> builder = ImmutableMap.builder(); for (Map.Entry<Class<?>, Object> keys: InterestRateMockSources.generateBaseComponents().entrySet()) { if (!keys.getKey().equals(HistoricalTimeSeriesSource.class)) { builder.put(keys.getKey(), keys.getValue()); } } return builder.build(); } @Test public void testPresentValue() { Result<MultipleCurrencyAmount> pvComputed = _irFutureFn.calculatePV(ENV, TRADE); assertSuccess(pvComputed); } @Test public void testBucketedZeroDelta() { Result<BucketedCurveSensitivities> bucketedZeroDelta = _irFutureFn .calculateBucketedZeroIRDelta(ENV, TRADE); assertSuccess(bucketedZeroDelta); } private static InterestRateFutureTrade createIRFutureTrade() { Expiry expiry = new Expiry(ZonedDateTime.of(LocalDate.of(2014, 6, 18), LocalTime.of(0, 0), ZoneOffset.UTC)); String tradingExchange = ""; String settlementExchange = ""; Currency currency = Currency.USD; double unitAmount = 1000; ExternalId underlyingId = InterestRateMockSources.getLiborIndexId(); String category = ""; InterestRateFutureSecurity irFuture = new InterestRateFutureSecurity(expiry, tradingExchange, settlementExchange, currency, unitAmount, underlyingId, category); // Need this for time series lookup irFuture.setExternalIdBundle(ExternalSchemes.syntheticSecurityId("Test future").toBundle()); Counterparty counterparty = new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "COUNTERPARTY")); BigDecimal tradeQuantity = BigDecimal.valueOf(10); LocalDate tradeDate = LocalDate.of(2000, 1, 1); OffsetTime tradeTime = OffsetTime.of(LocalTime.of(0, 0), ZoneOffset.UTC); SimpleTrade trade = new SimpleTrade(irFuture, tradeQuantity, counterparty, tradeDate, tradeTime); trade.setPremium(0.0); trade.setPremiumCurrency(Currency.USD); return new InterestRateFutureTrade(trade); } }