com.opengamma.integration.tool.marketdata.CurveHtsResolverTool.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.integration.tool.marketdata.CurveHtsResolverTool.java

Source

/**
 * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.integration.tool.marketdata;

import static com.google.common.collect.Sets.newHashSet;
import static com.opengamma.lambdava.streams.Lambdava.functional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.Clock;
import org.threeten.bp.LocalDate;

import com.opengamma.bbg.BloombergIdentifierProvider;
import com.opengamma.bbg.loader.hts.BloombergHistoricalTimeSeriesLoader;
import com.opengamma.component.tool.AbstractTool;
import com.opengamma.core.config.ConfigSource;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.financial.analytics.ircurve.ConfigDBInterpolatedYieldCurveSpecificationBuilder;
import com.opengamma.financial.analytics.ircurve.FixedIncomeStripWithIdentifier;
import com.opengamma.financial.analytics.ircurve.InterpolatedYieldCurveSpecification;
import com.opengamma.financial.analytics.ircurve.InterpolatedYieldCurveSpecificationBuilder;
import com.opengamma.financial.analytics.ircurve.YieldCurveDefinition;
import com.opengamma.financial.convention.ConventionBundle;
import com.opengamma.financial.convention.ConventionBundleMaster;
import com.opengamma.financial.convention.DefaultConventionBundleSource;
import com.opengamma.financial.convention.InMemoryConventionBundleMaster;
import com.opengamma.id.ExternalId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.integration.tool.IntegrationToolContext;
import com.opengamma.lambdava.functions.Function1;
import com.opengamma.master.config.ConfigDocument;
import com.opengamma.master.config.ConfigMaster;
import com.opengamma.master.config.ConfigSearchRequest;
import com.opengamma.master.config.impl.ConfigSearchIterator;
import com.opengamma.scripts.Scriptable;
import com.opengamma.util.money.Currency;

/**
 */
@Scriptable
public class CurveHtsResolverTool extends AbstractTool<IntegrationToolContext> {
    /**
     * Logger.
     */
    private static Logger s_logger = LoggerFactory.getLogger(CurveHtsResolverTool.class);

    /** Portfolio name option flag*/
    private static final String CURVE_NAME_OPT = "n";
    /** Write option flag */
    private static final String WRITE_OPT = "w";
    /** Verbose option flag */
    private static final String VERBOSE_OPT = "v";
    /** Time series data provider option flag*/
    private static final String TIME_SERIES_DATAPROVIDER_OPT = "p";
    /** Time series data field option flag*/
    private static final String TIME_SERIES_DATAFIELD_OPT = "d";

    //-------------------------------------------------------------------------

    /**
     * Main method to run the tool.
     * No arguments are needed.
     *
     * @param args  the arguments, unused
     */
    public static void main(final String[] args) { // CSIGNORE
        new CurveHtsResolverTool().initAndRun(args, IntegrationToolContext.class);
        System.exit(0);
    }

    //-------------------------------------------------------------------------
    @SuppressWarnings("unchecked")
    @Override
    protected void doRun() {

        Set<ExternalId> curveNodesExternalIds;

        Set<ExternalId> initialRateExternalIds;

        final ConfigSource configSource = getToolContext().getConfigSource();
        final ConfigMaster configMaster = getToolContext().getConfigMaster();

        // Find all matching curves
        final List<YieldCurveDefinition> curves = getCurveDefinitionNames(configMaster,
                getCommandLine().getOptionValue(CURVE_NAME_OPT));

        // Get initial rate hts external ids for curves
        final Set<Currency> currencies = newHashSet();
        for (final YieldCurveDefinition curve : curves) {
            currencies.add(curve.getCurrency());
        }
        initialRateExternalIds = getInitialRateExternalIds(currencies);

        // Get all other required hts external ids for curves
        final List<LocalDate> dates = buildDates();
        final Set<String> curveNames = functional(curves).map(new Function1<YieldCurveDefinition, String>() {
            @Override
            public String execute(final YieldCurveDefinition yieldCurveDefinition) {
                return yieldCurveDefinition.getName() + "_" + yieldCurveDefinition.getCurrency().getCode();
            }
        }).asSet();
        curveNodesExternalIds = getCurveRequiredExternalIds(configSource, curveNames, dates);

        // Load the required time series
        loadHistoricalData(getCommandLine().hasOption(WRITE_OPT),
                getCommandLine().getOptionValues(TIME_SERIES_DATAFIELD_OPT) == null ? new String[] { "PX_LAST" }
                        : getCommandLine().getOptionValues(TIME_SERIES_DATAFIELD_OPT),
                getCommandLine().getOptionValue(TIME_SERIES_DATAPROVIDER_OPT) == null ? "CMPL"
                        : getCommandLine().getOptionValue(TIME_SERIES_DATAPROVIDER_OPT),
                initialRateExternalIds, curveNodesExternalIds);
    }

    private Set<ExternalId> getInitialRateExternalIds(final Set<Currency> currencies) {
        final ConventionBundleMaster cbm = new InMemoryConventionBundleMaster();
        final DefaultConventionBundleSource cbs = new DefaultConventionBundleSource(cbm);
        final Set<ExternalId> externalInitialRateId = newHashSet();
        for (final Currency currency : currencies) {
            for (final String swapType : new String[] { "SWAP", "3M_SWAP", "6M_SWAP" }) {
                final String product = currency.getCode() + "_" + swapType;
                final ConventionBundle convention = cbs.getConventionBundle(
                        ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, product));
                if (convention != null) {
                    final ExternalId initialRate = convention.getSwapFloatingLegInitialRate();
                    final ConventionBundle realIdConvention = cbs.getConventionBundle(initialRate);
                    if (realIdConvention != null) {
                        externalInitialRateId.add(
                                realIdConvention.getIdentifiers().getExternalId(ExternalSchemes.BLOOMBERG_TICKER));
                    } else {
                        s_logger.error("No convention for {}", initialRate.toString());
                    }
                } else {
                    s_logger.warn("No convention for {} product", product);
                }
            }
        }
        return externalInitialRateId;
    }

    /**
     * Generate quarterly dates +/- 2 years around today to cover futures from past and near future
     * @return list of dates
     */
    private List<LocalDate> buildDates() {
        final Clock clock = Clock.systemDefaultZone();
        final List<LocalDate> dates = new ArrayList<LocalDate>();
        final LocalDate twoYearsAgo = LocalDate.now(clock).minusYears(2);
        final LocalDate twoYearsTime = LocalDate.now(clock).plusYears(2);
        for (LocalDate next = twoYearsAgo; next.isBefore(twoYearsTime); next = next.plusMonths(3)) {
            dates.add(next);
        }
        return dates;
    }

    /**
     * Get all the curve definition config object names specified by glob expression.
     * @param configMaster
     * @param nameExpr glob type expression - e.g. blah*
     * @return list of names of config objects matching glob expression
     */
    private List<YieldCurveDefinition> getCurveDefinitionNames(final ConfigMaster configMaster,
            final String nameExpr) {
        final List<YieldCurveDefinition> results = new ArrayList<YieldCurveDefinition>();
        final ConfigSearchRequest<YieldCurveDefinition> request = new ConfigSearchRequest<YieldCurveDefinition>(
                YieldCurveDefinition.class);
        request.setName(nameExpr);
        for (final ConfigDocument doc : ConfigSearchIterator.iterable(configMaster, request)) {
            results.add((YieldCurveDefinition) doc.getConfig().getValue());
        }
        return results;
    }

    /**
     * For a given list of curve names, on a given list of dates, get the superset of all ids required by those curves.
     * @param configSource
     * @param names
     * @param dates
     * @return list of all ids required by curves
     */
    private Set<ExternalId> getCurveRequiredExternalIds(final ConfigSource configSource,
            final Collection<String> names, final List<LocalDate> dates) {
        final Set<ExternalId> externalIds = newHashSet();
        for (final String name : names) {
            s_logger.info("Processing curve " + name);
            YieldCurveDefinition curveDefinition = configSource.getSingle(YieldCurveDefinition.class, name,
                    VersionCorrection.LATEST);
            if (curveDefinition != null) {
                InterpolatedYieldCurveSpecificationBuilder builder = new ConfigDBInterpolatedYieldCurveSpecificationBuilder(
                        configSource);
                for (LocalDate date : dates) {
                    s_logger.info("Processing curve date " + date);
                    try {
                        final InterpolatedYieldCurveSpecification curveSpec = builder.buildCurve(date,
                                curveDefinition);
                        for (final FixedIncomeStripWithIdentifier strip : curveSpec.getStrips()) {
                            s_logger.info("Processing strip " + strip.getSecurity());
                            externalIds.add(strip.getSecurity());
                        }
                    } catch (final Throwable t) {
                        s_logger.warn("Unable to build curve " + t.getMessage());
                    }
                }
            } else {
                s_logger.warn("No curve definition with '{}' name", name);
            }
        }
        return externalIds;
    }

    private void loadHistoricalData(final boolean write, final String[] dataFields, final String dataProvider,
            final Set<ExternalId>... externalIdSets) {
        final BloombergHistoricalTimeSeriesLoader loader = new BloombergHistoricalTimeSeriesLoader(
                getToolContext().getHistoricalTimeSeriesMaster(),
                getToolContext().getHistoricalTimeSeriesProvider(),
                new BloombergIdentifierProvider(getToolContext().getBloombergReferenceDataProvider()));

        for (final Set<ExternalId> externalIds : externalIdSets) {
            if (externalIds.size() > 0) {
                for (final String dataField : dataFields) {
                    s_logger.info("Loading time series (field: " + dataField + ", provider: " + dataProvider
                            + ") with external IDs " + externalIds);
                    if (write) {
                        loader.loadTimeSeries(externalIds, dataProvider, dataField, LocalDate.now().minusYears(1),
                                null);
                    }
                }
            }
        }
    }

    @Override
    protected Options createOptions(final boolean contextProvided) {

        final Options options = super.createOptions(contextProvided);

        final Option curveNameOption = new Option(CURVE_NAME_OPT, "name", true,
                "The name of the yield curve definition for which to resolve time series");
        curveNameOption.setRequired(true);
        options.addOption(curveNameOption);

        final Option writeOption = new Option(WRITE_OPT, "write", false,
                "Actually persists the time series to the database if specified, otherwise pretty-prints without persisting");
        options.addOption(writeOption);

        final Option verboseOption = new Option(VERBOSE_OPT, "verbose", false,
                "Displays progress messages on the terminal");
        options.addOption(verboseOption);

        final Option timeSeriesDataProviderOption = new Option(TIME_SERIES_DATAPROVIDER_OPT, "provider", true,
                "The name of the time series data provider");
        options.addOption(timeSeriesDataProviderOption);

        final Option timeSeriesDataFieldOption = new Option(TIME_SERIES_DATAFIELD_OPT, "field", true,
                "The name(s) of the time series data field(s)");
        options.addOption(timeSeriesDataFieldOption);

        return options;
    }

}