/** * 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.SURFACE; 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_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.Map; import java.util.Set; import com.google.common.collect.Sets; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.model.volatility.smile.fitting.interpolation.GeneralSmileInterpolator; import com.opengamma.analytics.financial.model.volatility.smile.fitting.interpolation.SmileInterpolatorSpline; import com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.SmileSurfaceDataBundle; import com.opengamma.analytics.financial.model.volatility.surface.BlackVolatilitySurface; import com.opengamma.analytics.financial.model.volatility.surface.VolatilitySurfaceInterpolator; 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.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.curve.forward.ForwardCurveValuePropertyNames; /** * * @deprecated Deprecated */ @Deprecated public abstract class PiecewiseSABRSurfaceFunction extends AbstractFunction.NonCompiledInvoker { @Override public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final ValueRequirement desiredValue = desiredValues.iterator().next(); final String surfaceType = desiredValue.getConstraint(PROPERTY_SURFACE_TYPE); final boolean moneynessSurface = LocalVolatilityPDEUtils.isMoneynessSurface(surfaceType); if (!moneynessSurface) { throw new OpenGammaRuntimeException("Cannot handle surface type other than moneyness; asked for strike"); } final String xAxis = desiredValue.getConstraint(PROPERTY_X_AXIS); final boolean useLogTime = LocalVolatilityPDEUtils.useLogTime(xAxis); final String yAxis = desiredValue.getConstraint(PROPERTY_Y_AXIS); final boolean useIntegratedVariance = LocalVolatilityPDEUtils.useIntegratedVariance(yAxis); final String yAxisType = desiredValue.getConstraint(PROPERTY_Y_AXIS_TYPE); final boolean useLogValue = LocalVolatilityPDEUtils.useLogValue(yAxisType); final String surfaceName = desiredValue.getConstraint(SURFACE); final String curveCalculationMethodName = desiredValue.getConstraint(ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_CALCULATION_METHOD); final String forwardCurveName = desiredValue.getConstraint(CURVE); //TODO R White testing using spline rather than SABR - this should be an option final GeneralSmileInterpolator smileInterpolator = new SmileInterpolatorSpline(); final VolatilitySurfaceInterpolator surfaceFitter = new VolatilitySurfaceInterpolator(smileInterpolator, useLogTime, useIntegratedVariance, useLogValue); // final PiecewiseSABRSurfaceFitter1<?> surfaceFitter = new MoneynessPiecewiseSABRSurfaceFitter(useLogTime, useIntegratedVariance, useLogValue); final SmileSurfaceDataBundle data = getData(inputs, getVolatilityDataRequirement(target, surfaceName), getForwardCurveRequirement(target, curveCalculationMethodName, forwardCurveName)); final BlackVolatilitySurface<?> impliedVolatilitySurface = surfaceFitter.getVolatilitySurface(data); final ValueProperties properties = getResultProperties(surfaceName, surfaceType, xAxis, yAxis, yAxisType, curveCalculationMethodName, forwardCurveName); final ValueSpecification spec = new ValueSpecification(ValueRequirementNames.PIECEWISE_SABR_VOL_SURFACE, target.toSpecification(), properties); return Collections.singleton(new ComputedValue(spec, impliedVolatilitySurface)); } @Override public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target) { final ValueProperties properties = getResultProperties(); return Collections.singleton(new ValueSpecification(ValueRequirementNames.PIECEWISE_SABR_VOL_SURFACE, target.toSpecification(), properties)); } @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 String surfaceName = surfaceNames.iterator().next(); final Set<String> forwardCurveCalculationMethodNames = constraints.getValues(ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_CALCULATION_METHOD); if (forwardCurveCalculationMethodNames == null || forwardCurveCalculationMethodNames.size() != 1) { return null; } final String forwardCurveCalculationMethod = forwardCurveCalculationMethodNames.iterator().next(); final Set<String> forwardCurveNames = constraints.getValues(CURVE); if (forwardCurveNames == null || forwardCurveNames.size() != 1) { return null; } final String forwardCurveName = forwardCurveNames.iterator().next(); final Set<String> surfaceTypes = constraints.getValues(PROPERTY_SURFACE_TYPE); if (surfaceTypes == null || surfaceTypes.size() != 1) { return null; } final Set<String> xAxes = constraints.getValues(PROPERTY_X_AXIS); if (xAxes == null || xAxes.size() != 1) { return null; } final Set<String> yAxes = constraints.getValues(PROPERTY_Y_AXIS); if (yAxes == null || yAxes.size() != 1) { return null; } final Set<String> yAxisTypes = constraints.getValues(PROPERTY_Y_AXIS_TYPE); if (yAxisTypes == null || yAxisTypes.size() != 1) { return null; } return Sets.newHashSet(getVolatilityDataRequirement(target, surfaceName), getForwardCurveRequirement(target, forwardCurveCalculationMethod, forwardCurveName)); } @Override public Set<ValueSpecification> getResults(final FunctionCompilationContext context, final ComputationTarget target, final Map<ValueSpecification, ValueRequirement> inputs) { String surfaceName = null; String forwardCurveCalculationMethod = null; String forwardCurveName = null; for (final Map.Entry<ValueSpecification, ValueRequirement> input : inputs.entrySet()) { final ValueProperties constraints = input.getValue().getConstraints(); if (input.getValue().getValueName().equals(ValueRequirementNames.FORWARD_CURVE)) { if (constraints.getValues(ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_CALCULATION_METHOD) != null) { final Set<String> forwardCurveCalculationMethodNames = constraints.getValues(ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_CALCULATION_METHOD); if (forwardCurveCalculationMethodNames == null || forwardCurveCalculationMethodNames.size() != 1) { throw new OpenGammaRuntimeException("Missing or non-unique forward curve calculation method name"); } forwardCurveCalculationMethod = forwardCurveCalculationMethodNames.iterator().next(); } if (constraints.getValues(CURVE) != null) { final Set<String> forwardCurveNames = constraints.getValues(CURVE); if (forwardCurveNames == null || forwardCurveNames.size() != 1) { throw new OpenGammaRuntimeException("Missing or non-unique forward curve name"); } forwardCurveName = forwardCurveNames.iterator().next(); } } else if (input.getValue().getValueName().equals(ValueRequirementNames.VOLATILITY_SURFACE_DATA)) { if (constraints.getValues(ValuePropertyNames.SURFACE) != null) { final Set<String> surfaceNames = constraints.getValues(ValuePropertyNames.SURFACE); if (surfaceNames == null || surfaceNames.size() != 1) { throw new OpenGammaRuntimeException("Missing or non-unique surface name"); } surfaceName = surfaceNames.iterator().next(); } } } assert surfaceName != null; assert forwardCurveCalculationMethod != null; assert forwardCurveName != null; final ValueProperties properties = getResultProperties(surfaceName, forwardCurveCalculationMethod, forwardCurveName); return Collections.singleton(new ValueSpecification(ValueRequirementNames.PIECEWISE_SABR_VOL_SURFACE, target.toSpecification(), properties)); } protected abstract SmileSurfaceDataBundle getData(FunctionInputs inputs, ValueRequirement volDataRequirement, ValueRequirement forwardCurveRequirement); protected abstract ValueProperties getResultProperties(); protected abstract ValueProperties getResultProperties(final String definitionName, final String forwardCurveCalculationMethod, final String forwardCurveName); protected abstract ValueProperties getResultProperties(final String definitionName, final String surfaceType, final String xAxis, final String yAxis, final String yAxisType, final String forwardCurveCalculationMethod, final String forwardCurveName); protected abstract ValueRequirement getVolatilityDataRequirement(final ComputationTarget target, final String surfaceName); private ValueRequirement getForwardCurveRequirement(final ComputationTarget target, final String calculationMethod, final String forwardCurveName) { final ValueProperties properties = ValueProperties.builder() .with(ForwardCurveValuePropertyNames.PROPERTY_FORWARD_CURVE_CALCULATION_METHOD, calculationMethod) .with(CURVE, forwardCurveName).get(); return new ValueRequirement(ValueRequirementNames.FORWARD_CURVE, target.toSpecification(), properties); } }