}
@Override
public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) {
final ZonedDateTime today = ZonedDateTime.now(executionContext.getValuationClock());
final EquityOptionSecurity optionSec = (EquityOptionSecurity) target.getSecurity();
// Get inputs:
final ValueRequirement optionPriceReq = getPriceRequirement(optionSec.getUniqueId());
final ValueRequirement underlyingPriceReq = getPriceRequirement(optionSec.getUnderlyingId());
final Double optionPrice = (Double) inputs.getValue(optionPriceReq);
final Double underlyingPrice = (Double) inputs.getValue(underlyingPriceReq);
final YieldAndDiscountCurve discountCurve = (YieldAndDiscountCurve) inputs.getValue(ValueRequirementNames.YIELD_CURVE);
// TODO cost-of-carry model
if (optionPrice == null) {
throw new OpenGammaRuntimeException("No market value for option price");
}
if (underlyingPrice == null) {
throw new OpenGammaRuntimeException("No market value for underlying price");
}
// Perform the calculation:
final Expiry expiry = optionSec.getExpiry();
final double years = DateUtils.getDifferenceInYears(today, expiry.getExpiry());
final double b = discountCurve.getInterestRate(years); // TODO
final OptionDefinition europeanVanillaOptionDefinition = new EuropeanVanillaOptionDefinition(optionSec.getStrike(), expiry, (optionSec.getOptionType() == OptionType.CALL));
final Map<OptionDefinition, Double> prices = new HashMap<OptionDefinition, Double>();
prices.put(europeanVanillaOptionDefinition, optionPrice);
final VolatilitySurface volatilitySurface = _volatilitySurfaceModel.getSurface(prices, new StandardOptionDataBundle(discountCurve, b, null, underlyingPrice, today));
//This is so cheap no need to check desired values