com.opengamma.bbg.loader.BloombergSecurityFileLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.bbg.loader.BloombergSecurityFileLoader.java

Source

/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.bbg.loader;

import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_CHAIN;
import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_EXPIRE_DT;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.fudgemsg.FudgeField;
import org.fudgemsg.FudgeMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.threeten.bp.LocalDate;

import com.google.common.collect.Lists;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.bbg.BloombergConstants;
import com.opengamma.bbg.referencedata.ReferenceDataProvider;
import com.opengamma.bbg.util.BloombergDomainIdentifierResolver;
import com.opengamma.bbg.util.ReferenceDataProviderUtils;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.financial.security.DefaultSecurityLoader;
import com.opengamma.id.ExternalId;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.id.ExternalScheme;
import com.opengamma.id.UniqueId;
import com.opengamma.master.security.SecurityMaster;
import com.opengamma.provider.security.SecurityProvider;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.time.DateUtils;
import com.opengamma.util.time.Expiry;

/**
 * Loads security data from Bloomberg and add/update the security data to SecurityMaster
 * <p>
 * Security Identifiers to load is read from a supplied file or from position master, which one to used is specified
 * from command line options
 * <pre>
 *    usage: java com.opengamma.bbg.loader.BloombergSecurityFileLoader [options]... [files]...
 *    -h,--help                                       Print this message
 *    -o,--optionSize [size]                          First x number of options to load
 *    -s,--scheme [BLOOMBERG_TICKER, BLOOMBERG_BUID]  Identification scheme
 * </pre>
 */
public class BloombergSecurityFileLoader {

    /** Logger. */
    private static final Logger s_logger = LoggerFactory.getLogger(BloombergSecurityFileLoader.class);

    /* package */static final String CONTEXT_CONFIGURATION_PATH = "/com/opengamma/bbg/loader/bloomberg-security-loader-context.xml";

    private static final String HELP_OPTION = "help";
    private static final String OPTION = "option";
    private static final String IDENTIFICATION_SCHEME = "scheme";

    private final DefaultSecurityLoader _securityLoader;
    private ReferenceDataProvider _refDataProvider;
    private String[] _files;
    private int _optionSize;
    private ExternalScheme _scheme;

    /**
     * Creates an instance.
     * 
     * @param securityMaster  the security master, not null
     * @param securityProvider  bloomberg security loader, not null
     */
    public BloombergSecurityFileLoader(final SecurityProvider securityProvider,
            final SecurityMaster securityMaster) {
        ArgumentChecker.notNull(securityProvider, "securityProvider");
        ArgumentChecker.notNull(securityMaster, "securityMaster");
        _securityLoader = new DefaultSecurityLoader(securityMaster, securityProvider);
    }

    //-------------------------------------------------------------------------
    /**
     * Gets the refDataProvider field.
     * @return the refDataProvider
     */
    public ReferenceDataProvider getRefDataProvider() {
        return _refDataProvider;
    }

    /**
     * Sets the reference data provider.
     * @param refDataProvider  the reference data provider
     */
    public void setRefDataProvider(ReferenceDataProvider refDataProvider) {
        _refDataProvider = refDataProvider;
    }

    /**
     * Gets the scheme field.
     * @return the scheme
     */
    public ExternalScheme getScheme() {
        return _scheme;
    }

    /**
     * Sets the scheme field.
     * @param scheme  the scheme
     */
    public void setScheme(ExternalScheme scheme) {
        _scheme = scheme;
    }

    //-------------------------------------------------------------------------
    public void run() {

        Set<ExternalIdBundle> identifiers = readInputFiles();

        Map<ExternalIdBundle, UniqueId> loadedSecurities = _securityLoader.loadSecurities(identifiers);
        List<ExternalIdBundle> errors = findErrors(loadedSecurities);
        if (_optionSize > 0) {
            Set<ExternalIdBundle> optionIdentifiers = loadOptionIdentifiers(identifiers);
            Map<ExternalIdBundle, UniqueId> loadedOptionSecurities = _securityLoader
                    .loadSecurities(optionIdentifiers);
            errors.addAll(findErrors(loadedOptionSecurities));
        }

        //print securities with errors
        if (!errors.isEmpty()) {
            s_logger.warn("Unable to load the following securities");
            for (ExternalIdBundle identifierBundle : errors) {
                s_logger.warn("{}", identifierBundle);
            }
        }

        //    for (ExternalIdBundle bundle : findSucesses(loadedSecurities)) {
        //      System.err.println(bundle.getIdentifier(SecurityUtils.ISIN));
        //    }
    }

    private List<ExternalIdBundle> findErrors(final Map<ExternalIdBundle, UniqueId> loadedSecurities) {
        List<ExternalIdBundle> result = Lists.newArrayList();
        for (Entry<ExternalIdBundle, UniqueId> entry : loadedSecurities.entrySet()) {
            if (entry.getValue() == null) {
                result.add(entry.getKey());
            }
        }
        return result;
    }

    private Set<ExternalIdBundle> loadOptionIdentifiers(final Set<ExternalIdBundle> identifiers) {
        Set<String> bloombergKeys = new HashSet<String>();
        for (ExternalIdBundle dsids : identifiers) {
            ExternalId preferredIdentifier = BloombergDomainIdentifierResolver.resolvePreferredIdentifier(dsids);
            bloombergKeys.add(BloombergDomainIdentifierResolver.toBloombergKey(preferredIdentifier));
        }

        Set<ExternalIdBundle> optionsIdentifiers = new HashSet<ExternalIdBundle>();
        Map<String, FudgeMsg> refDataResultMap = _refDataProvider.getReferenceDataIgnoreCache(bloombergKeys,
                Collections.singleton(FIELD_OPT_CHAIN));
        for (Entry<String, FudgeMsg> entry : refDataResultMap.entrySet()) {
            FudgeMsg fieldContainer = entry.getValue();
            //process the options
            int nAdded = 0;
            for (FudgeField field : fieldContainer.getAllByName(BloombergConstants.FIELD_OPT_CHAIN)) {
                FudgeMsg optionContainer = (FudgeMsg) field.getValue();
                String optionTickerStr = optionContainer.getString("Security Description");
                String expiryStr = ReferenceDataProviderUtils.singleFieldSearchIgnoreCache(optionTickerStr,
                        FIELD_OPT_EXPIRE_DT, _refDataProvider);
                LocalDate expiryLocalDate = null;
                try {
                    expiryLocalDate = LocalDate.parse(expiryStr);
                } catch (Exception e) {
                    throw new OpenGammaRuntimeException(
                            expiryStr + " returned from bloomberg not in format yyyy-mm-dd", e);
                }
                int year = expiryLocalDate.getYear();
                int month = expiryLocalDate.getMonthValue();
                int day = expiryLocalDate.getDayOfMonth();
                Expiry expiry = new Expiry(DateUtils.getUTCDate(year, month, day));

                if (expiry.getExpiry().toInstant()
                        .toEpochMilli() < (System.currentTimeMillis() + (25L * 60L * 60L * 1000L))) {
                    s_logger.info("Option {} in future, so passing on it.", optionTickerStr);
                    continue;
                }

                ExternalId optionTicker = ExternalSchemes.bloombergTickerSecurityId(optionTickerStr);
                optionsIdentifiers.add(ExternalIdBundle.of(optionTicker));

                nAdded++;
                if (nAdded >= _optionSize) {
                    break;
                }
            }
        }
        return optionsIdentifiers;
    }

    /**
     * Sets the files field.
     * @param files  the files
     */
    public void setFiles(String[] files) {
        _files = files;
    }

    /**
     * Sets the optionSize field.
     * @param optionSize  the optionSize
     */
    public void setOptionSize(int optionSize) {
        _optionSize = optionSize;
    }

    /**
     * @param args
     */
    public static void main(String[] args) { // CSIGNORE
        Options options = createOptions();
        processCommandLineOptions(args, options);
    }

    /**
     * @param args
     * @param options
     */
    private static void processCommandLineOptions(String[] args, Options options) {
        CommandLineParser parser = new PosixParser();
        CommandLine line = null;
        try {
            line = parser.parse(options, args);
        } catch (ParseException e) {
            usage(options);
            return;
        }
        if (line.hasOption(HELP_OPTION)) {
            usage(options);
            return;
        }

        String[] files = line.getArgs();
        BloombergSecurityFileLoader securityLoader = getBloombergSecurityFileLoader();
        securityLoader.setFiles(files);

        if (line.hasOption(OPTION)) {
            try {
                securityLoader.setOptionSize(Integer.parseInt(line.getOptionValue(OPTION)));
            } catch (NumberFormatException ex) {
                s_logger.warn("{} option size is not an integer", line.getOptionValue(OPTION));
            }
        }

        if (line.hasOption(IDENTIFICATION_SCHEME)) {
            String schemeValue = line.getOptionValue(IDENTIFICATION_SCHEME);
            securityLoader.setScheme(ExternalScheme.of(schemeValue));
        } else {
            securityLoader.setScheme(ExternalSchemes.BLOOMBERG_TICKER);
        }
        securityLoader.run();
    }

    private static Options createOptions() {
        Options options = new Options();
        options.addOption(createHelpOption());
        options.addOption(createOptionSize());
        options.addOption(createSchemeOption());
        return options;
    }

    private static Option createSchemeOption() {
        OptionBuilder.withLongOpt(IDENTIFICATION_SCHEME);
        OptionBuilder.withDescription("Identification scheme");
        OptionBuilder.hasArg();
        OptionBuilder.withArgName("BLOOMBERG_TICKER, BLOOMBERG_BUID");
        return OptionBuilder.create("s");
    }

    private static Option createHelpOption() {
        return new Option("h", HELP_OPTION, false, "Print this message");
    }

    private static Option createOptionSize() {
        OptionBuilder.withLongOpt(OPTION);
        OptionBuilder.withDescription("First x number of options to load");
        OptionBuilder.hasArg();
        OptionBuilder.withArgName("size");
        return OptionBuilder.create("o");
    }

    private static void usage(Options options) {
        HelpFormatter formatter = new HelpFormatter();
        formatter.setWidth(120);
        formatter.printHelp("java " + BloombergSecurityFileLoader.class.getName() + " [options]... [files]...",
                options);
    }

    @SuppressWarnings("unchecked")
    private Set<ExternalIdBundle> readInputFiles() {
        Set<String> securities = new HashSet<String>();
        if (_files != null) {
            for (String file : _files) {
                try {
                    securities.addAll(FileUtils.readLines(new File(file)));
                } catch (IOException e) {
                    s_logger.warn("Problem reading from input file={}", file);
                    throw new OpenGammaRuntimeException("Problem reading from " + file, e);
                }
            }
        }
        Set<ExternalIdBundle> result = new HashSet<ExternalIdBundle>();
        for (String secDes : securities) {
            if (!StringUtils.isBlank(secDes)) {
                result.add(ExternalIdBundle.of(ExternalId.of(getScheme(), secDes.trim())));
            }
        }
        return result;
    }

    private static BloombergSecurityFileLoader getBloombergSecurityFileLoader() {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(CONTEXT_CONFIGURATION_PATH);
        context.start();
        BloombergSecurityFileLoader loader = (BloombergSecurityFileLoader) context.getBean("securityLoader");
        return loader;
    }

}