com.opengamma.financial.analytics.model.forex.option.black.FXOptionBlackValuePhiFunction.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.financial.analytics.model.forex.option.black.FXOptionBlackValuePhiFunction.java

Source

/**
 * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.financial.analytics.model.forex.option.black;

import static com.opengamma.financial.analytics.model.forex.option.black.FXOptionFunctionUtils.getResultCurrency;

import java.util.Collections;
import java.util.List;
import java.util.Map;
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.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.forex.method.MultipleCurrencyInterestRateCurveSensitivity;
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.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.financial.OpenGammaCompilationContext;
import com.opengamma.financial.analytics.CurrencyPairsFunction;
import com.opengamma.financial.analytics.model.CalculationPropertyNamesAndValues;
import com.opengamma.financial.analytics.model.InterpolatedDataProperties;
import com.opengamma.financial.analytics.model.forex.ForexVisitors;
import com.opengamma.financial.currency.CurrencyPair;
import com.opengamma.financial.currency.CurrencyPairs;
import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.financial.security.FinancialSecurityTypes;
import com.opengamma.util.async.AsynchronousExecution;
import com.opengamma.util.money.Currency;
import com.opengamma.util.tuple.DoublesPair;

/**
 * @deprecated This class uses deprecated functionality in the analytics library.
 */
@Deprecated
public class FXOptionBlackValuePhiFunction extends AbstractFunction.NonCompiledInvoker {
    /** The logger */
    private static final Logger s_logger = LoggerFactory.getLogger(FXOptionBlackValueRhoFunction.class);

    @Override
    public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs,
            final ComputationTarget target, final Set<ValueRequirement> desiredValues)
            throws AsynchronousExecution {
        final FinancialSecurity security = (FinancialSecurity) target.getSecurity();
        final ValueRequirement desiredValue = Iterables.getOnlyElement(desiredValues);
        final Object curveSensitivitiesObject = inputs.getValue(ValueRequirementNames.FX_CURVE_SENSITIVITIES);
        if (curveSensitivitiesObject == null) {
            throw new OpenGammaRuntimeException("Could not get curve sensitivities");
        }
        final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor());
        final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor());
        final String putCurrencyCurve = desiredValue.getConstraint(FXOptionBlackFunction.PUT_CURVE);
        final Object baseQuotePairsObject = inputs.getValue(ValueRequirementNames.CURRENCY_PAIRS);
        if (baseQuotePairsObject == null) {
            throw new OpenGammaRuntimeException("Could not get base/quote pair data");
        }
        final CurrencyPairs baseQuotePairs = (CurrencyPairs) baseQuotePairsObject;
        final CurrencyPair baseQuotePair = baseQuotePairs.getCurrencyPair(putCurrency, callCurrency);
        if (baseQuotePair == null) {
            throw new OpenGammaRuntimeException(
                    "Could not get base/quote pair for currency pair (" + putCurrency + ", " + callCurrency + ")");
        }
        final String resultCurrency = getResultCurrency(target, baseQuotePair);
        final String fullCurveName = putCurrencyCurve + "_" + putCurrency.getCode();
        final MultipleCurrencyInterestRateCurveSensitivity curveSensitivities = (MultipleCurrencyInterestRateCurveSensitivity) curveSensitivitiesObject;
        final Map<String, List<DoublesPair>> sensitivitiesForCurrency = curveSensitivities
                .getSensitivity(Currency.of(resultCurrency)).getSensitivities();
        final ValueSpecification spec = new ValueSpecification(ValueRequirementNames.VALUE_PHI,
                target.toSpecification(), getResultProperties(target, desiredValue, baseQuotePair).get());
        final double phi = sensitivitiesForCurrency.get(fullCurveName).get(0).second;
        return Collections.singleton(new ComputedValue(spec, phi));
    }

    @Override
    public ComputationTargetType getTargetType() {
        return FinancialSecurityTypes.FX_OPTION_SECURITY.or(FinancialSecurityTypes.FX_BARRIER_OPTION_SECURITY)
                .or(FinancialSecurityTypes.FX_DIGITAL_OPTION_SECURITY)
                .or(FinancialSecurityTypes.NON_DELIVERABLE_FX_OPTION_SECURITY)
                .or(FinancialSecurityTypes.NON_DELIVERABLE_FX_DIGITAL_OPTION_SECURITY);
    }

    @Override
    public Set<ValueSpecification> getResults(final FunctionCompilationContext context,
            final ComputationTarget target) {
        final ValueProperties.Builder properties = getResultProperties();
        return Collections.singleton(new ValueSpecification(ValueRequirementNames.VALUE_PHI,
                target.toSpecification(), properties.get()));
    }

    @Override
    public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context,
            final ComputationTarget target, final ValueRequirement desiredValue) {
        final ValueProperties constraints = desiredValue.getConstraints();
        final Set<String> putCurveNames = constraints.getValues(FXOptionBlackFunction.PUT_CURVE);
        if (putCurveNames == null || putCurveNames.size() != 1) {
            return null;
        }
        final Set<String> callCurveNames = constraints.getValues(FXOptionBlackFunction.CALL_CURVE);
        if (callCurveNames == null || callCurveNames.size() != 1) {
            return null;
        }
        final Set<String> putCurveCalculationConfigs = constraints
                .getValues(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG);
        if (putCurveCalculationConfigs == null || putCurveCalculationConfigs.size() != 1) {
            return null;
        }
        final Set<String> callCurveCalculationConfigs = constraints
                .getValues(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG);
        if (callCurveCalculationConfigs == null || callCurveCalculationConfigs.size() != 1) {
            return null;
        }
        final Set<String> surfaceNames = constraints.getValues(ValuePropertyNames.SURFACE);
        if (surfaceNames == null || surfaceNames.size() != 1) {
            return null;
        }
        final Set<String> interpolatorNames = constraints.getValues(InterpolatedDataProperties.X_INTERPOLATOR_NAME);
        if (interpolatorNames == null || interpolatorNames.size() != 1) {
            return null;
        }
        final Set<String> leftExtrapolatorNames = constraints
                .getValues(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME);
        if (leftExtrapolatorNames == null || leftExtrapolatorNames.size() != 1) {
            return null;
        }
        final Set<String> rightExtrapolatorNames = constraints
                .getValues(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME);
        if (rightExtrapolatorNames == null || rightExtrapolatorNames.size() != 1) {
            return null;
        }
        final String putCurveName = putCurveNames.iterator().next();
        final String callCurveName = callCurveNames.iterator().next();
        final String putCurveCalculationConfig = putCurveCalculationConfigs.iterator().next();
        final String callCurveCalculationConfig = callCurveCalculationConfigs.iterator().next();
        final String surfaceName = surfaceNames.iterator().next();
        final String interpolatorName = interpolatorNames.iterator().next();
        final String leftExtrapolatorName = leftExtrapolatorNames.iterator().next();
        final String rightExtrapolatorName = rightExtrapolatorNames.iterator().next();
        final ValueRequirement pairQuoteRequirement = new ValueRequirement(ValueRequirementNames.CURRENCY_PAIRS,
                ComputationTargetSpecification.NULL);
        final ValueRequirement sensitivitiesRequirement = getCurveSensitivitiesRequirement(putCurveName,
                putCurveCalculationConfig, callCurveName, callCurveCalculationConfig, surfaceName, interpolatorName,
                leftExtrapolatorName, rightExtrapolatorName, target);
        return Sets.newHashSet(sensitivitiesRequirement, pairQuoteRequirement);
    }

    @Override
    public Set<ValueSpecification> getResults(final FunctionCompilationContext context,
            final ComputationTarget target, final Map<ValueSpecification, ValueRequirement> inputs) {
        String currencyPairConfigName = null;
        for (final Map.Entry<ValueSpecification, ValueRequirement> entry : inputs.entrySet()) {
            final ValueSpecification specification = entry.getKey();
            if (specification.getValueName().equals(ValueRequirementNames.CURRENCY_PAIRS)) {
                currencyPairConfigName = specification.getProperty(CurrencyPairsFunction.CURRENCY_PAIRS_NAME);
                break;
            }
        }
        final CurrencyPairs baseQuotePairs = OpenGammaCompilationContext.getCurrencyPairsSource(context)
                .getCurrencyPairs(currencyPairConfigName);
        final FinancialSecurity security = (FinancialSecurity) target.getSecurity();
        final Currency putCurrency = security.accept(ForexVisitors.getPutCurrencyVisitor());
        final Currency callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor());
        final CurrencyPair baseQuotePair = baseQuotePairs.getCurrencyPair(putCurrency, callCurrency);
        if (baseQuotePair == null) {
            s_logger.error(
                    "Could not get base/quote pair for currency pair (" + putCurrency + ", " + callCurrency + ")");
            return null;
        }
        final String resultCurrency = getResultCurrency(target, baseQuotePair);
        final ValueProperties.Builder properties = getResultProperties(resultCurrency);
        return Collections.singleton(new ValueSpecification(ValueRequirementNames.VALUE_PHI,
                target.toSpecification(), properties.get()));
    }

    private ValueProperties.Builder getResultProperties() {
        return createValueProperties()
                .with(ValuePropertyNames.CALCULATION_METHOD, CalculationPropertyNamesAndValues.BLACK_METHOD)
                .withAny(FXOptionBlackFunction.PUT_CURVE).withAny(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG)
                .withAny(FXOptionBlackFunction.CALL_CURVE).withAny(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG)
                .withAny(ValuePropertyNames.SURFACE).withAny(InterpolatedDataProperties.X_INTERPOLATOR_NAME)
                .withAny(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME)
                .withAny(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME).withAny(ValuePropertyNames.CURRENCY);
    }

    private ValueProperties.Builder getResultProperties(final String currency) {
        return createValueProperties()
                .with(ValuePropertyNames.CALCULATION_METHOD, CalculationPropertyNamesAndValues.BLACK_METHOD)
                .withAny(FXOptionBlackFunction.PUT_CURVE).withAny(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG)
                .withAny(FXOptionBlackFunction.CALL_CURVE).withAny(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG)
                .withAny(ValuePropertyNames.SURFACE).withAny(InterpolatedDataProperties.X_INTERPOLATOR_NAME)
                .withAny(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME)
                .withAny(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME)
                .with(ValuePropertyNames.CURRENCY, currency);
    }

    private ValueProperties.Builder getResultProperties(final ComputationTarget target,
            final ValueRequirement desiredValue, final CurrencyPair baseQuotePair) {
        final String putCurveName = desiredValue.getConstraint(FXOptionBlackFunction.PUT_CURVE);
        final String callCurveName = desiredValue.getConstraint(FXOptionBlackFunction.CALL_CURVE);
        final String putCurveCalculationConfig = desiredValue
                .getConstraint(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG);
        final String callCurveCalculationConfig = desiredValue
                .getConstraint(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG);
        final String interpolatorName = desiredValue.getConstraint(InterpolatedDataProperties.X_INTERPOLATOR_NAME);
        final String leftExtrapolatorName = desiredValue
                .getConstraint(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME);
        final String rightExtrapolatorName = desiredValue
                .getConstraint(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME);
        final String surfaceName = desiredValue.getConstraint(ValuePropertyNames.SURFACE);
        return createValueProperties()
                .with(ValuePropertyNames.CALCULATION_METHOD, CalculationPropertyNamesAndValues.BLACK_METHOD)
                .with(FXOptionBlackFunction.PUT_CURVE, putCurveName)
                .with(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG, putCurveCalculationConfig)
                .with(FXOptionBlackFunction.CALL_CURVE, callCurveName)
                .with(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG, callCurveCalculationConfig)
                .with(ValuePropertyNames.SURFACE, surfaceName)
                .with(InterpolatedDataProperties.X_INTERPOLATOR_NAME, interpolatorName)
                .with(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME, leftExtrapolatorName)
                .with(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME, rightExtrapolatorName)
                .with(ValuePropertyNames.CURRENCY, getResultCurrency(target, baseQuotePair));
    }

    private static ValueRequirement getCurveSensitivitiesRequirement(final String putCurveName,
            final String putCurveCalculationConfig, final String callCurveName,
            final String callCurveCalculationConfig, final String surfaceName, final String interpolatorName,
            final String leftExtrapolatorName, final String rightExtrapolatorName, final ComputationTarget target) {
        final ValueProperties properties = ValueProperties.builder()
                .with(FXOptionBlackFunction.PUT_CURVE, putCurveName)
                .with(FXOptionBlackFunction.CALL_CURVE, callCurveName)
                .with(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG, putCurveCalculationConfig)
                .with(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG, callCurveCalculationConfig)
                .with(ValuePropertyNames.SURFACE, surfaceName)
                .with(ValuePropertyNames.CALCULATION_METHOD, CalculationPropertyNamesAndValues.BLACK_METHOD)
                .with(InterpolatedDataProperties.X_INTERPOLATOR_NAME, interpolatorName)
                .with(InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME, leftExtrapolatorName)
                .with(InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME, rightExtrapolatorName).get();
        return new ValueRequirement(ValueRequirementNames.FX_CURVE_SENSITIVITIES, target.toSpecification(),
                properties);
    }

}