/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.sesame.exposure;
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 org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;
import java.math.BigDecimal;
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.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.core.link.ConfigLink;
import com.opengamma.core.position.Counterparty;
import com.opengamma.core.position.Trade;
import com.opengamma.core.position.impl.SimpleCounterparty;
import com.opengamma.core.position.impl.SimpleTrade;
import com.opengamma.financial.analytics.curve.exposure.ExposureFunctions;
import com.opengamma.financial.security.fra.FRASecurity;
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.CurveDefinitionFn;
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.DiscountingMulticurveBundleFn;
import com.opengamma.sesame.DiscountingMulticurveBundleResolverFn;
import com.opengamma.sesame.DiscountingMulticurveCombinerFn;
import com.opengamma.sesame.ExposureFunctionsDiscountingMulticurveCombinerFn;
import com.opengamma.sesame.FXMatrixFn;
import com.opengamma.sesame.MarketExposureSelector;
import com.opengamma.sesame.MulticurveBundle;
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.MarketDataFn;
import com.opengamma.sesame.trade.FraTrade;
import com.opengamma.sesame.trade.InterestRateFutureTrade;
import com.opengamma.util.money.Currency;
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 of ExposureFunctions at the view level
*/
@Test(groups = TestGroup.UNIT)
public class ExposureFunctionTest {
private static SimpleEnvironment _environment;
private static ImmutableMap<Class<?>, Object> _components = InterestRateMockSources.generateBaseComponents();
@BeforeClass
private void setUpClass() {
ZonedDateTime valTime = LocalDate.of(2014, 6, 1).atStartOfDay(ZoneOffset.UTC);
MarketDataBundle marketDataBundle = new MapMarketDataBundle(InterestRateMockSources.createMarketDataEnvironment());
_environment = new SimpleEnvironment(valTime, marketDataBundle);
VersionCorrectionProvider vcProvider = new FixedInstantVersionCorrectionProvider(Instant.now());
ServiceContext serviceContext = ServiceContext.of(_components).with(VersionCorrectionProvider.class, vcProvider);
ThreadLocalServiceContext.init(serviceContext);
}
private FunctionModelConfig createFunctionModelConfig(ExposureFunctions exposureFunctions) {
return config(
arguments(
function(
MarketExposureSelector.class,
argument("exposureFunctions", ConfigLink.resolved(exposureFunctions))),
function(
RootFinderConfiguration.class,
argument("rootFinderAbsoluteTolerance", 1e-9),
argument("rootFinderRelativeTolerance", 1e-9),
argument("rootFinderMaxIterations", 1000)),
function(
DefaultCurveNodeConverterFn.class,
argument("timeSeriesDuration", RetrievalPeriod.of(Period.ofYears(1)))),
function(
DefaultDiscountingMulticurveBundleFn.class,
argument("impliedCurveNames", StringSet.of()))),
implementations(
DiscountingMulticurveCombinerFn.class, ExposureFunctionsDiscountingMulticurveCombinerFn.class,
DiscountingMulticurveBundleFn.class, DefaultDiscountingMulticurveBundleFn.class,
DiscountingMulticurveBundleResolverFn.class, DefaultDiscountingMulticurveBundleResolverFn.class,
CurveDefinitionFn.class, DefaultCurveDefinitionFn.class,
CurveSpecificationFn.class, DefaultCurveSpecificationFn.class,
CurveSpecificationMarketDataFn.class, DefaultCurveSpecificationMarketDataFn.class,
FXMatrixFn.class, DefaultFXMatrixFn.class,
CurveNodeConverterFn.class, DefaultCurveNodeConverterFn.class,
MarketDataFn.class, DefaultMarketDataFn.class,
FXMatrixFn.class, DefaultFXMatrixFn.class,
HistoricalMarketDataFn.class, DefaultHistoricalMarketDataFn.class));
}
@Test
public void tradeAttributeExposureViaTradePass() {
FunctionModelConfig config = createFunctionModelConfig(InterestRateMockSources.mockTradeAttributeExposureFunctions());
ExposureFunctionsDiscountingMulticurveCombinerFn multicurveCombinerFunction =
FunctionModel.build(
ExposureFunctionsDiscountingMulticurveCombinerFn.class,
config,
ComponentMap.of(_components));
InterestRateFutureTrade trade = createInterestRateFutureTrade(true);
Result<MulticurveBundle> result = multicurveCombinerFunction.getMulticurveBundle(_environment, trade);
assertThat(result.isSuccess(), is((true)));
MulticurveProviderDiscount multicurveProviderDiscount = result.getValue().getMulticurveProvider();
assertThat(multicurveProviderDiscount.getAllCurveNames(),
containsInAnyOrder(
InterestRateMockSources.USD_LIBOR3M_CURVE_NAME,
InterestRateMockSources.USD_OIS_CURVE_NAME));
}
@Test
public void tradeAttributeExposureViaTradeFail() {
FunctionModelConfig config = createFunctionModelConfig(InterestRateMockSources.mockTradeAttributeExposureFunctions());
ExposureFunctionsDiscountingMulticurveCombinerFn multicurveCombinerFunction =
FunctionModel.build(
ExposureFunctionsDiscountingMulticurveCombinerFn.class,
config,
ComponentMap.of(_components));
InterestRateFutureTrade trade = createInterestRateFutureTrade(false);
Result<MulticurveBundle> result = multicurveCombinerFunction.getMulticurveBundle(_environment, trade);
//There are no curves for this trade defined in the exposure function, so the result should fail
assertThat(result.isSuccess(), is((false)));
}
@Test
public void counterpartyExposureViaTradePass() {
FunctionModelConfig config = createFunctionModelConfig(InterestRateMockSources.mockCounterpartyExposureFunctions());
ExposureFunctionsDiscountingMulticurveCombinerFn multicurveCombinerFunction =
FunctionModel.build(
ExposureFunctionsDiscountingMulticurveCombinerFn.class,
config,
ComponentMap.of(_components));
InterestRateFutureSecurity security = createInterestRateFutureSecurity(Currency.USD);
SimpleCounterparty counterparty = new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "PASS"));
InterestRateFutureTrade trade = createInterestRateFutureTrade(security, counterparty, true);
Result<MulticurveBundle> result = multicurveCombinerFunction.getMulticurveBundle(_environment, trade);
assertThat(result.isSuccess(), is((true)));
MulticurveProviderDiscount multicurveProviderDiscount = result.getValue().getMulticurveProvider();
assertThat(multicurveProviderDiscount.getAllCurveNames(),
containsInAnyOrder(
InterestRateMockSources.USD_LIBOR3M_CURVE_NAME,
InterestRateMockSources.USD_OIS_CURVE_NAME));
}
@Test
public void counterpartyExposureViaTradeFail() {
FunctionModelConfig config = createFunctionModelConfig(InterestRateMockSources.mockCounterpartyExposureFunctions());
ExposureFunctionsDiscountingMulticurveCombinerFn multicurveCombinerFunction =
FunctionModel.build(
ExposureFunctionsDiscountingMulticurveCombinerFn.class,
config,
ComponentMap.of(_components));
InterestRateFutureSecurity security = createInterestRateFutureSecurity(Currency.USD);
SimpleCounterparty counterparty = new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "FAIL"));
InterestRateFutureTrade trade = createInterestRateFutureTrade(security, counterparty, true);
Result<MulticurveBundle> result = multicurveCombinerFunction.getMulticurveBundle(_environment, trade);
//There are no curves for this counterparty defined in the exposure function, so the result should fail
assertThat(result.isSuccess(), is((false)));
}
@Test
public void currencyUsdExposureViaSecurityPass() {
FunctionModelConfig config = createFunctionModelConfig(InterestRateMockSources.mockCurrencyExposureFunctions());
ExposureFunctionsDiscountingMulticurveCombinerFn multicurveCombinerFunction =
FunctionModel.build(
ExposureFunctionsDiscountingMulticurveCombinerFn.class,
config,
ComponentMap.of(_components));
FRASecurity security = createSingleFra(Currency.USD);
Trade trade = new SimpleTrade(security,
BigDecimal.ONE,
new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "CPARTY")),
LocalDate.now(),
OffsetTime.now());
FraTrade tradeWrapper = new FraTrade(trade);
Result<MulticurveBundle> result = multicurveCombinerFunction.getMulticurveBundle(_environment, tradeWrapper);
assertThat(result.isSuccess(), is((true)));
MulticurveProviderDiscount multicurveProviderDiscount = result.getValue().getMulticurveProvider();
assertThat(multicurveProviderDiscount.getAllCurveNames(),
containsInAnyOrder(
InterestRateMockSources.USD_LIBOR3M_CURVE_NAME,
InterestRateMockSources.USD_OIS_CURVE_NAME));
}
@Test
public void currencyUsdExposureViaTradePass() {
FunctionModelConfig config = createFunctionModelConfig(InterestRateMockSources.mockCurrencyExposureFunctions());
ExposureFunctionsDiscountingMulticurveCombinerFn multicurveCombinerFunction =
FunctionModel.build(
ExposureFunctionsDiscountingMulticurveCombinerFn.class,
config,
ComponentMap.of(_components));
InterestRateFutureSecurity security = createInterestRateFutureSecurity(Currency.USD);
InterestRateFutureTrade trade = createInterestRateFutureTrade(security, true);
Result<MulticurveBundle> result = multicurveCombinerFunction.getMulticurveBundle(_environment, trade);
assertThat(result.isSuccess(), is((true)));
MulticurveProviderDiscount multicurveProviderDiscount = result.getValue().getMulticurveProvider();
assertThat(multicurveProviderDiscount.getAllCurveNames(),
containsInAnyOrder(
InterestRateMockSources.USD_LIBOR3M_CURVE_NAME,
InterestRateMockSources.USD_OIS_CURVE_NAME));
}
@Test
public void currencyGbpExposureViaTradeFail() {
FunctionModelConfig config = createFunctionModelConfig(InterestRateMockSources.mockCurrencyExposureFunctions());
ExposureFunctionsDiscountingMulticurveCombinerFn multicurveCombinerFunction =
FunctionModel.build(
ExposureFunctionsDiscountingMulticurveCombinerFn.class,
config,
ComponentMap.of(_components));
InterestRateFutureSecurity security = createInterestRateFutureSecurity(Currency.GBP);
InterestRateFutureTrade trade = createInterestRateFutureTrade(security, true);
Result<MulticurveBundle> result = multicurveCombinerFunction.getMulticurveBundle(_environment, trade);
//There are no GBP curves in the defined exposure function, so the result should fail
assertThat(result.isSuccess(), is((false)));
}
//Only used to test the deprecated security lookup
private FRASecurity createSingleFra(Currency currency) {
return new FRASecurity(currency,
ExternalSchemes.financialRegionId("US"),
DateUtils.getUTCDate(2014, 9, 12),
DateUtils.getUTCDate(2014, 12, 12),
0.0125,
-10000000,
InterestRateMockSources.getLiborIndexId(),
DateUtils.getUTCDate(2014, 1, 22));
}
private InterestRateFutureTrade createInterestRateFutureTrade(boolean pass) {
return createInterestRateFutureTrade(createInterestRateFutureSecurity(), pass);
}
private InterestRateFutureTrade createInterestRateFutureTrade(InterestRateFutureSecurity security, boolean pass) {
SimpleCounterparty counterparty = new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "TEST"));
return createInterestRateFutureTrade(security, counterparty, pass);
}
private InterestRateFutureTrade createInterestRateFutureTrade(InterestRateFutureSecurity security,
SimpleCounterparty counterparty,
boolean pass) {
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(security, tradeQuantity, counterparty, tradeDate, tradeTime);
trade.setPremium(0.0);
trade.setPremiumCurrency(security.getCurrency());
if (pass) {
trade.addAttribute("TEST", "PASS");
} else {
trade.addAttribute("TEST", "FAIL");
}
return new InterestRateFutureTrade(trade);
}
private InterestRateFutureSecurity createInterestRateFutureSecurity() {
return createInterestRateFutureSecurity(Currency.USD);
}
private InterestRateFutureSecurity createInterestRateFutureSecurity(Currency currency) {
Expiry expiry = new Expiry(ZonedDateTime.of(LocalDate.of(2014, 6, 18), LocalTime.of(0, 0), ZoneOffset.UTC));
String tradingExchange = "";
String settlementExchange = "";
double unitAmount = 1000;
ExternalId underlyingId = InterestRateMockSources.getLiborIndexId();
String category = "";
return new InterestRateFutureSecurity(expiry,
tradingExchange,
settlementExchange,
currency,
unitAmount,
underlyingId,
category);
}
}