@Override
public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) {
final Clock snapshotClock = executionContext.getValuationClock();
final ZonedDateTime now = ZonedDateTime.now(snapshotClock);
final Trade trade = target.getTrade();
final IRFutureOptionSecurity security = (IRFutureOptionSecurity) trade.getSecurity();
final ValueRequirement desiredValue = desiredValues.iterator().next();
final Currency currency = FinancialSecurityUtils.getCurrency(security);
final String curveCalculationConfigName = desiredValue.getConstraint(ValuePropertyNames.CURVE_CALCULATION_CONFIG);
final ConfigSource configSource = OpenGammaExecutionContext.getConfigSource(executionContext);
final ConfigDBCurveCalculationConfigSource curveCalculationConfigSource = new ConfigDBCurveCalculationConfigSource(configSource);
final MultiCurveCalculationConfig curveCalculationConfig = curveCalculationConfigSource.getConfig(curveCalculationConfigName);
if (curveCalculationConfig == null) {
throw new OpenGammaRuntimeException("Could not find curve calculation configuration named " + curveCalculationConfigName);
}
final String[] curveNames = curveCalculationConfig.getYieldCurveNames();
// Append _CCY to be consistent with curve names from YieldCurveFunctionUtils.getAllYieldCurves
final String[] fullCurveNames = new String[Math.max(2, curveNames.length)];
for (int i = 0; i < curveNames.length; i++) {
fullCurveNames[i] = curveNames[i] + "_" + currency.getCode();
}
if (curveNames.length == 1) { // MultiCurveCalculationConfig contains just a single curve for discounting and forwarding
fullCurveNames[1] = fullCurveNames[0];
}
final YieldCurveBundle curves = YieldCurveFunctionUtils.getAllYieldCurves(inputs, curveCalculationConfig, curveCalculationConfigSource);
final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE);
final String surfaceNameWithPrefix = surfaceName + "_" + IRFutureOptionFunctionHelper.getFutureOptionPrefix(target);
final Object volatilitySurfaceObject = inputs.getValue(getVolatilityRequirement(surfaceNameWithPrefix, currency));
if (volatilitySurfaceObject == null) {
throw new OpenGammaRuntimeException("Could not get volatility surface");
}
final VolatilitySurface volatilitySurface = (VolatilitySurface) volatilitySurfaceObject;
if (!(volatilitySurface.getSurface() instanceof InterpolatedDoublesSurface)) {
throw new OpenGammaRuntimeException("Expecting an InterpolatedDoublesSurface; got " + volatilitySurface.getSurface().getClass());
}
final InstrumentDefinition<?> irFutureOptionDefinition = _converter.convert(trade);
final HistoricalTimeSeries ts = (HistoricalTimeSeries) inputs.getValue(ValueRequirementNames.HISTORICAL_TIME_SERIES);
final int length = ts.getTimeSeries().size();
if (length == 0) {
throw new OpenGammaRuntimeException("Price time series for " + security.getUnderlyingId() + " was empty");
}
final double lastMarginPrice = ts.getTimeSeries().getLatestValue();
final YieldCurveWithBlackCubeBundle data = new YieldCurveWithBlackCubeBundle(volatilitySurface.getSurface(), curves);
final String daysForward = desiredValue.getConstraint(PROPERTY_DAYS_TO_MOVE_FORWARD);