/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.bondcleanprice; 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.financial.security.bond.BondSecurity; import com.opengamma.util.async.AsynchronousExecution; /** * Prototype - Multiplies {@link ValueRequirementNames#QUANTITY} by {@link ValueRequirementNames#SECURITY_MARKET_PRICE}.<p> * The latter is equivalent to {@link ValueRequirementNames#MARKET_CLEAN_PRICE}. */ public class BondNetMarketValueFromCleanPriceFunction extends AbstractFunction.NonCompiledInvoker { private String getOutputName() { return ValueRequirementNames.NET_MARKET_VALUE; } @Override public boolean canApplyTo(final FunctionCompilationContext context, final ComputationTarget target) { Security security = target.getPositionOrTrade().getSecurity(); return (security instanceof BondSecurity); } @Override public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) throws AsynchronousExecution { // Get Clean Price Double cleanPrice = null; final ComputedValue inputVal = inputs.getComputedValue(ValueRequirementNames.SECURITY_MARKET_PRICE); if (inputVal != null) { // Ensure the value was successfully obtained cleanPrice = (Double) inputVal.getValue(); } else { throw new OpenGammaRuntimeException("Did not satisfy requirement," + ValueRequirementNames.SECURITY_MARKET_PRICE + ", for trade " + target.getPositionOrTrade().getUniqueId()); } // Scale by Quantity final double quantity = target.getPositionOrTrade().getQuantity().doubleValue(); final Double bondEquivalentValue = quantity * cleanPrice; // 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, bondEquivalentValue)); } 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.SECURITY_MARKET_PRICE) { 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(ValuePropertyNames.CURRENCY, currency) .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.SECURITY_MARKET_PRICE, target.toSpecification(), desiredValue.getConstraints().withoutAny(ValuePropertyNames.FUNCTION))); } }