diff --git a/modules/measure/src/main/java/com/opengamma/strata/measure/index/DefaultOvernightFutureOptionMarketData.java b/modules/measure/src/main/java/com/opengamma/strata/measure/index/DefaultOvernightFutureOptionMarketData.java new file mode 100644 index 0000000000..9e9efc8345 --- /dev/null +++ b/modules/measure/src/main/java/com/opengamma/strata/measure/index/DefaultOvernightFutureOptionMarketData.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2023 - present by OpenGamma Inc. and the OpenGamma group of companies + * + * Please see distribution for license. + */ +package com.opengamma.strata.measure.index; + +import java.io.Serializable; +import java.lang.invoke.MethodHandles; + +import org.joda.beans.ImmutableBean; +import org.joda.beans.JodaBeanUtils; +import org.joda.beans.MetaBean; +import org.joda.beans.TypedMetaBean; +import org.joda.beans.gen.BeanDefinition; +import org.joda.beans.gen.ImmutableConstructor; +import org.joda.beans.gen.PropertyDefinition; +import org.joda.beans.impl.light.LightMetaBean; + +import com.opengamma.strata.basics.index.OvernightIndex; +import com.opengamma.strata.collect.ArgChecker; +import com.opengamma.strata.data.MarketData; +import com.opengamma.strata.pricer.index.OvernightFutureOptionVolatilities; + +/** + * The default market data for Overnight future options. + *
+ * This uses a {@link OvernightFutureOptionMarketDataLookup} to provide a view on {@link MarketData}. + */ +@BeanDefinition(style = "light") +final class DefaultOvernightFutureOptionMarketData implements OvernightFutureOptionMarketData, ImmutableBean, Serializable { + + /** + * The lookup. + */ + @PropertyDefinition(validate = "notNull", overrideGet = true) + private final OvernightFutureOptionMarketDataLookup lookup; + /** + * The market data. + */ + @PropertyDefinition(validate = "notNull", overrideGet = true) + private final MarketData marketData; + + //------------------------------------------------------------------------- + /** + * Obtains an instance based on a lookup and market data. + *
+ * The lookup knows how to obtain the volatilities from the market data.
+ * This might involve accessing a surface or a cube.
+ *
+ * @param lookup the lookup
+ * @param marketData the market data
+ * @return the rates market view
+ */
+ public static DefaultOvernightFutureOptionMarketData of(
+ OvernightFutureOptionMarketDataLookup lookup,
+ MarketData marketData) {
+
+ return new DefaultOvernightFutureOptionMarketData(lookup, marketData);
+ }
+
+ @ImmutableConstructor
+ private DefaultOvernightFutureOptionMarketData(
+ OvernightFutureOptionMarketDataLookup lookup,
+ MarketData marketData) {
+
+ this.lookup = ArgChecker.notNull(lookup, "lookup");
+ this.marketData = ArgChecker.notNull(marketData, "marketData");
+ }
+
+ //-------------------------------------------------------------------------
+ @Override
+ public OvernightFutureOptionMarketData withMarketData(MarketData marketData) {
+ return DefaultOvernightFutureOptionMarketData.of(lookup, marketData);
+ }
+
+ //-------------------------------------------------------------------------
+ @Override
+ public OvernightFutureOptionVolatilities volatilities(OvernightIndex index) {
+ return lookup.volatilities(index, marketData);
+ }
+
+ //------------------------- AUTOGENERATED START -------------------------
+ /**
+ * The meta-bean for {@code DefaultOvernightFutureOptionMarketData}.
+ */
+ private static final TypedMetaBean
+ * This provides Overnight future option volatilities by index.
+ *
+ * The lookup implements {@link CalculationParameter} and is used by passing it
+ * as an argument to {@link CalculationRules}. It provides the link between the
+ * data that the function needs and the data that is available in {@link ScenarioMarketData}.
+ */
+@BeanDefinition(style = "light")
+final class DefaultOvernightFutureOptionMarketDataLookup
+ implements OvernightFutureOptionMarketDataLookup, ImmutableBean, Serializable {
+
+ /**
+ * The volatility identifiers, keyed by index.
+ */
+ @PropertyDefinition(validate = "notNull")
+ private final ImmutableMap
+ * The lookup provides volatilities for the specified index.
+ *
+ * @param index the Overnight index
+ * @param volatilityId the volatility identifier
+ * @return the Overnight future option lookup containing the specified mapping
+ */
+ public static DefaultOvernightFutureOptionMarketDataLookup of(OvernightIndex index, OvernightFutureOptionVolatilitiesId volatilityId) {
+ return new DefaultOvernightFutureOptionMarketDataLookup(ImmutableMap.of(index, volatilityId));
+ }
+
+ /**
+ * Obtains an instance based on a map of volatility identifiers.
+ *
+ * The map is used to specify the appropriate volatilities to use for each index.
+ *
+ * @param volatilityIds the volatility identifiers, keyed by index
+ * @return the Overnight future option lookup containing the specified volatilities
+ */
+ public static DefaultOvernightFutureOptionMarketDataLookup of(Map
+ * This uses a {@link OvernightFutureOptionMarketDataLookup} to provide a view on {@link ScenarioMarketData}.
+ */
+@BeanDefinition(style = "light")
+final class DefaultOvernightFutureOptionScenarioMarketData
+ implements OvernightFutureOptionScenarioMarketData, ImmutableBean, Serializable {
+
+ /**
+ * The lookup.
+ */
+ @PropertyDefinition(validate = "notNull", overrideGet = true)
+ private final OvernightFutureOptionMarketDataLookup lookup;
+ /**
+ * The market data.
+ */
+ @PropertyDefinition(validate = "notNull", overrideGet = true)
+ private final ScenarioMarketData marketData;
+
+ //-------------------------------------------------------------------------
+ /**
+ * Obtains an instance based on a lookup and market data.
+ *
+ * The lookup knows how to obtain the volatilities from the market data.
+ * This might involve accessing a surface or a cube.
+ *
+ * @param lookup the lookup
+ * @param marketData the market data
+ * @return the rates market view
+ */
+ public static DefaultOvernightFutureOptionScenarioMarketData of(
+ OvernightFutureOptionMarketDataLookup lookup,
+ ScenarioMarketData marketData) {
+
+ return new DefaultOvernightFutureOptionScenarioMarketData(lookup, marketData);
+ }
+
+ @ImmutableConstructor
+ private DefaultOvernightFutureOptionScenarioMarketData(
+ OvernightFutureOptionMarketDataLookup lookup,
+ ScenarioMarketData marketData) {
+
+ this.lookup = ArgChecker.notNull(lookup, "lookup");
+ this.marketData = ArgChecker.notNull(marketData, "marketData");
+ }
+
+ //-------------------------------------------------------------------------
+ @Override
+ public OvernightFutureOptionScenarioMarketData withMarketData(ScenarioMarketData marketData) {
+ return DefaultOvernightFutureOptionScenarioMarketData.of(lookup, marketData);
+ }
+
+ //-------------------------------------------------------------------------
+ @Override
+ public int getScenarioCount() {
+ return marketData.getScenarioCount();
+ }
+
+ @Override
+ public OvernightFutureOptionMarketData scenario(int scenarioIndex) {
+ return lookup.marketDataView(marketData.scenario(scenarioIndex));
+ }
+
+ //------------------------- AUTOGENERATED START -------------------------
+ /**
+ * The meta-bean for {@code DefaultOvernightFutureOptionScenarioMarketData}.
+ */
+ private static final TypedMetaBean
+ * This interface exposes the market data necessary for pricing an Overnight future option.
+ *
+ * Implementations of this interface must be immutable.
+ */
+public interface OvernightFutureOptionMarketData {
+
+ /**
+ * Gets the valuation date.
+ *
+ * @return the valuation date
+ */
+ public default LocalDate getValuationDate() {
+ return getMarketData().getValuationDate();
+ }
+
+ //-------------------------------------------------------------------------
+ /**
+ * Gets the lookup that provides access to Overnight future option volatilities.
+ *
+ * @return the Overnight future option lookup
+ */
+ public abstract OvernightFutureOptionMarketDataLookup getLookup();
+
+ /**
+ * Gets the market data.
+ *
+ * @return the market data
+ */
+ public abstract MarketData getMarketData();
+
+ /**
+ * Returns a copy of this instance with the specified market data.
+ *
+ * @param marketData the market data to use
+ * @return a market view based on the specified data
+ */
+ public abstract OvernightFutureOptionMarketData withMarketData(MarketData marketData);
+
+ //-------------------------------------------------------------------------
+ /**
+ * Gets the volatilities for the specified Overnight index.
+ *
+ * If the index is not found, an exception is thrown.
+ *
+ * @param index the Overnight index
+ * @return the volatilities for the index
+ * @throws MarketDataNotFoundException if the index is not found
+ */
+ public abstract OvernightFutureOptionVolatilities volatilities(OvernightIndex index);
+
+}
diff --git a/modules/measure/src/main/java/com/opengamma/strata/measure/index/OvernightFutureOptionMarketDataLookup.java b/modules/measure/src/main/java/com/opengamma/strata/measure/index/OvernightFutureOptionMarketDataLookup.java
new file mode 100644
index 0000000000..c8c4a8690e
--- /dev/null
+++ b/modules/measure/src/main/java/com/opengamma/strata/measure/index/OvernightFutureOptionMarketDataLookup.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2023 - present by OpenGamma Inc. and the OpenGamma group of companies
+ *
+ * Please see distribution for license.
+ */
+package com.opengamma.strata.measure.index;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.opengamma.strata.basics.index.OvernightIndex;
+import com.opengamma.strata.calc.CalculationRules;
+import com.opengamma.strata.calc.runner.CalculationParameter;
+import com.opengamma.strata.calc.runner.CalculationParameters;
+import com.opengamma.strata.calc.runner.FunctionRequirements;
+import com.opengamma.strata.data.MarketData;
+import com.opengamma.strata.data.MarketDataId;
+import com.opengamma.strata.data.MarketDataNotFoundException;
+import com.opengamma.strata.data.scenario.ScenarioMarketData;
+import com.opengamma.strata.pricer.index.OvernightFutureOptionVolatilities;
+import com.opengamma.strata.pricer.index.OvernightFutureOptionVolatilitiesId;
+
+/**
+ * The lookup that provides access to Overnight future option volatilities in market data.
+ *
+ * The Overnight future option market lookup provides access to the volatilities used to price Overnight future options.
+ *
+ * The lookup implements {@link CalculationParameter} and is used by passing it
+ * as an argument to {@link CalculationRules}. It provides the link between the
+ * data that the function needs and the data that is available in {@link ScenarioMarketData}.
+ *
+ * Implementations of this interface must be immutable.
+ */
+public interface OvernightFutureOptionMarketDataLookup extends CalculationParameter {
+
+ /**
+ * Obtains an instance based on a single mapping from index to volatility identifier.
+ *
+ * The lookup provides volatilities for the specified index.
+ *
+ * @param index the Overnight index
+ * @param volatilityId the volatility identifier
+ * @return the Overnight future option lookup containing the specified mapping
+ */
+ public static OvernightFutureOptionMarketDataLookup of(OvernightIndex index, OvernightFutureOptionVolatilitiesId volatilityId) {
+ return DefaultOvernightFutureOptionMarketDataLookup.of(ImmutableMap.of(index, volatilityId));
+ }
+
+ /**
+ * Obtains an instance based on a map of volatility identifiers.
+ *
+ * The map is used to specify the appropriate volatilities to use for each index.
+ *
+ * @param volatilityIds the volatility identifiers, keyed by index
+ * @return the Overnight future option lookup containing the specified volatilities
+ */
+ public static OvernightFutureOptionMarketDataLookup of(Map
+ * This returns {@code OvernightFutureOptionMarketLookup.class}.
+ * When querying parameters using {@link CalculationParameters#findParameter(Class)},
+ * {@code OvernightFutureOptionMarketLookup.class} must be passed in to find the instance.
+ *
+ * @return the type of the parameter implementation
+ */
+ @Override
+ public default Class extends CalculationParameter> queryType() {
+ return OvernightFutureOptionMarketDataLookup.class;
+ }
+
+ //-------------------------------------------------------------------------
+ /**
+ * Gets the set of indices that volatilities are provided for.
+ *
+ * @return the set of indices
+ */
+ public abstract ImmutableSet
+ * The result will typically refer to a surface or cube.
+ * If the index is not found, an exception is thrown.
+ *
+ * @param index the index for which identifiers are required
+ * @return the set of market data identifiers
+ * @throws IllegalArgumentException if the index is not found
+ */
+ public abstract ImmutableSet
+ * This method returns an instance that binds the lookup to the market data.
+ * The input is {@link ScenarioMarketData}, which contains market data for all scenarios.
+ *
+ * @param marketData the complete set of market data for all scenarios
+ * @return the filtered market data
+ */
+ public default OvernightFutureOptionScenarioMarketData marketDataView(ScenarioMarketData marketData) {
+ return DefaultOvernightFutureOptionScenarioMarketData.of(this, marketData);
+ }
+
+ /**
+ * Obtains a filtered view of the complete set of market data.
+ *
+ * This method returns an instance that binds the lookup to the market data.
+ * The input is {@link MarketData}, which contains market data for one scenario.
+ *
+ * @param marketData the complete set of market data for one scenario
+ * @return the filtered market data
+ */
+ public default OvernightFutureOptionMarketData marketDataView(MarketData marketData) {
+ return DefaultOvernightFutureOptionMarketData.of(this, marketData);
+ }
+
+ //-------------------------------------------------------------------------
+ /**
+ * Obtains Overnight future option volatilities based on the specified market data.
+ *
+ * This provides {@link OvernightFutureOptionVolatilities} suitable for pricing an Overnight future option.
+ * Although this method can be used directly, it is typically invoked indirectly
+ * via {@link OvernightFutureOptionMarketData}:
+ *
+ * This interface exposes the market data necessary for pricing an Overnight future option.
+ *
+ * Implementations of this interface must be immutable.
+ */
+public interface OvernightFutureOptionScenarioMarketData {
+
+ /**
+ * Gets the lookup that provides access to Overnight future option volatilities.
+ *
+ * @return the Overnight future option lookup
+ */
+ public abstract OvernightFutureOptionMarketDataLookup getLookup();
+
+ /**
+ * Gets the market data.
+ *
+ * @return the market data
+ */
+ public abstract ScenarioMarketData getMarketData();
+
+ /**
+ * Returns a copy of this instance with the specified market data.
+ *
+ * @param marketData the market data to use
+ * @return a market view based on the specified data
+ */
+ public abstract OvernightFutureOptionScenarioMarketData withMarketData(ScenarioMarketData marketData);
+
+ //-------------------------------------------------------------------------
+ /**
+ * Gets the number of scenarios.
+ *
+ * @return the number of scenarios
+ */
+ public abstract int getScenarioCount();
+
+ /**
+ * Returns market data for a single scenario.
+ *
+ * This returns a view of the market data for the specified scenario.
+ *
+ * @param scenarioIndex the scenario index
+ * @return the market data for the specified scenario
+ * @throws IndexOutOfBoundsException if the scenario index is invalid
+ */
+ public abstract OvernightFutureOptionMarketData scenario(int scenarioIndex);
+
+}
diff --git a/modules/measure/src/test/java/com/opengamma/strata/measure/index/OvernightFutureOptionMarketDataLookupTest.java b/modules/measure/src/test/java/com/opengamma/strata/measure/index/OvernightFutureOptionMarketDataLookupTest.java
new file mode 100644
index 0000000000..a05ea88848
--- /dev/null
+++ b/modules/measure/src/test/java/com/opengamma/strata/measure/index/OvernightFutureOptionMarketDataLookupTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2023 - present by OpenGamma Inc. and the OpenGamma group of companies
+ *
+ * Please see distribution for license.
+ */
+package com.opengamma.strata.measure.index;
+
+import static com.opengamma.strata.basics.index.OvernightIndices.GBP_SONIA;
+import static com.opengamma.strata.basics.index.OvernightIndices.USD_FED_FUND;
+import static com.opengamma.strata.basics.index.OvernightIndices.USD_SOFR;
+import static com.opengamma.strata.collect.TestHelper.assertSerialization;
+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.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.time.LocalDate;
+
+import org.joda.beans.ImmutableBean;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.opengamma.strata.basics.index.OvernightIndex;
+import com.opengamma.strata.calc.runner.FunctionRequirements;
+import com.opengamma.strata.data.MarketData;
+import com.opengamma.strata.data.scenario.ScenarioMarketData;
+import com.opengamma.strata.measure.curve.TestMarketDataMap;
+import com.opengamma.strata.pricer.index.OvernightFutureOptionVolatilities;
+import com.opengamma.strata.pricer.index.OvernightFutureOptionVolatilitiesId;
+
+/**
+ * Test {@link OvernightFutureOptionMarketDataLookup}.
+ */
+public class OvernightFutureOptionMarketDataLookupTest {
+
+ private static final OvernightFutureOptionVolatilitiesId VOL_ID1 = OvernightFutureOptionVolatilitiesId.of("USD1");
+ private static final OvernightFutureOptionVolatilities MOCK_VOLS = mock(OvernightFutureOptionVolatilities.class);
+ private static final MarketData MOCK_MARKET_DATA = mock(MarketData.class);
+ private static final ScenarioMarketData MOCK_CALC_MARKET_DATA = mock(ScenarioMarketData.class);
+
+ static {
+ when(MOCK_MARKET_DATA.getValue(VOL_ID1)).thenReturn(MOCK_VOLS);
+ }
+
+ //-------------------------------------------------------------------------
+ @Test
+ public void test_of_single() {
+ OvernightFutureOptionMarketDataLookup test = OvernightFutureOptionMarketDataLookup.of(USD_SOFR, VOL_ID1);
+ assertThat(test.queryType()).isEqualTo(OvernightFutureOptionMarketDataLookup.class);
+ assertThat(test.getVolatilityIndices()).containsOnly(USD_SOFR);
+ assertThat(test.getVolatilityIds(USD_SOFR)).containsOnly(VOL_ID1);
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> test.getVolatilityIds(GBP_SONIA));
+
+ assertThat(test.requirements(USD_SOFR)).isEqualTo(FunctionRequirements.builder().valueRequirements(VOL_ID1).build());
+ assertThat(test.requirements(ImmutableSet.of(USD_SOFR)))
+ .isEqualTo(FunctionRequirements.builder().valueRequirements(VOL_ID1).build());
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> test.requirements(ImmutableSet.of(GBP_SONIA)));
+ }
+
+ @Test
+ public void test_of_map() {
+ ImmutableMap
+ * // bind the baseData to this lookup
+ * OvernightFutureOptionMarketData view = lookup.marketDataView(baseData);
+ *
+ * // pass around OvernightFutureOptionMarketData within the function to use in pricing
+ * OvernightFutureOptionVolatilities vols = view.volatilities(index);
+ *
+ *
+ * @param index the Overnight index
+ * @param marketData the complete set of market data for one scenario
+ * @return the volatilities
+ * @throws MarketDataNotFoundException if the index is not found
+ */
+ public abstract OvernightFutureOptionVolatilities volatilities(OvernightIndex index, MarketData marketData);
+
+}
diff --git a/modules/measure/src/main/java/com/opengamma/strata/measure/index/OvernightFutureOptionScenarioMarketData.java b/modules/measure/src/main/java/com/opengamma/strata/measure/index/OvernightFutureOptionScenarioMarketData.java
new file mode 100644
index 0000000000..f0ac64ac04
--- /dev/null
+++ b/modules/measure/src/main/java/com/opengamma/strata/measure/index/OvernightFutureOptionScenarioMarketData.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 - present by OpenGamma Inc. and the OpenGamma group of companies
+ *
+ * Please see distribution for license.
+ */
+package com.opengamma.strata.measure.index;
+
+import com.opengamma.strata.data.scenario.ScenarioMarketData;
+
+/**
+ * Market data for Overnight future options, used for calculation across multiple scenarios.
+ *