@Override
public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) throws AsynchronousExecution {
// Get security price (market value)
final Trade trade = target.getTrade();
final FutureSecurity security = (FutureSecurity) trade.getSecurity();
final double price = (Double) inputs.getValue(new ValueRequirement(MarketDataRequirementNames.MARKET_VALUE, ComputationTargetType.SECURITY, security.getUniqueId()));
// Get shift to price, if provided, and hence PNL
final double pnl;
ValueProperties constraints = desiredValues.iterator().next().getConstraints();
String priceConstraint = constraints.getValues(s_priceShift).iterator().next();
String priceShiftTypeConstraint = constraints.getValues(s_priceShiftType).iterator().next();
if (priceConstraint.equals("")) {
pnl = 0.0;
} else {
final Double priceShift = Double.valueOf(priceConstraint);
if (priceShiftTypeConstraint.equals("Additive")) {
// The shift is itself the pnl
pnl = priceShift;
} else if (priceShiftTypeConstraint.equals("Multiplicative")) {
// The market value under shift, d = (1 + d ) * market_value, hence pnl = scenario_value - market_value = d * market_value
pnl = priceShift * price;
} else {
s_logger.debug("Valid PriceShiftType's: Additive and Multiplicative. Found: " + priceShiftTypeConstraint + " Defaulting to Multiplicative.");
pnl = priceShift * price;
}
}
// Scale by unit notional of contract and trade size
final Double scaledPnl = pnl * security.getUnitAmount() * trade.getQuantity().floatValue();
// Return PNL with specification
final ValueRequirement desiredValue = desiredValues.iterator().next();
final ValueSpecification valueSpec = new ValueSpecification(getValueRequirementName(), target.toSpecification(), desiredValue.getConstraints());
return Collections.singleton(new ComputedValue(valueSpec, scaledPnl));