/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.model;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.interestrate.YieldCurveBundle;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.function.FunctionInputs;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.value.ValuePropertiesUtils;
import com.opengamma.engine.value.ValuePropertyNames;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.financial.analytics.ircurve.calcconfig.ConfigDBCurveCalculationConfigSource;
import com.opengamma.financial.analytics.ircurve.calcconfig.MultiCurveCalculationConfig;
import com.opengamma.financial.analytics.model.forex.option.black.FXOptionBlackFunction;
/**
*
*/
public class YieldCurveFunctionUtils {
public static Set<ValueRequirement> getCurveRequirements(final MultiCurveCalculationConfig curveConfig, final ConfigDBCurveCalculationConfigSource configSource) {
final Set<ValueRequirement> requirements = new HashSet<>();
if (curveConfig.getExogenousConfigData() != null) {
final LinkedHashMap<String, String[]> exogenousCurves = curveConfig.getExogenousConfigData();
for (final Map.Entry<String, String[]> entry : exogenousCurves.entrySet()) {
final String exogenousConfigName = entry.getKey();
final MultiCurveCalculationConfig exogenousConfig = configSource.getConfig(exogenousConfigName);
final ComputationTargetSpecification target = exogenousConfig.getTarget();
final String curveCalculationMethod = exogenousConfig.getCalculationMethod();
for (final String exogenousCurveName : entry.getValue()) {
requirements.add(getCurveRequirement(target, exogenousCurveName, exogenousConfigName, curveCalculationMethod));
}
requirements.addAll(getCurveRequirements(exogenousConfig, configSource));
}
}
final String[] yieldCurveNames = curveConfig.getYieldCurveNames();
final String curveCalculationConfigName = curveConfig.getCalculationConfigName();
final String curveCalculationMethod = curveConfig.getCalculationMethod();
final ComputationTargetSpecification target = curveConfig.getTarget();
for (final String yieldCurveName : yieldCurveNames) {
requirements.add(getCurveRequirement(target, yieldCurveName, curveCalculationConfigName, curveCalculationMethod));
}
return requirements;
}
public static Set<ValueRequirement> getCurveRequirements(final MultiCurveCalculationConfig curveConfig, final ConfigDBCurveCalculationConfigSource configSource,
final ValueRequirement desiredValue) {
final Set<ValueRequirement> requirements = new HashSet<>();
if (curveConfig.getExogenousConfigData() != null) {
final LinkedHashMap<String, String[]> exogenousCurves = curveConfig.getExogenousConfigData();
for (final Map.Entry<String, String[]> entry : exogenousCurves.entrySet()) {
final String exogenousConfigName = entry.getKey();
final MultiCurveCalculationConfig exogenousConfig = configSource.getConfig(exogenousConfigName);
final ComputationTargetSpecification target = exogenousConfig.getTarget();
final String curveCalculationMethod = exogenousConfig.getCalculationMethod();
for (final String exogenousCurveName : entry.getValue()) {
requirements.add(getCurveRequirement(target, exogenousCurveName, exogenousConfigName, curveCalculationMethod));
}
requirements.addAll(getCurveRequirements(exogenousConfig, configSource));
}
}
final ValueProperties constraints = desiredValue.getConstraints();
final String[] yieldCurveNames = curveConfig.getYieldCurveNames();
final String curveCalculationConfigName;
if (constraints.getValues(ValuePropertyNames.CURVE_CALCULATION_CONFIG) == null) {
curveCalculationConfigName = curveConfig.getCalculationConfigName();
} else {
curveCalculationConfigName = Iterables.getOnlyElement(constraints.getValues(ValuePropertyNames.CURVE_CALCULATION_CONFIG));
}
final String curveCalculationMethod = curveConfig.getCalculationMethod();
final ComputationTargetSpecification target = curveConfig.getTarget();
for (final String yieldCurveName : yieldCurveNames) {
requirements.add(getCurveRequirement(target, yieldCurveName, curveCalculationConfigName, curveCalculationMethod));
}
return requirements;
}
public static ValueRequirement getCurveRequirement(final ComputationTargetSpecification target, final String yieldCurveName, final String curveCalculationConfigName,
final String curveCalculationMethod) {
final ValueProperties properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(ValuePropertyNames.CURVE_CALCULATION_METHOD, curveCalculationMethod).get();
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target, properties);
}
public static ValueRequirement getCurveRequirement(final ComputationTargetSpecification target, final String yieldCurveName, final String curveCalculationConfigName) {
final ValueProperties properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName).get();
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target, properties);
}
public static ValueRequirement getCurveRequirementForFXOption(final ComputationTargetSpecification target, final String yieldCurveName, final String curveCalculationConfigName,
final String curveCalculationMethod, final boolean isPut) {
final ValueProperties properties;
if (isPut) {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(ValuePropertyNames.CURVE_CALCULATION_METHOD, curveCalculationMethod)
.with(FXOptionBlackFunction.PUT_CURVE, yieldCurveName).withOptional(FXOptionBlackFunction.PUT_CURVE)
.with(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG, curveCalculationConfigName).withOptional(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG)
.get();
} else {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(ValuePropertyNames.CURVE_CALCULATION_METHOD, curveCalculationMethod)
.with(FXOptionBlackFunction.CALL_CURVE, yieldCurveName).withOptional(FXOptionBlackFunction.CALL_CURVE)
.with(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG, curveCalculationConfigName).withOptional(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG)
.get();
}
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target, properties);
}
public static ValueRequirement getCurveRequirementForFXOption(final ComputationTargetSpecification target, final String yieldCurveName, final String curveCalculationConfigName,
final boolean isPut, final ValueProperties optionalProperties) {
final ValueProperties properties;
if (isPut) {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(FXOptionBlackFunction.PUT_CURVE, yieldCurveName).withOptional(FXOptionBlackFunction.PUT_CURVE)
.with(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG, curveCalculationConfigName).withOptional(FXOptionBlackFunction.PUT_CURVE_CALC_CONFIG)
.get();
} else {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(FXOptionBlackFunction.CALL_CURVE, yieldCurveName).withOptional(FXOptionBlackFunction.CALL_CURVE)
.with(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG, curveCalculationConfigName).withOptional(FXOptionBlackFunction.CALL_CURVE_CALC_CONFIG)
.get();
}
final ValueProperties allProperties = ValuePropertiesUtils.addAllOptional(properties, optionalProperties).get();
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target, allProperties);
}
public static ValueRequirement getCurveRequirementForFXForward(final ComputationTargetSpecification target, final String yieldCurveName, final String curveCalculationConfigName,
final String curveCalculationMethod, final boolean isPay) {
final ValueProperties properties;
if (isPay) {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(ValuePropertyNames.CURVE_CALCULATION_METHOD, curveCalculationMethod)
.with(ValuePropertyNames.PAY_CURVE, yieldCurveName).withOptional(ValuePropertyNames.PAY_CURVE)
.with(ValuePropertyNames.PAY_CURVE_CALCULATION_CONFIG, curveCalculationConfigName).withOptional(ValuePropertyNames.PAY_CURVE_CALCULATION_CONFIG)
.get();
} else {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(ValuePropertyNames.CURVE_CALCULATION_METHOD, curveCalculationMethod)
.with(ValuePropertyNames.RECEIVE_CURVE, yieldCurveName).withOptional(ValuePropertyNames.RECEIVE_CURVE)
.with(ValuePropertyNames.RECEIVE_CURVE_CALCULATION_CONFIG, curveCalculationConfigName).withOptional(ValuePropertyNames.RECEIVE_CURVE_CALCULATION_CONFIG)
.get();
}
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target, properties);
}
public static ValueRequirement getCurveRequirementForFXForward(final ComputationTargetSpecification target, final String yieldCurveName, final String curveCalculationConfigName,
final boolean isPay) {
final ValueProperties properties;
if (isPay) {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(ValuePropertyNames.PAY_CURVE, yieldCurveName).withOptional(ValuePropertyNames.PAY_CURVE)
.with(ValuePropertyNames.PAY_CURVE_CALCULATION_CONFIG, curveCalculationConfigName).withOptional(ValuePropertyNames.PAY_CURVE_CALCULATION_CONFIG)
.get();
} else {
properties = ValueProperties.builder()
.with(ValuePropertyNames.CURVE, yieldCurveName)
.with(ValuePropertyNames.CURVE_CALCULATION_CONFIG, curveCalculationConfigName)
.with(ValuePropertyNames.RECEIVE_CURVE, yieldCurveName).withOptional(ValuePropertyNames.RECEIVE_CURVE)
.with(ValuePropertyNames.RECEIVE_CURVE_CALCULATION_CONFIG, curveCalculationConfigName).withOptional(ValuePropertyNames.RECEIVE_CURVE_CALCULATION_CONFIG)
.get();
}
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target, properties);
}
public static ValueRequirement getCurveRequirement(final ComputationTargetSpecification target) {
return new ValueRequirement(ValueRequirementNames.YIELD_CURVE, target);
}
//TODO won't work if curves have different currencies
public static YieldCurveBundle getAllYieldCurves(final FunctionInputs inputs, final MultiCurveCalculationConfig curveConfig, final ConfigDBCurveCalculationConfigSource configSource) {
final YieldCurveBundle curves = new YieldCurveBundle();
if (curveConfig.getExogenousConfigData() != null) {
final LinkedHashMap<String, String[]> exogenousCurves = curveConfig.getExogenousConfigData();
for (final Map.Entry<String, String[]> entry : exogenousCurves.entrySet()) {
final String exogenousConfigName = entry.getKey();
final MultiCurveCalculationConfig exogenousConfig = configSource.getConfig(exogenousConfigName);
final ComputationTargetSpecification target = exogenousConfig.getTarget();
final String exogenousCalculationMethod = exogenousConfig.getCalculationMethod();
for (final String curveName : entry.getValue()) {
final ValueRequirement curveRequirement = YieldCurveFunctionUtils.getCurveRequirement(target, curveName, exogenousConfigName, exogenousCalculationMethod);
final Object curveObject = inputs.getValue(curveRequirement);
if (curveObject == null) {
throw new OpenGammaRuntimeException("Could not get curve called " + curveName);
}
final YieldAndDiscountCurve curve = (YieldAndDiscountCurve) curveObject;
final String fullCurveName = curveName + "_" + target.getUniqueId().getValue();
curves.setCurve(fullCurveName, curve);
}
curves.addAll(getAllYieldCurves(inputs, exogenousConfig, configSource));
}
}
final String[] curveNames = curveConfig.getYieldCurveNames();
final ComputationTargetSpecification target = curveConfig.getTarget();
for (final String curveName : curveNames) {
final ValueRequirement curveRequirement = YieldCurveFunctionUtils.getCurveRequirement(target, curveName, curveConfig.getCalculationConfigName(), curveConfig.getCalculationMethod());
final Object curveObject = inputs.getValue(curveRequirement);
if (curveObject == null) {
throw new OpenGammaRuntimeException("Could not get curve called " + curveName);
}
final YieldAndDiscountCurve curve = (YieldAndDiscountCurve) curveObject;
final String fullCurveName = curveName + "_" + target.getUniqueId().getValue();
curves.setCurve(fullCurveName, curve);
}
return curves;
}
//TODO won't work if curves have different currencies
public static YieldCurveBundle getYieldCurves(final FunctionInputs inputs, final MultiCurveCalculationConfig curveConfig) {
final YieldCurveBundle curves = new YieldCurveBundle();
final String[] curveNames = curveConfig.getYieldCurveNames();
final ComputationTargetSpecification target = curveConfig.getTarget();
for (final String curveName : curveNames) {
final ValueRequirement curveRequirement = YieldCurveFunctionUtils.getCurveRequirement(target, curveName, curveConfig.getCalculationConfigName(), curveConfig.getCalculationMethod());
final Object curveObject = inputs.getValue(curveRequirement);
if (curveObject == null) {
throw new OpenGammaRuntimeException("Could not get curve called " + curveName);
}
final YieldAndDiscountCurve curve = (YieldAndDiscountCurve) curveObject;
final String fullCurveName = curveName + "_" + target.getUniqueId().getValue();
curves.setCurve(fullCurveName, curve);
}
return curves;
}
//TODO won't work if curves have different currencies
public static YieldCurveBundle getFixedCurves(final FunctionInputs inputs, final MultiCurveCalculationConfig curveConfig,
final ConfigDBCurveCalculationConfigSource configSource) {
final YieldCurveBundle curves = new YieldCurveBundle();
if (curveConfig.getExogenousConfigData() != null) {
final LinkedHashMap<String, String[]> exogenousCurves = curveConfig.getExogenousConfigData();
for (final Map.Entry<String, String[]> entry : exogenousCurves.entrySet()) {
final MultiCurveCalculationConfig config = configSource.getConfig(entry.getKey());
curves.addAll(getYieldCurves(inputs, config));
}
return curves;
}
return null;
}
public static Set<String> intersection(final Set<String> as, final String[] bs) {
final Set<String> i = Sets.newHashSetWithExpectedSize(as.size());
for (final String b : bs) {
if (as.contains(b)) {
i.add(b);
}
}
return i;
}
}