@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 FXOptionSecurity fxOption = (FXOptionSecurity) target.getSecurity();
final ValueRequirement desiredValue = desiredValues.iterator().next();
final String surfaceName = desiredValue.getConstraint(SURFACE);
final String surfaceType = desiredValue.getConstraint(PROPERTY_SURFACE_TYPE);
final String xAxis = desiredValue.getConstraint(PROPERTY_X_AXIS);
final String yAxis = desiredValue.getConstraint(PROPERTY_Y_AXIS);
final String yAxisType = desiredValue.getConstraint(PROPERTY_Y_AXIS_TYPE);
final String forwardCurveCalculationMethod = desiredValue.getConstraint(ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_CALCULATION_METHOD);
final String forwardCurveName = desiredValue.getConstraint(CURVE);
final String h = desiredValue.getConstraint(PROPERTY_H);
final String theta = desiredValue.getConstraint(PROPERTY_THETA);
final String timeSteps = desiredValue.getConstraint(PROPERTY_TIME_STEPS);
final String spaceSteps = desiredValue.getConstraint(PROPERTY_SPACE_STEPS);
final String timeGridBunching = desiredValue.getConstraint(PROPERTY_TIME_GRID_BUNCHING);
final String spaceGridBunching = desiredValue.getConstraint(PROPERTY_SPACE_GRID_BUNCHING);
final String maxMoneyness = desiredValue.getConstraint(PROPERTY_MAX_MONEYNESS);
final String pdeDirection = desiredValue.getConstraint(PROPERTY_PDE_DIRECTION);
if (!(pdeDirection.equals(LocalVolatilityPDEValuePropertyNames.FORWARD_PDE))) {
throw new OpenGammaRuntimeException("Can only use forward PDE; should never ask for this direction: " + pdeDirection);
}
final String strikeInterpolatorName = desiredValue.getConstraint(PROPERTY_RESULT_STRIKE_INTERPOLATOR);
final String timeInterpolatorName = desiredValue.getConstraint(PROPERTY_RESULT_TIME_INTERPOLATOR);
final ValueRequirement gridRequirement = getPDEGridRequirement(target, surfaceName, surfaceType, xAxis, yAxis, yAxisType,
forwardCurveCalculationMethod, h, forwardCurveName,
theta, timeSteps, spaceSteps, timeGridBunching, spaceGridBunching, maxMoneyness, pdeDirection);
final Object pdeGridObject = inputs.getValue(gridRequirement);
if (pdeGridObject == null) {
throw new OpenGammaRuntimeException("PDE grid was null");
}
final PDEFullResults1D pdeGrid = (PDEFullResults1D) pdeGridObject;
final double[] gridTimes = pdeGrid.getGrid().getTimeNodes();
final double[] gridMoneyness = pdeGrid.getGrid().getSpaceNodes();
final CurrencyPairs currencyPairs = OpenGammaExecutionContext.getCurrencyPairsSource(executionContext).getCurrencyPairs(CurrencyPairs.DEFAULT_CURRENCY_PAIRS);
final CurrencyPair currencyPair = currencyPairs.getCurrencyPair(fxOption.getPutCurrency(), fxOption.getCallCurrency());
//TODO interpolate
///////////////////////////////
final double tau = getExpiry(fxOption, now);
final UnorderedCurrencyPair currencies = UnorderedCurrencyPair.of(fxOption.getCallCurrency(), fxOption.getPutCurrency());
final ValueRequirement forwardCurveRequirement = getForwardCurveRequirement(forwardCurveCalculationMethod, forwardCurveName, currencies);
final Object forwardCurveObject = inputs.getValue(forwardCurveRequirement);
if (forwardCurveObject == null) {
throw new OpenGammaRuntimeException("Forward curve was null");
}