/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.volatility.local.deprecated; import static com.opengamma.engine.value.ValuePropertyNames.CURVE; import static com.opengamma.engine.value.ValuePropertyNames.CURVE_CALCULATION_METHOD; import static com.opengamma.engine.value.ValuePropertyNames.SURFACE; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_H; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_MAX_MONEYNESS; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_PDE_DIRECTION; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_SPACE_GRID_BUNCHING; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_SPACE_STEPS; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_SURFACE_TYPE; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_THETA; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_TIME_GRID_BUNCHING; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_TIME_STEPS; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_X_AXIS; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_Y_AXIS; import static com.opengamma.financial.analytics.model.volatility.local.deprecated.LocalVolatilityPDEValuePropertyNames.PROPERTY_Y_AXIS_TYPE; import java.util.Collections; import java.util.Set; import com.google.common.collect.Sets; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.greeks.PDEResultCollection; 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.analytics.model.InstrumentTypeProperties; import com.opengamma.financial.analytics.model.forex.ConventionBasedFXRateFunction; import com.opengamma.financial.security.FinancialSecurityTypes; import com.opengamma.financial.security.option.FXOptionSecurity; import com.opengamma.util.money.Currency; /** * @deprecated Deprecated */ @Deprecated public class ForexLocalVolatilityPDEGridPresentValueFunction extends AbstractFunction.NonCompiledInvoker { @Override public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final FXOptionSecurity fxOption = (FXOptionSecurity) target.getSecurity(); final ValueRequirement desiredValue = desiredValues.iterator().next(); final String surfaceName = desiredValue.getConstraint(SURFACE); final String surfaceType = desiredValue.getConstraint(PROPERTY_SURFACE_TYPE); final String xAxis = desiredValue.getConstraint(PROPERTY_X_AXIS); final String yAxis = desiredValue.getConstraint(PROPERTY_Y_AXIS); final String yAxisType = desiredValue.getConstraint(PROPERTY_Y_AXIS_TYPE); final String forwardCurveCalculationMethod = desiredValue.getConstraint(CURVE_CALCULATION_METHOD); final String forwardCurveName = desiredValue.getConstraint(CURVE); final String h = desiredValue.getConstraint(PROPERTY_H); final String theta = desiredValue.getConstraint(PROPERTY_THETA); final String timeSteps = desiredValue.getConstraint(PROPERTY_TIME_STEPS); final String spaceSteps = desiredValue.getConstraint(PROPERTY_SPACE_STEPS); final String timeGridBunching = desiredValue.getConstraint(PROPERTY_TIME_GRID_BUNCHING); final String spaceGridBunching = desiredValue.getConstraint(PROPERTY_SPACE_GRID_BUNCHING); final String maxMoneyness = desiredValue.getConstraint(PROPERTY_MAX_MONEYNESS); final String pdeDirection = desiredValue.getConstraint(PROPERTY_PDE_DIRECTION); if (!(pdeDirection.equals(LocalVolatilityPDEValuePropertyNames.FORWARD_PDE))) { throw new OpenGammaRuntimeException("Can only use forward PDE; should never ask for this direction: " + pdeDirection); } final Object greekObject = inputs.getValue(getGreekRequirement(target, surfaceName, surfaceType, xAxis, yAxis, yAxisType, forwardCurveCalculationMethod, forwardCurveName, theta, timeSteps, spaceSteps, timeGridBunching, spaceGridBunching, maxMoneyness, h, pdeDirection)); if (greekObject == null) { throw new OpenGammaRuntimeException("Could not get greeks"); } final PDEResultCollection greeks = (PDEResultCollection) greekObject; final Object spotFXObject = inputs.getValue(getSpotRequirement(fxOption)); if (spotFXObject == null) { throw new OpenGammaRuntimeException("Could not get spot FX"); } final double[] strikes = greeks.getStrikes(); final double[] lvPutPips = greeks.getGridGreeks(PDEResultCollection.GRID_PRICE); final double[] blackPutPips = greeks.getGridGreeks(PDEResultCollection.GRID_BLACK_PRICE); final double spotFX = (Double) spotFXObject; final Currency putCurrency = fxOption.getPutCurrency(); final Currency callCurrency = fxOption.getCallCurrency(); final double putAmount = fxOption.getPutAmount(); final double callAmount = fxOption.getCallAmount(); final ForexLocalVolatilityPDEPresentValueResultCollection result = new ForexLocalVolatilityPDEPresentValueResultCollection(strikes, lvPutPips, blackPutPips, spotFX, putCurrency, callCurrency, putAmount, callAmount); final ValueProperties properties = createValueProperties() .with(ValuePropertyNames.CALCULATION_METHOD, LocalVolatilityPDEValuePropertyNames.LOCAL_VOLATILITY_METHOD) .with(InstrumentTypeProperties.PROPERTY_SURFACE_INSTRUMENT_TYPE, InstrumentTypeProperties.FOREX) .with(SURFACE, surfaceName) .with(PROPERTY_SURFACE_TYPE, surfaceType) .with(PROPERTY_X_AXIS, xAxis) .with(PROPERTY_Y_AXIS, yAxis) .with(PROPERTY_Y_AXIS_TYPE, yAxisType) .with(CURVE_CALCULATION_METHOD, forwardCurveCalculationMethod) .with(CURVE, forwardCurveName) .with(PROPERTY_THETA, theta) .with(PROPERTY_TIME_STEPS, timeSteps) .with(PROPERTY_SPACE_STEPS, spaceSteps) .with(PROPERTY_TIME_GRID_BUNCHING, timeGridBunching) .with(PROPERTY_SPACE_GRID_BUNCHING, spaceGridBunching) .with(PROPERTY_MAX_MONEYNESS, maxMoneyness) .with(PROPERTY_H, h) .with(PROPERTY_PDE_DIRECTION, pdeDirection).get(); final ValueSpecification resultSpec = new ValueSpecification(ValueRequirementNames.LOCAL_VOLATILITY_FOREX_PV_QUOTES, target.toSpecification(), properties); return Collections.singleton(new ComputedValue(resultSpec, result)); } @Override public ComputationTargetType getTargetType() { return FinancialSecurityTypes.FX_OPTION_SECURITY; } @Override public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target) { final ValueProperties properties = createValueProperties() .with(ValuePropertyNames.CALCULATION_METHOD, LocalVolatilityPDEValuePropertyNames.LOCAL_VOLATILITY_METHOD) .with(InstrumentTypeProperties.PROPERTY_SURFACE_INSTRUMENT_TYPE, InstrumentTypeProperties.FOREX) .withAny(SURFACE) .withAny(PROPERTY_SURFACE_TYPE) .withAny(PROPERTY_X_AXIS) .withAny(PROPERTY_Y_AXIS) .withAny(PROPERTY_Y_AXIS_TYPE) .withAny(CURVE_CALCULATION_METHOD) .withAny(CURVE) .withAny(PROPERTY_THETA) .withAny(PROPERTY_TIME_STEPS) .withAny(PROPERTY_SPACE_STEPS) .withAny(PROPERTY_TIME_GRID_BUNCHING) .withAny(PROPERTY_SPACE_GRID_BUNCHING) .withAny(PROPERTY_MAX_MONEYNESS) .withAny(PROPERTY_H) .withAny(PROPERTY_PDE_DIRECTION).get(); final ValueSpecification result = new ValueSpecification(ValueRequirementNames.LOCAL_VOLATILITY_FOREX_PV_QUOTES, target.toSpecification(), properties); return Collections.singleton(result); } @Override public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) { final ValueProperties constraints = desiredValue.getConstraints(); final Set<String> surfaceNames = constraints.getValues(SURFACE); if (surfaceNames == null || surfaceNames.size() != 1) { return null; } final Set<String> surfaceTypeNames = constraints.getValues(PROPERTY_SURFACE_TYPE); if (surfaceTypeNames == null || surfaceTypeNames.size() != 1) { return null; } final Set<String> xAxisNames = constraints.getValues(PROPERTY_X_AXIS); if (xAxisNames == null || xAxisNames.size() != 1) { return null; } final Set<String> yAxisNames = constraints.getValues(PROPERTY_Y_AXIS); if (yAxisNames == null || yAxisNames.size() != 1) { return null; } final Set<String> yAxisTypeNames = constraints.getValues(PROPERTY_Y_AXIS_TYPE); if (yAxisTypeNames == null || yAxisTypeNames.size() != 1) { return null; } final Set<String> forwardCurveCalculationMethodNames = constraints.getValues(CURVE_CALCULATION_METHOD); if (forwardCurveCalculationMethodNames == null || forwardCurveCalculationMethodNames.size() != 1) { return null; } final Set<String> hNames = constraints.getValues(PROPERTY_H); if (hNames == null || hNames.size() != 1) { return null; } final Set<String> forwardCurveNames = constraints.getValues(CURVE); if (forwardCurveNames == null || forwardCurveNames.size() != 1) { return null; } final Set<String> thetaNames = constraints.getValues(PROPERTY_THETA); if (thetaNames == null || thetaNames.size() != 1) { return null; } final Set<String> timeStepsNames = constraints.getValues(PROPERTY_TIME_STEPS); if (timeStepsNames == null || timeStepsNames.size() != 1) { return null; } final Set<String> spaceStepsNames = constraints.getValues(PROPERTY_SPACE_STEPS); if (spaceStepsNames == null || spaceStepsNames.size() != 1) { return null; } final Set<String> timeGridBunchingNames = constraints.getValues(PROPERTY_TIME_GRID_BUNCHING); if (timeGridBunchingNames == null || timeGridBunchingNames.size() != 1) { return null; } final Set<String> spaceGridBunchingNames = constraints.getValues(PROPERTY_SPACE_GRID_BUNCHING); if (spaceGridBunchingNames == null || spaceGridBunchingNames.size() != 1) { return null; } final Set<String> maxMoneynessNames = constraints.getValues(PROPERTY_MAX_MONEYNESS); if (maxMoneynessNames == null || maxMoneynessNames.size() != 1) { return null; } final Set<String> pdeDirectionNames = constraints.getValues(PROPERTY_PDE_DIRECTION); if (pdeDirectionNames == null || pdeDirectionNames.size() != 1) { return null; } final String surfaceType = surfaceTypeNames.iterator().next(); final String xAxis = xAxisNames.iterator().next(); final String yAxis = yAxisNames.iterator().next(); final String yAxisType = yAxisTypeNames.iterator().next(); final String forwardCurveCalculationMethod = forwardCurveCalculationMethodNames.iterator().next(); final String h = hNames.iterator().next(); final String forwardCurveName = forwardCurveNames.iterator().next(); final String surfaceName = surfaceNames.iterator().next(); final String theta = thetaNames.iterator().next(); final String timeSteps = timeStepsNames.iterator().next(); final String spaceSteps = spaceStepsNames.iterator().next(); final String timeGridBunching = timeGridBunchingNames.iterator().next(); final String spaceGridBunching = spaceGridBunchingNames.iterator().next(); final String maxMoneyness = maxMoneynessNames.iterator().next(); final String pdeDirection = pdeDirectionNames.iterator().next(); return Sets.newHashSet(getGreekRequirement(target, surfaceName, surfaceType, xAxis, yAxis, yAxisType, forwardCurveCalculationMethod, forwardCurveName, theta, timeSteps, spaceSteps, timeGridBunching, spaceGridBunching, maxMoneyness, h, pdeDirection), getSpotRequirement((FXOptionSecurity) target.getSecurity())); } private ValueRequirement getGreekRequirement(final ComputationTarget target, final String surfaceName, final String surfaceType, final String xAxis, final String yAxis, final String yAxisType, final String forwardCurveCalculationMethod, final String forwardCurveName, final String theta, final String timeSteps, final String spaceSteps, final String timeGridBunching, final String spaceGridBunching, final String maxMoneyness, final String h, final String pdeDirection) { final ValueProperties properties = ValueProperties.builder() .with(ValuePropertyNames.CALCULATION_METHOD, LocalVolatilityPDEValuePropertyNames.LOCAL_VOLATILITY_METHOD) .with(InstrumentTypeProperties.PROPERTY_SURFACE_INSTRUMENT_TYPE, InstrumentTypeProperties.FOREX) .with(SURFACE, surfaceName) .with(PROPERTY_SURFACE_TYPE, surfaceType) .with(PROPERTY_X_AXIS, xAxis) .with(PROPERTY_Y_AXIS, yAxis) .with(PROPERTY_Y_AXIS_TYPE, yAxisType) .with(CURVE_CALCULATION_METHOD, forwardCurveCalculationMethod) .with(CURVE, forwardCurveName) .with(PROPERTY_THETA, theta) .with(PROPERTY_TIME_STEPS, timeSteps) .with(PROPERTY_SPACE_STEPS, spaceSteps) .with(PROPERTY_TIME_GRID_BUNCHING, timeGridBunching) .with(PROPERTY_SPACE_GRID_BUNCHING, spaceGridBunching) .with(PROPERTY_MAX_MONEYNESS, maxMoneyness) .with(PROPERTY_H, h) .with(PROPERTY_PDE_DIRECTION, pdeDirection).get(); return new ValueRequirement(ValueRequirementNames.LOCAL_VOLATILITY_PDE_GREEKS, target.toSpecification(), properties); } private ValueRequirement getSpotRequirement(final FXOptionSecurity security) { return ConventionBasedFXRateFunction.getSpotRateRequirement(security.getCallCurrency(), security.getPutCurrency()); } }