/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model.carrlee;
import static com.opengamma.engine.value.ValuePropertyNames.CALCULATION_METHOD;
import static com.opengamma.engine.value.ValuePropertyNames.CURRENCY;
import static com.opengamma.engine.value.ValuePropertyNames.CURVE_EXPOSURES;
import static com.opengamma.engine.value.ValuePropertyNames.SURFACE;
import static com.opengamma.financial.analytics.model.CalculationPropertyNamesAndValues.PROPERTY_REALIZED_VARIANCE_METHOD;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.LEFT_X_EXTRAPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.RIGHT_X_EXTRAPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.InterpolatedDataProperties.X_INTERPOLATOR_NAME;
import static com.opengamma.financial.analytics.model.curve.CurveCalculationPropertyNamesAndValues.DISCOUNTING;
import static com.opengamma.financial.analytics.model.curve.CurveCalculationPropertyNamesAndValues.PROPERTY_CURVE_TYPE;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import com.opengamma.analytics.financial.forex.method.FXMatrix;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface;
import com.opengamma.analytics.financial.provider.description.volatilityswap.CarrLeeData;
import com.opengamma.core.holiday.HolidaySource;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionExecutionContext;
import com.opengamma.engine.function.FunctionInputs;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.financial.OpenGammaCompilationContext;
import com.opengamma.financial.analytics.conversion.FixedIncomeConverterDataProvider;
import com.opengamma.financial.analytics.conversion.DefaultTradeConverter;
import com.opengamma.financial.analytics.conversion.VolatilitySwapSecurityConverter;
import com.opengamma.financial.analytics.model.discounting.DiscountingFunction;
import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.financial.security.FinancialSecurityUtils;
/**
* Base function for all volatility swap pricing and risk function that use the Carr-Lee method.
*/
public abstract class CarrLeeVolatilitySwapFunction extends DiscountingFunction {
/** The calculation method */
public static final String CARR_LEE = "CarrLee";
/**
* @param valueRequirements The value requirement names, not null
*/
public CarrLeeVolatilitySwapFunction(final String... valueRequirements) {
super(valueRequirements);
}
@Override
protected DefaultTradeConverter getTargetToDefinitionConverter(final FunctionCompilationContext context) {
final HolidaySource holidaySource = OpenGammaCompilationContext.getHolidaySource(context);
final VolatilitySwapSecurityConverter securityConverter = new VolatilitySwapSecurityConverter(holidaySource);
return new DefaultTradeConverter(securityConverter);
}
/**
* Base compiled function for all pricing and risk functions that use the Carr-Lee method.
*/
protected abstract class CarrLeeVolatilitySwapCompiledFunction extends DiscountingCompiledFunction {
/**
* @param tradeToDefinitionConverter Converts targets to definitions, not null
* @param definitionToDerivativeConverter Converts definitions to derivatives, not null
* @param withCurrency True if the result properties set the {@link ValuePropertyNames#CURRENCY} property.
*/
protected CarrLeeVolatilitySwapCompiledFunction(final DefaultTradeConverter tradeToDefinitionConverter, final FixedIncomeConverterDataProvider definitionToDerivativeConverter,
final boolean withCurrency) {
super(tradeToDefinitionConverter, definitionToDerivativeConverter, withCurrency);
}
@SuppressWarnings("synthetic-access")
@Override
protected Collection<ValueProperties.Builder> getResultProperties(final FunctionCompilationContext context, final ComputationTarget target) {
final ValueProperties.Builder properties = createValueProperties()
.with(PROPERTY_CURVE_TYPE, DISCOUNTING)
.with(CALCULATION_METHOD, CARR_LEE)
.withAny(SURFACE)
.withAny(X_INTERPOLATOR_NAME)
.withAny(LEFT_X_EXTRAPOLATOR_NAME)
.withAny(RIGHT_X_EXTRAPOLATOR_NAME)
.withAny(PROPERTY_REALIZED_VARIANCE_METHOD)
.withAny(CURVE_EXPOSURES);
if (isWithCurrency()) {
final FinancialSecurity security = (FinancialSecurity) target.getTrade().getSecurity();
final String currency = FinancialSecurityUtils.getCurrency(security).getCode();
properties.with(CURRENCY, currency);
return Collections.singleton(properties);
}
return Collections.singleton(properties);
}
@Override
public Set<ValueRequirement> getRequirements(final FunctionCompilationContext context, final ComputationTarget target, final ValueRequirement desiredValue) {
final Set<ValueRequirement> requirements = super.getRequirements(context, target, desiredValue);
if (requirements == null) {
return null;
}
requirements.add(getVolatilitySurfaceRequirement(desiredValue, target));
requirements.add(getSpotRequirement(target));
// TODO ideally, realized variance should only be requested for seasoned swaps
requirements.add(getRealizedVarianceRequirement(desiredValue, target));
return requirements;
}
@Override
protected boolean requirementsSet(final ValueProperties constraints) {
final Set<String> surfaceNames = constraints.getValues(SURFACE);
if (surfaceNames == null) {
return false;
}
final Set<String> interpolatorNames = constraints.getValues(X_INTERPOLATOR_NAME);
if (interpolatorNames == null || interpolatorNames.size() != 1) {
return false;
}
final Set<String> leftExtrapolatorNames = constraints.getValues(LEFT_X_EXTRAPOLATOR_NAME);
if (leftExtrapolatorNames == null || leftExtrapolatorNames.size() != 1) {
return false;
}
final Set<String> rightExtrapolatorNames = constraints.getValues(RIGHT_X_EXTRAPOLATOR_NAME);
if (rightExtrapolatorNames == null || rightExtrapolatorNames.size() != 1) {
return false;
}
final Set<String> varianceCalculationMethods = constraints.getValues(PROPERTY_REALIZED_VARIANCE_METHOD);
if (varianceCalculationMethods == null || varianceCalculationMethods.size() != 1) {
return false;
}
return super.requirementsSet(constraints);
}
/**
* Gets the volatility surface requirement.
*
* @param desiredValue The desired value
* @param target The target
* @return The volatility surface requirement
*/
protected abstract ValueRequirement getVolatilitySurfaceRequirement(ValueRequirement desiredValue, ComputationTarget target);
/**
* Gets the spot requirement.
*
* @param target The target
* @return The spot requirement
*/
protected abstract ValueRequirement getSpotRequirement(ComputationTarget target);
/**
* Gets the realized variance requirement.
*
* @param desiredValue The desired vale
* @param target The target
* @return The realized variance requirement
*/
protected abstract ValueRequirement getRealizedVarianceRequirement(ValueRequirement desiredValue, ComputationTarget target);
/**
* Gets the Carr-Lee data.
*
* @param executionContext The execution context, not null
* @param inputs The function inputs, not null
* @param target The computation target, not null
* @param fxMatrix The FX matrix, not null
* @return The Carr-Lee data
*/
protected abstract CarrLeeData<? extends MulticurveProviderInterface, ?> getCarrLeeData(final FunctionExecutionContext executionContext, final FunctionInputs inputs,
final ComputationTarget target, final FXMatrix fxMatrix);
}
}