/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model.credit;
import static com.opengamma.engine.value.ValuePropertyNames.CURRENCY;
import static com.opengamma.engine.value.ValueRequirementNames.JUMP_TO_DEFAULT;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.opengamma.core.position.PortfolioNode;
import com.opengamma.core.position.Position;
import com.opengamma.core.position.impl.PositionAccumulator;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.ComputationTargetSpecification;
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.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.financial.analytics.StringLabelledMatrix1D;
import com.opengamma.util.async.AsynchronousExecution;
/**
*
*/
public class JumpToDefaultPortfolioNodeFunction extends AbstractFunction.NonCompiledInvoker {
/** The logger */
private static final Logger s_logger = LoggerFactory.getLogger(JumpToDefaultPortfolioNodeFunction.class);
@Override
public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target,
final Set<ValueRequirement> desiredValues) throws AsynchronousExecution {
final ValueRequirement desiredValue = Iterables.getOnlyElement(desiredValues);
final int size = inputs.getAllValues().size();
final String[] entityNames = new String[size];
final double[] mcas = new double[size];
final Collection<ComputedValue> values = inputs.getAllValues();
int i = 0;
for (final ComputedValue value : values) {
final ValueSpecification spec = value.getSpecification();
final Object jtdObject = value.getValue();
if (jtdObject instanceof Double) {
// final Currency resultCurrency = Currency.of(spec.getProperty(CURRENCY));
final double jtd = (Double) jtdObject;
entityNames[i] = Integer.toString(i);
mcas[i++] = jtd;
} else {
s_logger.error("Jump to default value was not a double");
}
}
final StringLabelledMatrix1D matrix = new StringLabelledMatrix1D(entityNames, mcas);
final ValueSpecification spec = new ValueSpecification(JUMP_TO_DEFAULT, target.toSpecification(), desiredValue.getConstraints().copy().get());
return Collections.singleton(new ComputedValue(spec, matrix));
}
@Override
public ComputationTargetType getTargetType() {
return ComputationTargetType.PORTFOLIO_NODE;
}
@Override
public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target) {
final ValueProperties properties = createValueProperties()
.withAny(CURRENCY)
.withOptional(CURRENCY)
.get();
return Collections.singleton(new ValueSpecification(JUMP_TO_DEFAULT, target.toSpecification(), properties));
}
@Override
public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) {
final PortfolioNode node = target.getPortfolioNode();
final ValueProperties.Builder properties = ValueProperties.builder();
final ValueProperties constraints = desiredValue.getConstraints();
final Set<String> currencies = constraints.getValues(CURRENCY);
if (currencies != null && currencies.size() == 1) {
properties.with(CURRENCY, currencies);
}
final Set<Position> positions = PositionAccumulator.getAccumulatedPositions(node);
final Set<ValueRequirement> requirements = Sets.newHashSetWithExpectedSize(positions.size());
for (final Position position : positions) {
requirements.add(new ValueRequirement(JUMP_TO_DEFAULT, ComputationTargetSpecification.of(position), properties.get()));
}
return requirements;
}
/**
* Jump to default is valid only for certain security types. By allowing missing requirements, someone
* extending the list of relevant types does not have to remember to add logic to only ask for JtD on
* those types and does not have to explore the portfolio structure to eliminate irrelevant trade types
* in getRequirements().
* {@inheritDoc}
*/
@Override
public boolean canHandleMissingRequirements() {
return true;
}
}