Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

Expand All @@ -18,6 +19,7 @@
import org.joda.beans.MetaBean;
import org.joda.beans.TypedMetaBean;
import org.joda.beans.gen.BeanDefinition;
import org.joda.beans.gen.ImmutableValidator;
import org.joda.beans.gen.PropertyDefinition;
import org.joda.beans.impl.light.LightMetaBean;

Expand Down Expand Up @@ -195,6 +197,27 @@ String msgIndexNotFound(Index index) {
return Messages.format("Rates lookup has no forward curve defined for index '{}'", index);
}

@ImmutableValidator
private void validate() {
validateObservableSource(forwardCurves.values());
validateObservableSource(discountCurves.values());
}

/**
* Checks that the observable source in this instance matches the source in the IDs.
*/
private void validateObservableSource(Collection<CurveId> curveIds) {
for (CurveId curveId : curveIds) {
if (!curveId.getObservableSource().equals(observableSource)) {
throw new IllegalArgumentException(
Messages.format(
"The observable source '{}' must match the observable source in all curve IDs but found {}",
observableSource,
curveId));
}
}
}

//------------------------- AUTOGENERATED START -------------------------
/**
* The meta-bean for {@code DefaultRatesMarketDataLookup}.
Expand Down Expand Up @@ -244,6 +267,7 @@ private DefaultRatesMarketDataLookup(
this.forwardCurves = ImmutableMap.copyOf(forwardCurves);
this.observableSource = observableSource;
this.fxRateLookup = fxRateLookup;
validate();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,16 @@ public static RatesMarketDataLookup of(RatesCurveGroupDefinition curveGroupDefin
* @param fxLookup the lookup used to obtain FX rates
* @return the rates lookup based on the specified group
*/
public static RatesMarketDataLookup of(RatesCurveGroupDefinition curveGroupDefinition,
public static RatesMarketDataLookup of(
RatesCurveGroupDefinition curveGroupDefinition,
ObservableSource observableSource,
FxRateLookup fxLookup) {

CurveGroupName groupName = curveGroupDefinition.getName();
Map<Currency, CurveId> discountCurves = new HashMap<>();
Map<Index, CurveId> forwardCurves = new HashMap<>();
for (RatesCurveGroupEntry entry : curveGroupDefinition.getEntries()) {
CurveId curveId = CurveId.of(groupName, entry.getCurveName());
CurveId curveId = CurveId.of(groupName, entry.getCurveName(), observableSource);
entry.getDiscountCurrencies().forEach(ccy -> discountCurves.put(ccy, curveId));
entry.getIndices().forEach(idx -> forwardCurves.put(idx, curveId));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2019 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.measure.rate;

import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;

import java.util.Map;

import org.testng.annotations.Test;

import com.google.common.collect.ImmutableMap;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.index.IborIndex;
import com.opengamma.strata.basics.index.IborIndices;
import com.opengamma.strata.calc.runner.FxRateLookup;
import com.opengamma.strata.data.ObservableSource;
import com.opengamma.strata.market.curve.CurveGroupName;
import com.opengamma.strata.market.curve.CurveId;
import com.opengamma.strata.market.curve.CurveName;

@Test
public class DefaultRatesMarketDataLookupTest {

/**
* Validates the observable source in the curve IDs match the observable source passed in.
*/
public void validateObservableSourceDiscountCurves() {
ObservableSource observableSource = ObservableSource.of("source");
CurveId curveId = CurveId.of(CurveGroupName.of("group"), CurveName.of("curves"), observableSource);
Map<Currency, CurveId> curveMap = ImmutableMap.of(Currency.USD, curveId);
// This should complete successfully
DefaultRatesMarketDataLookup.of(curveMap, ImmutableMap.of(), observableSource, FxRateLookup.ofRates());
// This should blow up because the source in the IDs doesn't match the source passed to the method
assertThatIllegalArgumentException()
.isThrownBy(() ->
DefaultRatesMarketDataLookup.of(curveMap, ImmutableMap.of(), ObservableSource.NONE, FxRateLookup.ofRates()))
.withMessageContaining("must match the observable source in all curve IDs");
}

/**
* Validates the observable source in the curve IDs match the observable source passed in.
*/
public void validateObservableSourceForwardCurves() {
ObservableSource observableSource = ObservableSource.of("source");
CurveId curveId = CurveId.of(CurveGroupName.of("group"), CurveName.of("curves"), observableSource);
Map<IborIndex, CurveId> curveMap = ImmutableMap.of(IborIndices.AUD_BBSW_1M, curveId);
// This should complete successfully
DefaultRatesMarketDataLookup.of(ImmutableMap.of(), curveMap, observableSource, FxRateLookup.ofRates());
// This should blow up because the source in the IDs doesn't match the source passed to the method
assertThatIllegalArgumentException()
.isThrownBy(() ->
DefaultRatesMarketDataLookup.of(ImmutableMap.of(), curveMap, ObservableSource.NONE, FxRateLookup.ofRates()))
.withMessageContaining("must match the observable source in all curve IDs");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
import static org.testng.Assert.assertEquals;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.joda.beans.ImmutableBean;
import org.joda.beans.ser.JodaBeanSer;
import org.testng.annotations.Test;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.opengamma.strata.basics.currency.Currency;
Expand All @@ -53,10 +55,13 @@
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.CurveGroupName;
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.market.curve.RatesCurveGroup;
import com.opengamma.strata.market.curve.RatesCurveGroupDefinition;
import com.opengamma.strata.market.curve.RatesCurveGroupEntry;
import com.opengamma.strata.market.observable.IndexQuoteId;
import com.opengamma.strata.measure.curve.TestMarketDataMap;
import com.opengamma.strata.pricer.SimpleDiscountFactors;
Expand Down Expand Up @@ -146,6 +151,35 @@ public void test_of_curveGroup() {
assertThrowsIllegalArg(() -> test.getForwardMarketDataIds(GBP_LIBOR_3M));
}

public void test_of_curveGroupDefinition_and_observableSource() {
RatesCurveGroupEntry entry1 = RatesCurveGroupEntry.builder()
.curveName(CURVE_ID_DSC.getCurveName())
.discountCurrencies(USD)
.build();

RatesCurveGroupEntry entry2 = RatesCurveGroupEntry.builder()
.curveName(CURVE_ID_FWD.getCurveName())
.indices(USD_LIBOR_3M)
.build();

List<RatesCurveGroupEntry> entries = ImmutableList.of(entry1, entry2);
CurveGroupName groupName = CURVE_ID_DSC.getCurveGroupName();
RatesCurveGroupDefinition groupDefinition = RatesCurveGroupDefinition.of(groupName, entries, ImmutableList.of());

// The lookup should contain curve IDs with the non-default ObservableSource
CurveId dscId = CurveId.of(CURVE_ID_DSC.getCurveGroupName(), CURVE_ID_DSC.getCurveName(), OBS_SOURCE);
CurveId fwdId = CurveId.of(CURVE_ID_FWD.getCurveGroupName(), CURVE_ID_FWD.getCurveName(), OBS_SOURCE);

RatesMarketDataLookup test = RatesMarketDataLookup.of(groupDefinition, OBS_SOURCE, FxRateLookup.ofRates());
assertEquals(test.queryType(), RatesMarketDataLookup.class);
assertEquals(test.getDiscountCurrencies(), ImmutableSet.of(USD));
assertEquals(test.getDiscountMarketDataIds(USD), ImmutableSet.of(dscId));
assertEquals(test.getForwardIndices(), ImmutableSet.of(USD_LIBOR_3M));
assertEquals(test.getForwardMarketDataIds(USD_LIBOR_3M), ImmutableSet.of(fwdId));
assertThrowsIllegalArg(() -> test.getDiscountMarketDataIds(GBP));
assertThrowsIllegalArg(() -> test.getForwardMarketDataIds(GBP_LIBOR_3M));
}

//-------------------------------------------------------------------------
public void test_marketDataView() {
ImmutableMap<Currency, CurveId> discounts = ImmutableMap.of(USD, CURVE_ID_DSC);
Expand Down Expand Up @@ -243,7 +277,7 @@ public void coverage() {
ImmutableMap<Currency, CurveId> discounts2 = ImmutableMap.of(GBP, CURVE_ID_DSC);
ImmutableMap<Index, CurveId> forwards2 = ImmutableMap.of(GBP_LIBOR_3M, CURVE_ID_FWD);
DefaultRatesMarketDataLookup test2 =
DefaultRatesMarketDataLookup.of(discounts2, forwards2, OBS_SOURCE, FxRateLookup.ofRates(EUR));
DefaultRatesMarketDataLookup.of(discounts2, forwards2, ObservableSource.NONE, FxRateLookup.ofRates(EUR));
coverBeanEquals(test, test2);

// related coverage
Expand Down