com.opengamma.financial.generator.AbstractPortfolioGeneratorTool.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.financial.generator.AbstractPortfolioGeneratorTool.java

Source

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

import java.security.SecureRandom;
import java.util.Random;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.position.Portfolio;
import com.opengamma.core.position.PortfolioNode;
import com.opengamma.core.position.Position;
import com.opengamma.core.position.Trade;
import com.opengamma.core.security.Security;
import com.opengamma.core.security.SecuritySource;
import com.opengamma.financial.tool.ToolContext;
import com.opengamma.master.portfolio.ManageablePortfolio;
import com.opengamma.master.portfolio.ManageablePortfolioNode;
import com.opengamma.master.portfolio.PortfolioDocument;
import com.opengamma.master.portfolio.PortfolioSearchRequest;
import com.opengamma.master.portfolio.PortfolioSearchResult;
import com.opengamma.master.position.ManageablePosition;
import com.opengamma.master.position.ManageableTrade;
import com.opengamma.master.position.PositionDocument;
import com.opengamma.master.position.PositionMaster;
import com.opengamma.master.security.ManageableSecurityLink;
import com.opengamma.util.money.Currency;

/**
 * Utility for generating a portfolio of securities.
 */
public abstract class AbstractPortfolioGeneratorTool {

    private static final Logger s_logger = LoggerFactory.getLogger(AbstractPortfolioGeneratorTool.class);
    /**
     * Default counter party name
     */
    public static final String DEFAULT_COUNTER_PARTY = "COUNTERPARTY";

    /**
     * Default portfolio size used by sub-classes.
     */
    protected static final int PORTFOLIO_SIZE = 200;

    private Random _random;
    private SecurityPersister _securityPersister;
    private ToolContext _toolContext;
    private Class<? extends AbstractPortfolioGeneratorTool> _classContext;
    private AbstractPortfolioGeneratorTool _objectContext;
    private NameGenerator _counterPartyGenerator;
    private Currency[] _currencies;

    public AbstractPortfolioGeneratorTool() {
        _classContext = getClass();
    }

    public PortfolioGenerator createPortfolioGenerator(final NameGenerator portfolioNameGenerator) {
        return new PortfolioGenerator(createPortfolioNodeGenerator(PORTFOLIO_SIZE), portfolioNameGenerator);
    }

    public Portfolio createPortfolio(final String portfolioName) {
        return createPortfolioGenerator(new StaticNameGenerator(portfolioName)).createPortfolio();
    }

    public PortfolioNodeGenerator createPortfolioNodeGenerator(final int portfolioSize) {
        throw new UnsupportedOperationException();
    }

    public PortfolioNode createPortfolioNode(final int size) {
        return createPortfolioNodeGenerator(size).createPortfolioNode();
    }

    public PortfolioNode createPortfolioNode() {
        return createPortfolioNode(PORTFOLIO_SIZE);
    }

    public Random getRandom() {
        return _random;
    }

    public void setRandom(final Random random) {
        _random = random;
    }

    public Currency[] getCurrencies() {
        return _currencies;
    }

    public void setCurrencies(final Currency[] currencies) {
        _currencies = currencies;
    }

    private void setContext(final Class<? extends AbstractPortfolioGeneratorTool> classContext,
            final AbstractPortfolioGeneratorTool objectContext) {
        _classContext = classContext;
        _objectContext = objectContext;
    }

    private Class<? extends AbstractPortfolioGeneratorTool> getClassContext() {
        return _classContext;
    }

    private AbstractPortfolioGeneratorTool getObjectContext() {
        return _objectContext;
    }

    public SecurityPersister getSecurityPersister() {
        return _securityPersister;
    }

    public void setSecurityPersister(final SecurityPersister securityPersister) {
        _securityPersister = securityPersister;
    }

    public NameGenerator getCounterPartyGenerator() {
        return _counterPartyGenerator;
    }

    public void setCounterPartyGenerator(final NameGenerator counterPartyGenerator) {
        _counterPartyGenerator = counterPartyGenerator;
    }

    public ToolContext getToolContext() {
        return _toolContext;
    }

    public void setToolContext(final ToolContext toolContext) {
        _toolContext = toolContext;
    }

    protected final void configure(final SecurityGenerator<?> securityGenerator) {
        if (getRandom() != null) {
            securityGenerator.setRandom(getRandom());
        }
        if (getCurrencies() != null && getCurrencies().length > 0) {
            securityGenerator.setCurrencies(getCurrencies());
        }
        if (getToolContext() != null) {
            securityGenerator.setConfigSource(getToolContext().getConfigSource());
            securityGenerator.setConventionSource(getToolContext().getConventionSource());
            securityGenerator.setConventionBundleSource(getToolContext().getConventionBundleSource());
            securityGenerator.setHolidaySource(getToolContext().getHolidaySource());
            securityGenerator.setHistoricalSource(getToolContext().getHistoricalTimeSeriesSource());
            securityGenerator.setExchangeMaster(getToolContext().getExchangeMaster());
            securityGenerator.setRegionSource(getToolContext().getRegionSource());
            securityGenerator.setOrganizationSource(getToolContext().getOrganizationSource());
            securityGenerator.setSecurityMaster(getToolContext().getSecurityMaster());
            securityGenerator.setHistoricalTimeSeriesMaster(getToolContext().getHistoricalTimeSeriesMaster());
        }
        configureChain(securityGenerator);
    }

    protected void configureChain(final SecurityGenerator<?> securityGenerator) {
        if (getObjectContext() != null) {
            getObjectContext().configureChain(securityGenerator);
        }
    }

    protected void configure(final AbstractPortfolioGeneratorTool tool) {
        if (getRandom() != null) {
            tool.setRandom(getRandom());
        }
        if (getToolContext() != null) {
            tool.setToolContext(getToolContext());
        }
        if (getSecurityPersister() != null) {
            tool.setSecurityPersister(getSecurityPersister());
        }
        if (getCounterPartyGenerator() != null) {
            tool.setCounterPartyGenerator(getCounterPartyGenerator());
        }
    }

    /**
     * Command line option for specifying the portfolio name to generate.
     */
    public static final String PORTFOLIO_OPT = "portfolio";
    /**
     * Command line option to specifying the asset class to generate the portfolio for.
     */
    public static final String SECURITY_OPT = "security";
    /**
     * Command line option to specify to write to the database masters.
     */
    public static final String WRITE_OPT = "write";
    /**
     * Command line option to specifying the name of the counter party to use for trades.
     */
    public static final String COUNTER_PARTY_OPT = "counterPty";
    private static final String CURRENCIES_OPT = "currencies";

    private AbstractPortfolioGeneratorTool getInstance(final Class<?> clazz, final String security) {
        if (!AbstractPortfolioGeneratorTool.class.isAssignableFrom(clazz)) {
            throw new OpenGammaRuntimeException("Couldn't find generator tool class for " + security);
        }
        try {
            final String className;
            final int i = security.indexOf('.');
            if (i < 0) {
                className = clazz.getPackage().getName() + "." + security + "PortfolioGeneratorTool";
            } else {
                className = security;
            }
            final Class<?> instanceClass;
            try {
                s_logger.debug("Trying class {}", className);
                instanceClass = Class.forName(className);
            } catch (final ClassNotFoundException e) {
                return getInstance(clazz.getSuperclass(), security);
            }
            s_logger.info("Loading {}", className);
            final AbstractPortfolioGeneratorTool tool = (AbstractPortfolioGeneratorTool) instanceClass
                    .newInstance();
            tool.setContext(getClassContext(), this);
            return tool;
        } catch (final Exception e) {
            throw new OpenGammaRuntimeException("Couldn't create generator tool instance for " + security, e);
        }
    }

    protected AbstractPortfolioGeneratorTool getInstance(final String security) {
        return getInstance(getClassContext(), security);
    }

    public void run(final ToolContext context, final String portfolioName, final String security,
            final boolean write, final Currency[] currencies) {
        final AbstractPortfolioGeneratorTool instance = getInstance(security);
        instance.setToolContext(context);
        instance.setCounterPartyGenerator(getCounterPartyGenerator());
        instance.setRandom(new SecureRandom());
        final SecuritySource securitySource;
        if (write) {
            s_logger.info("Creating database security writer");
            securitySource = context.getSecuritySource();
            instance.setSecurityPersister(new MasterSecurityPersister(context.getSecurityMaster()));
        } else {
            s_logger.info("Using dummy security writer");
            final InMemorySecurityPersister securityPersister = new InMemorySecurityPersister();
            instance.setSecurityPersister(securityPersister);
            securitySource = securityPersister.getSecuritySource();
        }
        if (currencies != null && currencies.length > 0) {
            instance.setCurrencies(currencies);
        }
        s_logger.info("Creating portfolio {}", portfolioName);
        final Portfolio portfolio = instance.createPortfolio(portfolioName);
        if (write) {
            s_logger.info("Writing portfolio to the database");
            final ManageablePortfolio newPortfolio = new ManageablePortfolio(portfolio.getName());
            newPortfolio.setAttributes(portfolio.getAttributes());
            newPortfolio.setRootNode(createPortfolioNode(context.getPositionMaster(), portfolio.getRootNode()));
            final PortfolioSearchRequest request = new PortfolioSearchRequest();
            request.setDepth(0);
            request.setIncludePositions(false);
            request.setName(portfolio.getName());
            final PortfolioSearchResult result = context.getPortfolioMaster().search(request);
            PortfolioDocument document = result.getFirstDocument();
            if (document != null) {
                s_logger.info("Overwriting portfolio {}", document.getUniqueId());
                document.setPortfolio(newPortfolio);
                context.getPortfolioMaster().update(document);
            } else {
                document = new PortfolioDocument(newPortfolio);
                context.getPortfolioMaster().add(document);
            }
        } else {
            if (s_logger.isDebugEnabled()) {
                s_logger.debug("Portfolio {}", portfolioName);
                writePortfolio(securitySource, portfolio.getRootNode(), "");
            }
        }
    }

    private ManageablePortfolioNode createPortfolioNode(final PositionMaster positionMaster,
            final PortfolioNode node) {
        final ManageablePortfolioNode newNode = new ManageablePortfolioNode(node.getName());
        for (final PortfolioNode child : node.getChildNodes()) {
            newNode.addChildNode(createPortfolioNode(positionMaster, child));
        }
        for (final Position position : node.getPositions()) {
            final ManageablePosition newPosition = new ManageablePosition();
            newPosition.setAttributes(position.getAttributes());
            newPosition.setQuantity(position.getQuantity());
            newPosition.setSecurityLink(new ManageableSecurityLink(position.getSecurityLink()));
            for (final Trade trade : position.getTrades()) {
                newPosition.addTrade(new ManageableTrade(trade));
            }
            newNode.addPosition(positionMaster.add(new PositionDocument(newPosition)).getUniqueId());
        }
        return newNode;
    }

    private void writePortfolio(final SecuritySource securitySource, final PortfolioNode node,
            final String indent) {
        s_logger.debug("{}+{}", indent, node.getName());
        for (final PortfolioNode childNode : node.getChildNodes()) {
            writePortfolio(securitySource, childNode, indent + "  ");
        }
        for (final Position position : node.getPositions()) {
            final Security security = position.getSecurityLink().resolve(securitySource);
            s_logger.debug("{} {} x {}", new Object[] { indent, position.getQuantity(), security });
        }
    }

    private Option required(final Option option) {
        option.setRequired(true);
        return option;
    }

    @SuppressWarnings("static-access")
    public void createOptions(final Options options) {
        options.addOption(
                required(new Option("p", PORTFOLIO_OPT, true, "sets the name of the portfolio to create")));
        options.addOption(required(
                new Option("s", SECURITY_OPT, true, "selects the asset class to populate the portfolio with")));
        options.addOption(new Option("w", WRITE_OPT, false, "writes the portfolio and securities to the masters"));
        options.addOption(new Option("cp", COUNTER_PARTY_OPT, true, "sets the name of the counter party"));
        options.addOption(OptionBuilder.hasArgs().withArgName("Currency")
                .withDescription("Specify the currencies of the securities to be generated")
                .withLongOpt(CURRENCIES_OPT).create("ccy"));
    }

    private Currency[] parseCurrencies(final CommandLine commandLine) {
        if (commandLine.hasOption(CURRENCIES_OPT)) {
            final String[] currencies = commandLine.getOptionValues(CURRENCIES_OPT);
            final Currency[] ccys = new Currency[currencies.length];
            int i = 0;
            for (final String ccyStr : currencies) {
                ccys[i++] = Currency.of(ccyStr.trim());
            }
            return ccys;
        } else {
            return null;
        }
    }

    public void run(final ToolContext context, final CommandLine commandLine) {
        setCounterPartyGenerator(
                new StaticNameGenerator(commandLine.getOptionValue(COUNTER_PARTY_OPT, DEFAULT_COUNTER_PARTY)));
        run(context, commandLine.getOptionValue(PORTFOLIO_OPT), commandLine.getOptionValue(SECURITY_OPT),
                commandLine.hasOption(WRITE_OPT), parseCurrencies(commandLine));
    }

}