}
@Override
public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) {
final Position position = target.getPosition();
final FXFutureSecurity security = (FXFutureSecurity) position.getSecurity();
final Clock snapshotClock = executionContext.getValuationClock();
final LocalDate now = ZonedDateTime.now(snapshotClock).toLocalDate();
final ValueRequirement desiredValue = desiredValues.iterator().next();
final Set<String> samplingPeriodName = desiredValue.getConstraints().getValues(ValuePropertyNames.SAMPLING_PERIOD);
final Set<String> scheduleCalculatorName = desiredValue.getConstraints().getValues(ValuePropertyNames.SCHEDULE_CALCULATOR);
final Set<String> samplingFunctionName = desiredValue.getConstraints().getValues(ValuePropertyNames.SAMPLING_FUNCTION);
final Period samplingPeriod = getSamplingPeriod(samplingPeriodName);
final LocalDate startDate = now.minus(samplingPeriod);
final Currency payCurrency = security.getNumerator();
final Currency receiveCurrency = security.getDenominator();
final HistoricalTimeSeries dbTimeSeries = (HistoricalTimeSeries) inputs.getValue(ValueRequirementNames.HISTORICAL_TIME_SERIES);
if (dbTimeSeries == null) {
throw new OpenGammaRuntimeException("Could not get identifier / price series pair for " + security);
}
DoubleTimeSeries<?> ts = dbTimeSeries.getTimeSeries();
if (ts == null) {
throw new OpenGammaRuntimeException("Could not get price series for " + security);
}
if (ts.isEmpty()) {
throw new OpenGammaRuntimeException("Empty price series for " + security);
}
// TODO: If we know which way up we want the time series, don't request it in "convention order" and then lookup the convention again here, request it in
// the desired order in getRequirements using a CurrencyPair
final CurrencyPairs currencyPairs = OpenGammaExecutionContext.getCurrencyPairsSource(executionContext).getCurrencyPairs(CurrencyPairs.DEFAULT_CURRENCY_PAIRS);
final CurrencyPair currencyPair = currencyPairs.getCurrencyPair(security.getNumerator(), security.getDenominator());
if (!payCurrency.equals(currencyPair.getBase()) && receiveCurrency.equals(security.getCurrency())) {
ts = ts.reciprocal();
}
final Object pvObject = inputs.getValue(new ValueRequirement(ValueRequirementNames.PRESENT_VALUE, ComputationTargetType.SECURITY, security.getUniqueId()));
if (pvObject == null) {
throw new OpenGammaRuntimeException("Present value was null");
}
final double pv = (Double) pvObject;
final Schedule scheduleCalculator = getScheduleCalculator(scheduleCalculatorName);