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

Java tutorial

Introduction

Here is the source code for com.opengamma.financial.analytics.model.forex.option.black.FXOptionBlackRhoFunction.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 java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Iterables;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.forex.method.MultipleCurrencyInterestRateCurveSensitivity;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.ComputationTargetType;
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.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.analytics.model.InterpolatedDataProperties;
import com.opengamma.financial.analytics.model.forex.ForexVisitors;
import com.opengamma.financial.security.FinancialSecurity;
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.util.async.AsynchronousExecution;
import com.opengamma.util.money.Currency;
import com.opengamma.util.tuple.DoublesPair;

/**
 * 
 */
public class FXOptionBlackRhoFunction extends AbstractFunction.NonCompiledInvoker {

    @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 String callCurrency = security.accept(ForexVisitors.getCallCurrencyVisitor()).getCode();
        final String callCurrencyCurve = desiredValue.getConstraint(FXOptionBlackFunction.CALL_CURVE);
        final String resultCurrency = FXOptionBlackSingleValuedFunction.getResultCurrency(target);
        final String fullCurveName = callCurrencyCurve + "_" + callCurrency;
        final MultipleCurrencyInterestRateCurveSensitivity curveSensitivities = (MultipleCurrencyInterestRateCurveSensitivity) curveSensitivitiesObject;
        final Map<String, List<DoublesPair>> sensitivitiesForCurrency = curveSensitivities
                .getSensitivity(Currency.of(resultCurrency)).getSensitivities();
        final ValueSpecification spec = new ValueSpecification(ValueRequirementNames.VALUE_RHO,
                target.toSpecification(), getResultProperties(target, desiredValue).get());
        final double rho = sensitivitiesForCurrency.get(fullCurveName).get(0).second;
        return Collections.singleton(new ComputedValue(spec, rho));
    }

    @Override
    public ComputationTargetType getTargetType() {
        return ComputationTargetType.SECURITY;
    }

    @Override
    public boolean canApplyTo(final FunctionCompilationContext context, final ComputationTarget target) {
        if (target.getType() != ComputationTargetType.SECURITY) {
            return false;
        }
        return target.getSecurity() instanceof FXOptionSecurity
                || target.getSecurity() instanceof FXBarrierOptionSecurity
                || target.getSecurity() instanceof FXDigitalOptionSecurity
                || target.getSecurity() instanceof NonDeliverableFXOptionSecurity
                || target.getSecurity() instanceof NonDeliverableFXDigitalOptionSecurity;
    }

    @Override
    public Set<ValueSpecification> getResults(final FunctionCompilationContext context,
            final ComputationTarget target) {
        final ValueProperties.Builder properties = getResultProperties(target);
        return Collections.singleton(new ValueSpecification(ValueRequirementNames.VALUE_RHO,
                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();
        return Collections.singleton(getCurveSensitivitiesRequirement(putCurveName, putCurveCalculationConfig,
                callCurveName, callCurveCalculationConfig, surfaceName, interpolatorName, leftExtrapolatorName,
                rightExtrapolatorName, target));
    }

    private ValueProperties.Builder getResultProperties(final ComputationTarget target) {
        return createValueProperties()
                .with(ValuePropertyNames.CALCULATION_METHOD, FXOptionBlackFunction.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, FXOptionBlackSingleValuedFunction.getResultCurrency(target));
    }

    private ValueProperties.Builder getResultProperties(final ComputationTarget target,
            final ValueRequirement desiredValue) {
        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, FXOptionBlackFunction.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, FXOptionBlackSingleValuedFunction.getResultCurrency(target));
    }

    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, FXOptionBlackFunction.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);
    }
}