/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.timeseries;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeries;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesAdjuster;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesSource;
import com.opengamma.core.security.Security;
import com.opengamma.core.value.MarketDataRequirementNames;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.function.FunctionInputs;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.engine.value.ComputedValue;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValueProperties.Builder;
import com.opengamma.engine.value.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.financial.OpenGammaExecutionContext;
import com.opengamma.financial.analytics.model.InstrumentTypeProperties;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.master.historicaltimeseries.HistoricalTimeSeriesResolutionResult;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.UnorderedCurrencyPair;
/**
* Helper methods for working with the historical time series functions.
*/
public final class HistoricalTimeSeriesFunctionUtils {
/**
* Property describing the "data field" used to resolve the time series for each instrument.
*/
public static final String DATA_FIELD_PROPERTY = "DataField";
/**
* Property describing the "adjuster" that will apply normalization and/or any other rules to the underlying time series.
*/
public static final String ADJUST_PROPERTY = "Adjust";
/**
* Property describing the maximum age of a time-series point.
*/
public static final String AGE_LIMIT_PROPERTY = "AgeLimit";
/**
* Value for {@link #AGE_LIMIT_PROPERTY}.
*/
public static final String UNLIMITED_AGE_LIMIT_VALUE = "Unlimited";
/**
* Property describing the "resolution key" used to resolve the time series for each instrument.
*/
public static final String RESOLUTION_KEY_PROPERTY = "ResolutionKey";
/**
* Property describing the "start date" of the time series value.
*/
public static final String START_DATE_PROPERTY = "Start";
/**
* Property describing whether the start date was included in the time series.
*/
public static final String INCLUDE_START_PROPERTY = "IncludeStart";
/**
* Property describing the "end date" of the time series value.
*/
public static final String END_DATE_PROPERTY = "End";
/**
* Property describing whether the end date was included in the time series.
*/
public static final String INCLUDE_END_PROPERTY = "IncludeEnd";
/**
* Value for {@link #INCLUDE_START_PROPERTY} or {@link #INCLUDE_END_PROPERTY}.
*/
public static final String YES_VALUE = "Yes";
/**
* Value for {@link #INCLUDE_START_PROPERTY} or {@link #INCLUDE_END_PROPERTY}.
*/
public static final String NO_VALUE = "No";
private HistoricalTimeSeriesFunctionUtils() {
}
public static ValueProperties.Builder htsConstraints(final ValueProperties.Builder properties, final DateConstraint startDate, final boolean includeStart, final DateConstraint endDate,
final boolean includeEnd) {
if (startDate != null) {
properties.with(START_DATE_PROPERTY, startDate.toString()).with(INCLUDE_START_PROPERTY, includeStart ? YES_VALUE : NO_VALUE);
}
if (endDate != null) {
properties.with(END_DATE_PROPERTY, endDate.toString()).with(INCLUDE_END_PROPERTY, includeEnd ? YES_VALUE : NO_VALUE);
}
return properties;
}
public static ValueRequirement createHTSRequirement(final HistoricalTimeSeriesResolutionResult timeSeries, final String dataField, final ValueProperties constraints) {
final HistoricalTimeSeriesAdjuster adjuster = timeSeries.getAdjuster();
final String adjustment = (adjuster == null) ? "" : adjuster.getAdjustment(timeSeries.getHistoricalTimeSeriesInfo().getExternalIdBundle().toBundle()).toString();
final Builder properties = constraints.copy()
.with(DATA_FIELD_PROPERTY, dataField)
.with(ADJUST_PROPERTY, adjustment);
return new ValueRequirement(ValueRequirementNames.HISTORICAL_TIME_SERIES, ComputationTargetType.PRIMITIVE, timeSeries.getHistoricalTimeSeriesInfo().getUniqueId(),
properties.get());
}
public static ValueRequirement createHTSRequirement(final HistoricalTimeSeriesResolutionResult timeSeries, final String dataField, final DateConstraint startDate, final boolean includeStart,
final DateConstraint endDate, final boolean includeEnd) {
final HistoricalTimeSeriesAdjuster adjuster = timeSeries.getAdjuster();
final String adjustment = (adjuster == null) ? "" : adjuster.getAdjustment(timeSeries.getHistoricalTimeSeriesInfo().getExternalIdBundle().toBundle()).toString();
final Builder properties = htsConstraints(ValueProperties.builder(), startDate, includeStart, endDate, includeEnd)
.with(DATA_FIELD_PROPERTY, dataField)
.with(ADJUST_PROPERTY, adjustment);
return new ValueRequirement(ValueRequirementNames.HISTORICAL_TIME_SERIES, ComputationTargetType.PRIMITIVE, timeSeries.getHistoricalTimeSeriesInfo().getUniqueId(),
properties.get());
}
/** Creates a ValueRequirement for {@link ValueRequirementNames#HISTORICAL_TIME_SERIES_LATEST}.
* See {@link HistoricalTimeSeriesLatestSecurityValueFunction} which does the heavy lifting
* @param security {@link Security} for which value is required
* @param dataField Name of time series value. Example "Close"
* @param constraints {@link ValueProperties}
* @return The {@link ValueRequirement} "Historical Time Series (latest value)"
*/
public static ValueRequirement createHTSLatestRequirement(final Security security, final String dataField, final ValueProperties constraints) {
final Builder properties = (constraints == null ? ValueProperties.none() : constraints).copy().with(DATA_FIELD_PROPERTY, dataField);
return new ValueRequirement(ValueRequirementNames.HISTORICAL_TIME_SERIES_LATEST, ComputationTargetSpecification.of(security), properties.get());
}
public static ValueRequirement createYCHTSRequirement(final Currency currency, final String curveName, final String dataField, final String resolutionKey, final DateConstraint startDate,
final boolean includeStart, final DateConstraint endDate, final boolean includeEnd) {
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE_HISTORICAL_TIME_SERIES, ComputationTargetType.CURRENCY.specification(currency),
ValueProperties.builder()
.with(ValuePropertyNames.CURVE, curveName)
.with(DATA_FIELD_PROPERTY, dataField)
.with(RESOLUTION_KEY_PROPERTY, (resolutionKey != null) ? resolutionKey : "")
.with(START_DATE_PROPERTY, startDate.toString())
.with(INCLUDE_START_PROPERTY, includeStart ? YES_VALUE : NO_VALUE)
.with(END_DATE_PROPERTY, endDate.toString())
.with(INCLUDE_END_PROPERTY, includeEnd ? YES_VALUE : NO_VALUE).get());
}
public static ValueRequirement createCreditSpreadCurveHTSRequirement(final Security security, final String curveName, final String dataField, final String resolutionKey,
final DateConstraint startDate, final boolean includeStart, final DateConstraint endDate, final boolean includeEnd) {
return new ValueRequirement(ValueRequirementNames.CREDIT_SPREAD_CURVE_HISTORICAL_TIME_SERIES, ComputationTargetSpecification.of(security),
ValueProperties.builder()
.with(ValuePropertyNames.CURVE, curveName)
.with(DATA_FIELD_PROPERTY, dataField)
.with(RESOLUTION_KEY_PROPERTY, (resolutionKey != null) ? resolutionKey : "")
.with(START_DATE_PROPERTY, startDate.toString())
.with(INCLUDE_START_PROPERTY, includeStart ? YES_VALUE : NO_VALUE)
.with(END_DATE_PROPERTY, endDate.toString())
.with(INCLUDE_END_PROPERTY, includeEnd ? YES_VALUE : NO_VALUE).get());
}
public static ValueRequirement createFXForwardCurveHTSRequirement(final UnorderedCurrencyPair currencyPair, final String curveName, final String dataField, final String resolutionKey,
final DateConstraint startDate, final boolean includeStart, final DateConstraint endDate, final boolean includeEnd) {
return new ValueRequirement(ValueRequirementNames.FX_FORWARD_CURVE_HISTORICAL_TIME_SERIES, ComputationTargetType.UNORDERED_CURRENCY_PAIR.specification(currencyPair),
ValueProperties.builder()
.with(ValuePropertyNames.CURVE, curveName)
.with(DATA_FIELD_PROPERTY, dataField)
.with(RESOLUTION_KEY_PROPERTY, (resolutionKey != null) ? resolutionKey : "")
.with(START_DATE_PROPERTY, startDate.toString())
.with(INCLUDE_START_PROPERTY, includeStart ? YES_VALUE : NO_VALUE)
.with(END_DATE_PROPERTY, endDate.toString())
.with(INCLUDE_END_PROPERTY, includeEnd ? YES_VALUE : NO_VALUE).get());
}
public static ValueRequirement createVolatilitySurfaceHTSRequirement(final UnorderedCurrencyPair currencies, final String surfaceName, final String instrumentType, final String dataField,
final String resolutionKey, final DateConstraint startDate, final boolean includeStart, final DateConstraint endDate, final boolean includeEnd) {
return new ValueRequirement(ValueRequirementNames.VOLATILITY_SURFACE_HISTORICAL_TIME_SERIES, ComputationTargetType.UNORDERED_CURRENCY_PAIR.specification(currencies),
ValueProperties.builder()
.with(ValuePropertyNames.SURFACE, surfaceName)
.with(InstrumentTypeProperties.PROPERTY_SURFACE_INSTRUMENT_TYPE, instrumentType)
.with(DATA_FIELD_PROPERTY, dataField)
.with(RESOLUTION_KEY_PROPERTY, (resolutionKey != null) ? resolutionKey : "")
.with(START_DATE_PROPERTY, startDate.toString())
.with(INCLUDE_START_PROPERTY, includeStart ? YES_VALUE : NO_VALUE)
.with(END_DATE_PROPERTY, endDate.toString())
.with(INCLUDE_END_PROPERTY, includeEnd ? YES_VALUE : NO_VALUE).get());
}
/**
* Reduces any parameters of value name {@link ValueRequirementNames#HISTORICAL_TIME_SERIES} to a single {@link HistoricalTimeSeriesBundle}.
*
* @param executionContext the execution context, must contain a {@link HistoricalTimeSeriesSource}
* @param inputs the function inputs
* @return the time series bundle, not null
*/
public static HistoricalTimeSeriesBundle getHistoricalTimeSeriesInputs(final FunctionExecutionContext executionContext, final FunctionInputs inputs) {
final HistoricalTimeSeriesSource timeSeriesSource = OpenGammaExecutionContext.getHistoricalTimeSeriesSource(executionContext);
final HistoricalTimeSeriesBundle bundle = new HistoricalTimeSeriesBundle();
for (final ComputedValue input : inputs.getAllValues()) {
if (ValueRequirementNames.HISTORICAL_TIME_SERIES.equals(input.getSpecification().getValueName())) {
final String fieldName = input.getSpecification().getProperty(DATA_FIELD_PROPERTY);
final HistoricalTimeSeries hts = (HistoricalTimeSeries) input.getValue();
final ExternalIdBundle ids = timeSeriesSource.getExternalIdBundle(hts.getUniqueId());
if (fieldName == null) {
// Default to MARKET_VALUE in the bundle; this is not probably correct but this shouldn't happen for well written functions
bundle.add(MarketDataRequirementNames.MARKET_VALUE, ids, hts);
} else {
bundle.add(fieldName, ids, hts);
}
}
}
return bundle;
}
protected static boolean parseBoolean(final String str) {
return YES_VALUE.equals(str);
}
}