/**
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.measure.bond;
import static com.opengamma.strata.basics.currency.Currency.GBP;
import static com.opengamma.strata.basics.currency.Currency.USD;
import static com.opengamma.strata.basics.date.DayCounts.ACT_360;
import static com.opengamma.strata.collect.TestHelper.assertSerialization;
import static com.opengamma.strata.collect.TestHelper.assertThrowsIllegalArg;
import static com.opengamma.strata.collect.TestHelper.coverBeanEquals;
import static com.opengamma.strata.collect.TestHelper.coverImmutableBean;
import static com.opengamma.strata.collect.TestHelper.date;
import static org.mockito.Mockito.mock;
import static org.testng.Assert.assertEquals;
import java.time.LocalDate;
import java.util.Optional;
import org.joda.beans.ImmutableBean;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.opengamma.strata.basics.StandardId;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.calc.runner.FunctionRequirements;
import com.opengamma.strata.collect.tuple.Pair;
import com.opengamma.strata.data.ImmutableMarketData;
import com.opengamma.strata.data.MarketData;
import com.opengamma.strata.data.ObservableSource;
import com.opengamma.strata.data.scenario.ScenarioMarketData;
import com.opengamma.strata.market.curve.ConstantCurve;
import com.opengamma.strata.market.curve.Curve;
import com.opengamma.strata.market.curve.CurveId;
import com.opengamma.strata.market.curve.CurveName;
import com.opengamma.strata.market.curve.Curves;
import com.opengamma.strata.measure.curve.TestMarketDataMap;
import com.opengamma.strata.pricer.SimpleDiscountFactors;
import com.opengamma.strata.pricer.bond.IssuerCurveDiscountFactors;
import com.opengamma.strata.pricer.bond.LegalEntityDiscountingProvider;
import com.opengamma.strata.pricer.bond.LegalEntityGroup;
import com.opengamma.strata.pricer.bond.RepoCurveDiscountFactors;
import com.opengamma.strata.pricer.bond.RepoGroup;
import com.opengamma.strata.product.SecurityId;
/**
* Test {@link LegalEntityDiscountingMarketDataLookup}.
*/
@Test
public class LegalEntityDiscountingMarketDataLookupTest {
private static final SecurityId SEC_A1 = SecurityId.of("OG-Bond", "A1");
private static final SecurityId SEC_A2 = SecurityId.of("OG-Bond", "A2");
private static final SecurityId SEC_B1 = SecurityId.of("OG-Bond", "B1");
private static final SecurityId SEC_C1 = SecurityId.of("OG-Bond", "C1");
private static final SecurityId SEC_D1 = SecurityId.of("OG-Bond", "D1");
private static final StandardId ISSUER_A = StandardId.of("OG-LegEnt", "A");
private static final StandardId ISSUER_B = StandardId.of("OG-LegEnt", "B");
private static final StandardId ISSUER_C = StandardId.of("OG-LegEnt", "C");
private static final StandardId ISSUER_D = StandardId.of("OG-LegEnt", "D");
private static final RepoGroup GROUP_REPO_X = RepoGroup.of("X");
private static final RepoGroup GROUP_REPO_Y = RepoGroup.of("Y");
private static final LegalEntityGroup GROUP_ISSUER_M = LegalEntityGroup.of("M");
private static final LegalEntityGroup GROUP_ISSUER_N = LegalEntityGroup.of("N");
private static final CurveId CURVE_ID_USD1 = CurveId.of("Group", "USD1");
private static final CurveId CURVE_ID_USD2 = CurveId.of("Group", "USD2");
private static final CurveId CURVE_ID_USD3 = CurveId.of("Group", "USD3");
private static final CurveId CURVE_ID_USD4 = CurveId.of("Group", "USD4");
private static final CurveId CURVE_ID_GBP1 = CurveId.of("Group", "GBP1");
private static final CurveId CURVE_ID_GBP2 = CurveId.of("Group", "GBP2");
private static final ObservableSource OBS_SOURCE = ObservableSource.of("Vendor");
private static final MarketData MOCK_MARKET_DATA = mock(MarketData.class);
private static final ScenarioMarketData MOCK_CALC_MARKET_DATA = mock(ScenarioMarketData.class);
//-------------------------------------------------------------------------
public void test_of_map() {
ImmutableMap<StandardId, RepoGroup> repoGroups = ImmutableMap.of(
SEC_A1.getStandardId(), GROUP_REPO_X,
ISSUER_A, GROUP_REPO_Y,
ISSUER_B, GROUP_REPO_Y,
ISSUER_C, GROUP_REPO_Y,
ISSUER_D, GROUP_REPO_Y);
ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves = ImmutableMap.of(
Pair.of(GROUP_REPO_X, USD), CURVE_ID_USD1,
Pair.of(GROUP_REPO_Y, USD), CURVE_ID_USD2,
Pair.of(GROUP_REPO_Y, GBP), CURVE_ID_GBP1);
ImmutableMap<StandardId, LegalEntityGroup> issuerGroups = ImmutableMap.of(
ISSUER_A, GROUP_ISSUER_M,
ISSUER_B, GROUP_ISSUER_N,
ISSUER_C, GROUP_ISSUER_M);
ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves = ImmutableMap.of(
Pair.of(GROUP_ISSUER_M, USD), CURVE_ID_USD3,
Pair.of(GROUP_ISSUER_N, USD), CURVE_ID_USD4,
Pair.of(GROUP_ISSUER_N, GBP), CURVE_ID_GBP2);
LegalEntityDiscountingMarketDataLookup test =
LegalEntityDiscountingMarketDataLookup.of(repoGroups, repoCurves, issuerGroups, issuerCurves);
assertEquals(test.queryType(), LegalEntityDiscountingMarketDataLookup.class);
assertEquals(
test.requirements(SEC_A1, ISSUER_A, USD),
FunctionRequirements.builder().valueRequirements(CURVE_ID_USD1, CURVE_ID_USD3).outputCurrencies(USD).build());
assertEquals(
test.requirements(SEC_A2, ISSUER_A, USD),
FunctionRequirements.builder().valueRequirements(CURVE_ID_USD2, CURVE_ID_USD3).outputCurrencies(USD).build());
assertEquals(
test.requirements(SEC_B1, ISSUER_B, USD),
FunctionRequirements.builder().valueRequirements(CURVE_ID_USD2, CURVE_ID_USD4).outputCurrencies(USD).build());
assertEquals(
test.requirements(SEC_B1, ISSUER_B, GBP),
FunctionRequirements.builder().valueRequirements(CURVE_ID_GBP1, CURVE_ID_GBP2).outputCurrencies(GBP).build());
assertThrowsIllegalArg(() -> test.requirements(SEC_B1, StandardId.of("XXX", "XXX"), GBP));
assertThrowsIllegalArg(() -> test.requirements(SecurityId.of("XXX", "XXX"), StandardId.of("XXX", "XXX"), GBP));
assertThrowsIllegalArg(() -> test.requirements(SEC_A1, ISSUER_A, GBP));
assertThrowsIllegalArg(() -> test.requirements(SEC_C1, ISSUER_C, GBP));
assertThrowsIllegalArg(() -> test.requirements(SEC_D1, ISSUER_D, GBP));
assertEquals(
test.discountingProvider(MOCK_MARKET_DATA),
DefaultLookupLegalEntityDiscountingProvider.of((DefaultLegalEntityDiscountingMarketDataLookup) test, MOCK_MARKET_DATA));
}
//-------------------------------------------------------------------------
public void test_of_map_invalid() {
ImmutableMap<StandardId, RepoGroup> repoGroups = ImmutableMap.of(
SEC_A1.getStandardId(), GROUP_REPO_X);
ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves = ImmutableMap.of(
Pair.of(GROUP_REPO_X, USD), CURVE_ID_USD1);
ImmutableMap<StandardId, LegalEntityGroup> issuerGroups = ImmutableMap.of(
ISSUER_A, GROUP_ISSUER_M);
ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves = ImmutableMap.of(
Pair.of(GROUP_ISSUER_M, USD), CURVE_ID_USD3);
assertThrowsIllegalArg(() -> LegalEntityDiscountingMarketDataLookup.of(
repoGroups, ImmutableMap.of(), issuerGroups, issuerCurves));
assertThrowsIllegalArg(() -> LegalEntityDiscountingMarketDataLookup.of(
repoGroups, repoCurves, issuerGroups, ImmutableMap.of()));
}
//-------------------------------------------------------------------------
public void test_marketDataView() {
ImmutableMap<StandardId, RepoGroup> repoGroups = ImmutableMap.of(
SEC_A1.getStandardId(), GROUP_REPO_X);
ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves = ImmutableMap.of(
Pair.of(GROUP_REPO_X, USD), CURVE_ID_USD1);
ImmutableMap<StandardId, LegalEntityGroup> issuerGroups = ImmutableMap.of(
ISSUER_A, GROUP_ISSUER_M);
ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves = ImmutableMap.of(
Pair.of(GROUP_ISSUER_M, USD), CURVE_ID_USD3);
LegalEntityDiscountingMarketDataLookup test =
LegalEntityDiscountingMarketDataLookup.of(repoGroups, repoCurves, issuerGroups, issuerCurves);
LocalDate valDate = date(2015, 6, 30);
ScenarioMarketData md = new TestMarketDataMap(valDate, ImmutableMap.of(), ImmutableMap.of());
LegalEntityDiscountingScenarioMarketData multiScenario = test.marketDataView(md);
assertEquals(multiScenario.getLookup(), test);
assertEquals(multiScenario.getMarketData(), md);
assertEquals(multiScenario.getScenarioCount(), 1);
LegalEntityDiscountingMarketData scenario = multiScenario.scenario(0);
assertEquals(scenario.getLookup(), test);
assertEquals(scenario.getMarketData(), md.scenario(0));
assertEquals(scenario.getValuationDate(), valDate);
}
public void test_bondDiscountingProvider() {
ImmutableMap<StandardId, RepoGroup> repoGroups = ImmutableMap.of(
SEC_A1.getStandardId(), GROUP_REPO_X, ISSUER_B, GROUP_REPO_X);
ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves = ImmutableMap.of(
Pair.of(GROUP_REPO_X, USD), CURVE_ID_USD1);
ImmutableMap<StandardId, LegalEntityGroup> issuerGroups = ImmutableMap.of(
ISSUER_A, GROUP_ISSUER_M);
ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves = ImmutableMap.of(
Pair.of(GROUP_ISSUER_M, USD), CURVE_ID_USD3);
LegalEntityDiscountingMarketDataLookup test =
LegalEntityDiscountingMarketDataLookup.of(repoGroups, repoCurves, issuerGroups, issuerCurves);
LocalDate valDate = date(2015, 6, 30);
Curve repoCurve = ConstantCurve.of(Curves.discountFactors(CURVE_ID_USD1.getCurveName(), ACT_360), 1d);
Curve issuerCurve = ConstantCurve.of(Curves.discountFactors(CURVE_ID_USD3.getCurveName(), ACT_360), 2d);
MarketData md = ImmutableMarketData.of(valDate, ImmutableMap.of(CURVE_ID_USD1, repoCurve, CURVE_ID_USD3, issuerCurve));
LegalEntityDiscountingProvider provider = test.discountingProvider(md);
assertEquals(provider.getValuationDate(), valDate);
assertEquals(provider.findData(CURVE_ID_USD1.getCurveName()), Optional.of(repoCurve));
assertEquals(provider.findData(CURVE_ID_USD3.getCurveName()), Optional.of(issuerCurve));
assertEquals(provider.findData(CurveName.of("Rubbish")), Optional.empty());
// check repo
RepoCurveDiscountFactors rcdf = provider.repoCurveDiscountFactors(SEC_A1, ISSUER_A, USD);
SimpleDiscountFactors rdf = (SimpleDiscountFactors) rcdf.getDiscountFactors();
assertEquals(rdf.getCurve().getName(), repoCurve.getName());
assertEquals(rcdf, provider.repoCurveDiscountFactors(SEC_B1, ISSUER_B, USD));
assertThrowsIllegalArg(() -> provider.repoCurveDiscountFactors(SEC_A1, ISSUER_A, GBP));
assertThrowsIllegalArg(() -> provider.repoCurveDiscountFactors(SEC_C1, ISSUER_C, USD));
// check issuer
IssuerCurveDiscountFactors icdf = provider.issuerCurveDiscountFactors(ISSUER_A, USD);
SimpleDiscountFactors idf = (SimpleDiscountFactors) icdf.getDiscountFactors();
assertEquals(idf.getCurve().getName(), issuerCurve.getName());
assertThrowsIllegalArg(() -> provider.issuerCurveDiscountFactors(ISSUER_A, GBP));
assertThrowsIllegalArg(() -> provider.issuerCurveDiscountFactors(ISSUER_C, USD));
}
//-------------------------------------------------------------------------
public void coverage() {
ImmutableMap<StandardId, RepoGroup> repoGroups = ImmutableMap.of(
SEC_A1.getStandardId(), GROUP_REPO_X, ISSUER_A, GROUP_REPO_Y, ISSUER_B, GROUP_REPO_Y);
ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves = ImmutableMap.of(
Pair.of(GROUP_REPO_X, USD), CURVE_ID_USD1,
Pair.of(GROUP_REPO_Y, USD), CURVE_ID_USD2,
Pair.of(GROUP_REPO_Y, GBP), CURVE_ID_GBP1);
ImmutableMap<StandardId, LegalEntityGroup> issuerGroups = ImmutableMap.of(
ISSUER_A, GROUP_ISSUER_M, ISSUER_B, GROUP_ISSUER_N);
ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves = ImmutableMap.of(
Pair.of(GROUP_ISSUER_M, USD), CURVE_ID_USD3,
Pair.of(GROUP_ISSUER_N, USD), CURVE_ID_USD4,
Pair.of(GROUP_ISSUER_N, GBP), CURVE_ID_GBP2);
LegalEntityDiscountingMarketDataLookup test =
LegalEntityDiscountingMarketDataLookup.of(repoGroups, repoCurves, issuerGroups, issuerCurves);
coverImmutableBean((ImmutableBean) test);
ImmutableMap<StandardId, RepoGroup> repoGroups2 = ImmutableMap.of();
ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves2 = ImmutableMap.of();
ImmutableMap<StandardId, LegalEntityGroup> issuerGroups2 = ImmutableMap.of();
ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves2 = ImmutableMap.of();
LegalEntityDiscountingMarketDataLookup test2 =
LegalEntityDiscountingMarketDataLookup.of(repoGroups2, repoCurves2, issuerGroups2, issuerCurves2, OBS_SOURCE);
coverBeanEquals((ImmutableBean) test, (ImmutableBean) test2);
// related coverage
coverImmutableBean((ImmutableBean) test.marketDataView(MOCK_CALC_MARKET_DATA));
DefaultLegalEntityDiscountingScenarioMarketData.meta();
coverImmutableBean((ImmutableBean) test.marketDataView(MOCK_MARKET_DATA));
DefaultLegalEntityDiscountingMarketData.meta();
coverImmutableBean((ImmutableBean) test.marketDataView(MOCK_MARKET_DATA).discountingProvider());
DefaultLookupLegalEntityDiscountingProvider.meta();
}
public void test_serialization() {
ImmutableMap<StandardId, RepoGroup> repoGroups = ImmutableMap.of(
SEC_A1.getStandardId(), GROUP_REPO_X, ISSUER_A, GROUP_REPO_Y, ISSUER_B, GROUP_REPO_Y);
ImmutableMap<Pair<RepoGroup, Currency>, CurveId> repoCurves = ImmutableMap.of(
Pair.of(GROUP_REPO_X, USD), CURVE_ID_USD1,
Pair.of(GROUP_REPO_Y, USD), CURVE_ID_USD2,
Pair.of(GROUP_REPO_Y, GBP), CURVE_ID_GBP1);
ImmutableMap<StandardId, LegalEntityGroup> issuerGroups = ImmutableMap.of(
ISSUER_A, GROUP_ISSUER_M, ISSUER_B, GROUP_ISSUER_N);
ImmutableMap<Pair<LegalEntityGroup, Currency>, CurveId> issuerCurves = ImmutableMap.of(
Pair.of(GROUP_ISSUER_M, USD), CURVE_ID_USD3,
Pair.of(GROUP_ISSUER_N, USD), CURVE_ID_USD4,
Pair.of(GROUP_ISSUER_N, GBP), CURVE_ID_GBP2);
LegalEntityDiscountingMarketDataLookup test =
LegalEntityDiscountingMarketDataLookup.of(repoGroups, repoCurves, issuerGroups, issuerCurves);
assertSerialization(test);
}
}