/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model.equity.option;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Sets;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.security.Security;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.function.AbstractFunction;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.function.FunctionInputs;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.engine.value.ComputedValue;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.financial.security.FinancialSecurityUtils;
import com.opengamma.util.async.AsynchronousExecution;
/**
* Prototype - Takes {@link ValueRequirementNames#NET_MARKET_VALUE} as input requirement,
* and scales by a constant representing, say, a fund's capital
*/
public class NetCapitalFunction extends AbstractFunction.NonCompiledInvoker {
private static final Double CAPITAL = 1.497e7;
protected String getOutputName() {
return ValueRequirementNames.NET_CAPITAL;
}
@Override
public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) throws AsynchronousExecution {
// 1. Get Net Market Value
Double netMarketValue = null;
final ComputedValue inputVal = inputs.getComputedValue(ValueRequirementNames.NET_MARKET_VALUE);
if (inputVal != null) { // Ensure the value was successfully obtained
netMarketValue = (Double) inputVal.getValue();
} else {
throw new OpenGammaRuntimeException("Did not satisfy requirement," + ValueRequirementNames.NET_MARKET_VALUE + ", for trade " + target.getPositionOrTrade().getUniqueId());
}
// 2 Scale by Capital amount
final double netCapital = netMarketValue / CAPITAL;
// 3. Create specification and return
final ValueRequirement desiredValue = desiredValues.iterator().next();
final ValueSpecification valueSpecification = new ValueSpecification(desiredValue.getValueName(), target.toSpecification(), desiredValue.getConstraints());
return Sets.newHashSet(new ComputedValue(valueSpecification, netCapital));
}
@Override
public ComputationTargetType getTargetType() {
return ComputationTargetType.POSITION_OR_TRADE;
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target) {
return Collections.singleton(new ValueSpecification(getOutputName() , target.toSpecification(), ValueProperties.all()));
}
@Override
public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target, final Map<ValueSpecification, ValueRequirement> inputs) {
// inputs provide the properties of the required security greek. These we pass through to the position
final ValueSpecification netMarketValueSpec = inputs.keySet().iterator().next();
if (netMarketValueSpec.getValueName() != ValueRequirementNames.NET_MARKET_VALUE) {
return null;
}
final Security security = target.getPositionOrTrade().getSecurity();
final String currency = FinancialSecurityUtils.getCurrency(security).getCode();
final ValueProperties properties = netMarketValueSpec.getProperties().copy()
.withoutAny(ValuePropertyNames.FUNCTION).with(ValuePropertyNames.FUNCTION, getUniqueId())
.withoutAny(ValuePropertyNames.CURRENCY)
.with("Capital Constant", CAPITAL.toString())
.get();
return Collections.singleton(new ValueSpecification(getOutputName() , target.toSpecification(), properties));
}
@Override
public Set<ValueRequirement> getRequirements(FunctionCompilationContext context, ComputationTarget target, ValueRequirement desiredValue) {
if (!desiredValue.getValueName().equals(getOutputName())) {
return null;
}
return Collections.singleton(new ValueRequirement(ValueRequirementNames.NET_MARKET_VALUE, target.toSpecification(),
desiredValue.getConstraints().withoutAny(ValuePropertyNames.FUNCTION)));
}
}