/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.equity.varianceswap; import java.util.Collections; import java.util.Set; import org.threeten.bp.Clock; import org.threeten.bp.LocalDate; import org.threeten.bp.ZonedDateTime; import com.google.common.collect.Iterables; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.equity.variance.EquityVarianceSwap; import com.opengamma.analytics.financial.equity.variance.EquityVarianceSwapDefinition; import com.opengamma.analytics.financial.equity.variance.pricing.AffineDividends; import com.opengamma.analytics.financial.equity.variance.pricing.EquityVarianceSwapPricer; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve; import com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.SmileSurfaceDataBundle; import com.opengamma.core.historicaltimeseries.HistoricalTimeSeries; import com.opengamma.core.value.MarketDataRequirementNames; import com.opengamma.engine.ComputationTarget; 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.volatility.local.PDEPropertyNamesAndValues; import com.opengamma.financial.security.equity.EquityVarianceSwapSecurity; import com.opengamma.timeseries.DoubleTimeSeries; import com.opengamma.util.async.AsynchronousExecution; /** * */ public class EquityVarianceSwapPureLocalVolPVFunction extends EquityVarianceSwapFunction { @Override public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) throws AsynchronousExecution { final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = ZonedDateTime.now(snapshotClock); final ValueRequirement desiredValue = Iterables.getOnlyElement(desiredValues); final EquityVarianceSwapSecurity security = (EquityVarianceSwapSecurity) target.getSecurity(); final EquityVarianceSwapDefinition definition = security.accept(getConverter()); final Object spotObject = inputs.getValue(MarketDataRequirementNames.MARKET_VALUE); if (spotObject == null) { throw new OpenGammaRuntimeException("Spot value was null"); } final Object yieldCurveObject = inputs.getValue(ValueRequirementNames.YIELD_CURVE); if (yieldCurveObject == null) { throw new OpenGammaRuntimeException("Yield curve was null"); } final Object dividendsObject = inputs.getValue(ValueRequirementNames.AFFINE_DIVIDENDS); if (dividendsObject == null) { throw new OpenGammaRuntimeException("Dividends were null"); } final Object forwardCurveObject = inputs.getValue(ValueRequirementNames.FORWARD_CURVE); if (forwardCurveObject == null) { throw new OpenGammaRuntimeException("Forward curve was null"); } final Object volatilitiesObject = inputs.getValue(ValueRequirementNames.STANDARD_VOLATILITY_SURFACE_DATA); if (volatilitiesObject == null) { throw new OpenGammaRuntimeException("Volatility data were null"); } final Object tsObject = inputs.getValue(ValueRequirementNames.HISTORICAL_TIME_SERIES); final double spot = (Double) spotObject; final YieldAndDiscountCurve yieldCurve = (YieldAndDiscountCurve) yieldCurveObject; final AffineDividends dividends = (AffineDividends) dividendsObject; final SmileSurfaceDataBundle volatilities = getData(inputs); final DoubleTimeSeries<LocalDate> underlyingTS = ((HistoricalTimeSeries) tsObject).getTimeSeries(); final EquityVarianceSwap swap = definition.toDerivative(now, underlyingTS); final EquityVarianceSwapPricer pricer = EquityVarianceSwapPricer.builder().create(); //TODO don't just use defaults final double pv = pricer.priceFromImpliedVolsBackwardPDE(swap, spot, yieldCurve, dividends, volatilities); final ValueProperties properties = desiredValue.getConstraints().copy() .withoutAny(ValuePropertyNames.FUNCTION).with(ValuePropertyNames.FUNCTION, getUniqueId()).get(); final ValueSpecification spec = new ValueSpecification(getValueRequirementName(), target.toSpecification(), properties); return Collections.singleton(new ComputedValue(spec, pv)); } @Override protected String getValueRequirementName() { return ValueRequirementNames.PRESENT_VALUE; } @Override protected String getCalculationMethod() { return PDEPropertyNamesAndValues.BACKWARDS; } @Override protected String getVolatilitySurfaceType() { return PURE_LOCAL_VOLATILITY; } }