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