/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableMap; import com.opengamma.financial.analytics.curve.CurveConstructionConfiguration; import com.opengamma.sesame.marketdata.MulticurveMarketDataBuilder; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.result.Result; /** * Function implementation that for a particular curve config, determines which * curves need to go into a multicurve bundle and coordinates the building * of them. This ensures that a particular curve only needs to get built once. * Once the required curves have been built the function delegates to a * DiscountingMulticurveBundleFn to calculate the required result. * * @deprecated curves are built using {@link MulticurveMarketDataBuilder}. */ public class DefaultDiscountingMulticurveBundleResolverFn implements DiscountingMulticurveBundleResolverFn { private static final Logger s_logger = LoggerFactory.getLogger(DefaultDiscountingMulticurveBundleResolverFn.class); /** * Generates a discounting multicurve bundle. */ private final DiscountingMulticurveBundleFn _multicurveBundleProviderFunction; public DefaultDiscountingMulticurveBundleResolverFn(DiscountingMulticurveBundleFn multicurveBundleProviderFunction) { _multicurveBundleProviderFunction = ArgumentChecker.notNull(multicurveBundleProviderFunction, "multicurveBundleProviderFunction"); } @Override public Result<MulticurveBundle> generateBundle(Environment env, CurveConstructionConfiguration curveConfig) { s_logger.debug("Generating bundle '{}', valuationTime {}", curveConfig.getName(), env.getValuationTime()); Map<CurveConstructionConfiguration, Result<MulticurveBundle>> requiredCurves = buildRequiredCurves(env, curveConfig); return _multicurveBundleProviderFunction.generateBundle(env, curveConfig, requiredCurves); } @Override public Result<ImpliedDepositCurveData> extractImpliedDepositCurveData( Environment env, CurveConstructionConfiguration curveConfig) { Map<CurveConstructionConfiguration, Result<MulticurveBundle>> builtCurves = buildRequiredCurves(env, curveConfig); return _multicurveBundleProviderFunction.extractImpliedDepositCurveData(env, curveConfig, builtCurves); } // Builds all curves required as exogenous config for the supplied curve config. // As each curve is built, it is added to a collection and the collection // is passed in as each subsequent curve is built so the data can be // used in constructing the multicurve. // Note that this does not build the supplied curve config itself - callers need // to do that if desired. private Map<CurveConstructionConfiguration, Result<MulticurveBundle>> buildRequiredCurves( Environment env, CurveConstructionConfiguration curveConfig) { // Get the order to build any exogenous curves in LinkedHashSet<CurveConstructionConfiguration> orderedCurves = determineCurveConfigOrdering(curveConfig.resolveCurveConfigurations()); Map<CurveConstructionConfiguration, Result<MulticurveBundle>> builtCurves = new HashMap<>(); for (CurveConstructionConfiguration config : orderedCurves) { builtCurves.put(config, _multicurveBundleProviderFunction.generateBundle(env, config, ImmutableMap.copyOf(builtCurves))); } return builtCurves; } private LinkedHashSet<CurveConstructionConfiguration> determineCurveConfigOrdering( List<CurveConstructionConfiguration> curveConfigs) { return determineCurveConfigOrdering(new LinkedHashSet<CurveConstructionConfiguration>(), curveConfigs); } // Recursively determines the ordered set of curves that need to be built (due to // exogenous curves) before the requested set of curve configs can be built. Uses // a LinkedHashSet so we get ordering but no duplication of elements private LinkedHashSet<CurveConstructionConfiguration> determineCurveConfigOrdering( LinkedHashSet<CurveConstructionConfiguration> existing, List<CurveConstructionConfiguration> curveConfigs) { LinkedHashSet<CurveConstructionConfiguration> toBuild = new LinkedHashSet<>(existing); for (CurveConstructionConfiguration curveConfig : curveConfigs) { List<CurveConstructionConfiguration> exogenousConfigs = curveConfig.resolveCurveConfigurations(); if (!exogenousConfigs.isEmpty()) { toBuild.addAll(determineCurveConfigOrdering(toBuild, exogenousConfigs)); } toBuild.add(curveConfig); } return toBuild; } }