/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.data;
import java.time.LocalDate;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import com.opengamma.strata.basics.currency.FxRate;
import com.opengamma.strata.collect.Messages;
import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeries;
/**
* Provides access to market data, such as curves, surfaces and time-series.
* <p>
* Market data is looked up using subclasses of {@link MarketDataId}.
* All data is valid for a single date, defined by {@link #getValuationDate()}.
* When performing calculations with scenarios, only the data of a single scenario is accessible.
* <p>
* The standard implementation is {@link ImmutableMarketData}.
*/
public interface MarketData {
/**
* Obtains an instance from a valuation date and map of values.
* <p>
* Each entry in the map is a single piece of market data, keyed by the matching identifier.
* For example, an {@link FxRate} can be looked up using an {@link FxRateId}.
* The caller must ensure that the each entry in the map corresponds with the parameterized
* type on the identifier.
*
* @param valuationDate the valuation date of the market data
* @param values the market data values
* @return the market data instance containing the values in the map
* @throws ClassCastException if a value does not match the parameterized type associated with the identifier
*/
public static MarketData of(LocalDate valuationDate, Map<? extends MarketDataId<?>, ?> values) {
return ImmutableMarketData.of(valuationDate, values);
}
/**
* Obtains an instance from a valuation date, map of values and time-series.
*
* @param valuationDate the valuation date of the market data
* @param values the market data values
* @param timeSeries the time-series
* @return the market data instance containing the values in the map and the time-series
* @throws ClassCastException if a value does not match the parameterized type associated with the identifier
*/
public static MarketData of(
LocalDate valuationDate,
Map<? extends MarketDataId<?>, ?> values,
Map<? extends ObservableId, LocalDateDoubleTimeSeries> timeSeries) {
return ImmutableMarketData.builder(valuationDate).values(values).timeSeries(timeSeries).build();
}
/**
* Obtains an instance containing no market data.
*
* @param valuationDate the valuation date of the market data
* @return empty market data
*/
public static MarketData empty(LocalDate valuationDate) {
return ImmutableMarketData.builder(valuationDate).build();
}
//-------------------------------------------------------------------------
/**
* Gets the valuation date of the market data.
* <p>
* All values accessible through this interface have the same valuation date.
*
* @return the valuation date
*/
public abstract LocalDate getValuationDate();
//-------------------------------------------------------------------------
/**
* Checks if this market data contains a value for the specified identifier.
*
* @param id the identifier to find
* @return true if the market data contains a value for the identifier
*/
public default boolean containsValue(MarketDataId<?> id) {
return findValue(id).isPresent();
}
/**
* Gets the market data value associated with the specified identifier.
* <p>
* If this market data instance contains the identifier, the value will be returned.
* Otherwise, an exception will be thrown.
*
* @param <T> the type of the market data value
* @param id the identifier to find
* @return the market data value
* @throws MarketDataNotFoundException if the identifier is not found
*/
public default <T> T getValue(MarketDataId<T> id) {
return findValue(id)
.orElseThrow(() -> new MarketDataNotFoundException(Messages.format(
"Market data not found for '{}' of type '{}'", id, id.getClass().getSimpleName())));
}
/**
* Finds the market data value associated with the specified identifier.
* <p>
* If this market data instance contains the identifier, the value will be returned.
* Otherwise, an empty optional will be returned.
*
* @param <T> the type of the market data value
* @param id the identifier to find
* @return the market data value, empty if not found
*/
public abstract <T> Optional<T> findValue(MarketDataId<T> id);
//-------------------------------------------------------------------------
/**
* Gets the market data identifiers.
*
* @return the set of market data identifiers
*/
public abstract Set<MarketDataId<?>> getIds();
/**
* Finds the market data identifiers associated with the specified name.
* <p>
* This returns the unique identifiers that refer to the specified name.
* There may be more than one identifier associated with a name as the name is not unique.
*
* @param <T> the type of the market data value
* @param name the name to find
* @return the set of market data identifiers, empty if name not found
*/
public abstract <T> Set<MarketDataId<T>> findIds(MarketDataName<T> name);
//-------------------------------------------------------------------------
/**
* Gets the time-series identifiers.
*
* @return the set of observable identifiers
*/
public abstract Set<ObservableId> getTimeSeriesIds();
/**
* Gets the time-series identified by the specified identifier, empty if not found.
*
* @param id the identifier to find
* @return the time-series, empty if no time-series found
*/
public abstract LocalDateDoubleTimeSeries getTimeSeries(ObservableId id);
//-------------------------------------------------------------------------
/**
* Combines this market data with another.
* <p>
* The result combines both sets of market data.
* Values are taken from this set of market data if available, otherwise they are taken
* from the other set.
* <p>
* The valuation dates of the sets of market data must be the same.
*
* @param other the other market data
* @return the combined market data
*/
public default MarketData combinedWith(MarketData other) {
return new CombinedMarketData(this, other);
}
//-------------------------------------------------------------------------
/**
* Returns a copy of this market data with the specified value.
* <p>
* When the result is queried for the specified identifier, the specified value will be returned.
* <p>
* For example, this method could be used to replace a curve with a bumped curve.
*
* @param <T> the type of the market data value
* @param id the identifier to find
* @param value the value to associate with the identifier
* @return the derived market data with the specified identifier and value
*/
public default <T> MarketData withValue(MarketDataId<T> id, T value) {
return ExtendedMarketData.of(id, value, this);
}
}