/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model;
import static com.opengamma.engine.value.ValuePropertyNames.CURRENCY;
import static com.opengamma.engine.value.ValuePropertyNames.FUNCTION;
import static com.opengamma.engine.value.ValueRequirementNames.FX_CURRENCY_EXPOSURE;
import static com.opengamma.engine.value.ValueRequirementNames.PRESENT_VALUE;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.google.common.collect.Iterables;
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.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.financial.security.FinancialSecurityUtils;
import com.opengamma.financial.security.future.FXFutureSecurity;
import com.opengamma.financial.security.fx.FXForwardSecurity;
import com.opengamma.financial.security.fx.FXVolatilitySwapSecurity;
import com.opengamma.financial.security.fx.NonDeliverableFXForwardSecurity;
import com.opengamma.financial.security.option.FXBarrierOptionSecurity;
import com.opengamma.financial.security.option.FXDigitalOptionSecurity;
import com.opengamma.financial.security.option.FXOptionSecurity;
import com.opengamma.financial.security.option.NonDeliverableFXDigitalOptionSecurity;
import com.opengamma.financial.security.option.NonDeliverableFXOptionSecurity;
import com.opengamma.financial.value.ValueRenamingFunction;
import com.opengamma.util.async.AsynchronousExecution;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.MultipleCurrencyAmount;
/**
* Produces FX currency exposures for all instruments except FX. This is not done via a {@link ValueRenamingFunction}
* because the logic to produce currency exposure should eventually be moved into the analytics library.
*/
public class FXCurrencyExposureFunction extends AbstractFunction.NonCompiledInvoker {
@Override
public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target,
final Set<ValueRequirement> desiredValues) throws AsynchronousExecution {
final ComputedValue input = Iterables.getOnlyElement(inputs.getAllValues());
final ValueProperties properties = input.getSpecification().getProperties().copy()
.withoutAny(CURRENCY)
.withoutAny(FUNCTION)
.with(FUNCTION, getUniqueId())
.get();
final Currency currency = FinancialSecurityUtils.getCurrency(target.getTrade().getSecurity());
final double pv = (Double) input.getValue();
final MultipleCurrencyAmount mca = MultipleCurrencyAmount.of(currency, pv);
final ValueSpecification spec = new ValueSpecification(FX_CURRENCY_EXPOSURE, target.toSpecification(), properties);
return Collections.singleton(new ComputedValue(spec, mca));
}
@Override
public ComputationTargetType getTargetType() {
return ComputationTargetType.TRADE;
}
@Override
public boolean canApplyTo(final FunctionCompilationContext context, final ComputationTarget target) {
final Security security = target.getTrade().getSecurity();
if (security instanceof FXForwardSecurity ||
security instanceof NonDeliverableFXForwardSecurity ||
security instanceof FXOptionSecurity ||
security instanceof NonDeliverableFXOptionSecurity ||
security instanceof FXDigitalOptionSecurity ||
security instanceof NonDeliverableFXDigitalOptionSecurity ||
security instanceof FXBarrierOptionSecurity ||
security instanceof FXVolatilitySwapSecurity ||
security instanceof FXFutureSecurity) {
return false;
}
return true;
}
@Override
public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target) {
final ValueProperties properties = ValueProperties.all();
return Collections.singleton(new ValueSpecification(FX_CURRENCY_EXPOSURE, target.toSpecification(), properties));
}
@Override
public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) {
final String currency = FinancialSecurityUtils.getCurrency(target.getTrade().getSecurity()).getCode();
final ValueProperties constraints = desiredValue.getConstraints().copy()
.withoutAny(CURRENCY)
.with(CURRENCY, currency)
.get();
return Collections.singleton(new ValueRequirement(PRESENT_VALUE, target.toSpecification(), constraints));
}
@Override
public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target, final Map<ValueSpecification, ValueRequirement> inputs) {
if (inputs.size() != 1) {
return null;
}
final Entry<ValueSpecification, ValueRequirement> input = Iterables.getOnlyElement(inputs.entrySet());
final ValueProperties properties = input.getKey().getProperties().copy()
.withoutAny(CURRENCY)
.withoutAny(FUNCTION)
.with(FUNCTION, getUniqueId())
.get();
return Collections.singleton(new ValueSpecification(FX_CURRENCY_EXPOSURE, target.toSpecification(), properties));
}
}