Java tutorial
/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.examples.bloomberg.loader; import static com.opengamma.lambdava.streams.Lambdava.functional; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.RandomUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.bp.LocalDate; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.component.tool.AbstractTool; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.financial.security.DefaultSecurityLoader; import com.opengamma.financial.security.equity.EquitySecurity; import com.opengamma.financial.security.equity.GICSCode; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.id.UniqueId; import com.opengamma.integration.tool.IntegrationToolContext; import com.opengamma.lambdava.functions.Function1; import com.opengamma.master.portfolio.ManageablePortfolio; import com.opengamma.master.portfolio.ManageablePortfolioNode; import com.opengamma.master.portfolio.PortfolioDocument; import com.opengamma.master.position.ManageablePosition; import com.opengamma.master.position.ManageableTrade; import com.opengamma.master.position.PositionDocument; import com.opengamma.master.security.SecurityDocument; import com.opengamma.master.security.SecurityMaster; import com.opengamma.provider.security.SecurityProvider; import com.opengamma.scripts.Scriptable; /** * Example code to load a very simple equity portfolio. * <p> * This code is kept deliberately as simple as possible. * There are no checks for the securities or portfolios already existing, so if you run it * more than once you will get multiple copies portfolios and securities with the same names. * It is designed to run against the HSQLDB example database. */ @Scriptable public class ExampleEquityPortfolioLoader extends AbstractTool<IntegrationToolContext> { /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(ExampleEquityPortfolioLoader.class); private static final Map<String, String> SECTORS = new HashMap<>(); private static final String EXAMPLE_EQUITY_FILE = "example-equity.csv"; static { SECTORS.put("10", "10 Energy"); SECTORS.put("15", "15 Materials"); SECTORS.put("20", "20 Industrials"); SECTORS.put("25", "25 Consumer discretionary"); SECTORS.put("30", "30 Consumer staples"); SECTORS.put("35", "35 Health care"); SECTORS.put("40", "40 Financials"); SECTORS.put("45", "45 Information technology"); SECTORS.put("50", "50 Telecommunication"); SECTORS.put("55", "55 Utilities"); } /** * The name of the portfolio. */ public static final String PORTFOLIO_NAME = "Equity Portfolio"; //------------------------------------------------------------------------- /** * Main method to run the tool. * No arguments are needed. * * @param args the arguments, unused */ public static void main(final String[] args) { // CSIGNORE new ExampleEquityPortfolioLoader().initAndRun(args, IntegrationToolContext.class); System.exit(0); } protected void createPortfolio(final Collection<ExternalId> tickers) { // create shell portfolio final ManageablePortfolio portfolio = createEmptyPortfolio(); final ManageablePortfolioNode rootNode = portfolio.getRootNode(); final Collection<UniqueId> loadSecurities = loadSecurities(tickers); final SecurityMaster secMaster = getToolContext().getSecurityMaster(); for (final UniqueId uniqueId : loadSecurities) { final SecurityDocument securityDocument = secMaster.get(uniqueId); final EquitySecurity security = (EquitySecurity) securityDocument.getSecurity(); final GICSCode gics = security.getGicsCode(); if (gics == null || gics.isPartial()) { continue; } final String sector = SECTORS.get(gics.getSectorCode()); final String industryGroup = gics.getIndustryGroupCode(); final String industry = gics.getIndustryCode(); final String subIndustry = gics.getSubIndustryCode(); // create portfolio structure ManageablePortfolioNode sectorNode = rootNode.findNodeByName(sector); if (sectorNode == null) { s_logger.debug("Creating node for sector {}", sector); sectorNode = new ManageablePortfolioNode(sector); rootNode.addChildNode(sectorNode); } ManageablePortfolioNode groupNode = sectorNode.findNodeByName("Group " + industryGroup); if (groupNode == null) { s_logger.debug("Creating node for industry group {}", industryGroup); groupNode = new ManageablePortfolioNode("Group " + industryGroup); sectorNode.addChildNode(groupNode); } ManageablePortfolioNode industryNode = groupNode.findNodeByName("Industry " + industry); if (industryNode == null) { s_logger.debug("Creating node for industry {}", industry); industryNode = new ManageablePortfolioNode("Industry " + industry); groupNode.addChildNode(industryNode); } ManageablePortfolioNode subIndustryNode = industryNode.findNodeByName("Sub industry " + subIndustry); if (subIndustryNode == null) { s_logger.debug("Creating node for sub industry {}", subIndustry); subIndustryNode = new ManageablePortfolioNode("Sub industry " + subIndustry); industryNode.addChildNode(subIndustryNode); } // create the position and add it to the master final ManageablePosition position = createPositionAndTrade(security); final PositionDocument addedPosition = addPosition(position); // add the position reference (the unique identifier) to portfolio subIndustryNode.addPosition(addedPosition.getUniqueId()); } // adds the complete tree structure to the master addPortfolio(portfolio); } //------------------------------------------------------------------------- @Override protected void doRun() { // load all equity securities final Collection<ExternalId> tickers = readEquityTickers(); createPortfolio(tickers); } private Collection<UniqueId> loadSecurities(final Collection<ExternalId> identifiers) { final SecurityMaster securityMaster = getToolContext().getSecurityMaster(); final SecurityProvider securityProvider = getToolContext().getSecurityProvider(); final DefaultSecurityLoader securityLoader = new DefaultSecurityLoader(securityMaster, securityProvider); final Map<ExternalIdBundle, UniqueId> loadedSecurities = securityLoader .loadSecurities(functional(identifiers).map(new Function1<ExternalId, ExternalIdBundle>() { @Override public ExternalIdBundle execute(final ExternalId ticker) { return ExternalIdBundle.of(ticker); } }).asList()); return loadedSecurities.values(); } /** * Create a empty portfolio. * <p> * This creates the portfolio and the root of the tree structure that holds the positions. * Subsequent methods then populate the tree. * * @return the emoty portfolio, not null */ protected ManageablePortfolio createEmptyPortfolio() { final ManageablePortfolio portfolio = new ManageablePortfolio(PORTFOLIO_NAME); final ManageablePortfolioNode rootNode = portfolio.getRootNode(); rootNode.setName("Root"); return portfolio; } /** * Create a position of a random number of shares. * <p> * This creates the position using a random number of units and create one or two trades making up the position. * * @param security the security to add a position for, not null * @return the position, not null */ protected ManageablePosition createPositionAndTrade(final EquitySecurity security) { s_logger.debug("Creating position {}", security); final int shares = (RandomUtils.nextInt(490) + 10) * 10; final ExternalIdBundle bundle = security.getExternalIdBundle(); // we could add an identifier pointing back to the original source database if we're doing an ETL. final ManageablePosition position = new ManageablePosition(BigDecimal.valueOf(shares), bundle); // create random trades that add up in shares to the position they're under (this is not enforced by the system) if (shares <= 2000) { final ManageableTrade trade = new ManageableTrade(BigDecimal.valueOf(shares), bundle, LocalDate.of(2010, 12, 3), null, ExternalId.of("CPARTY", "BACS")); position.addTrade(trade); } else { final ManageableTrade trade1 = new ManageableTrade(BigDecimal.valueOf(2000), bundle, LocalDate.of(2010, 12, 1), null, ExternalId.of("CPARTY", "BACS")); position.addTrade(trade1); final ManageableTrade trade2 = new ManageableTrade(BigDecimal.valueOf(shares - 2000), bundle, LocalDate.of(2010, 12, 2), null, ExternalId.of("CPARTY", "BACS")); position.addTrade(trade2); } return position; } /** * Adds the position to the master. * * @param position the position to add, not null * @return the added document, not null */ protected PositionDocument addPosition(final ManageablePosition position) { return getToolContext().getPositionMaster().add(new PositionDocument(position)); } /** * Adds the portfolio to the master. * * @param portfolio the portfolio to add, not null * @return the added document, not null */ protected PortfolioDocument addPortfolio(final ManageablePortfolio portfolio) { return getToolContext().getPortfolioMaster().add(new PortfolioDocument(portfolio)); } protected Collection<ExternalId> readEquityTickers() { final Collection<ExternalId> result = new ArrayList<>(); final InputStream inputStream = ExampleEquityPortfolioLoader.class .getResourceAsStream("example-equity.csv"); try { if (inputStream != null) { final List<String> equityTickers = IOUtils.readLines(inputStream); for (String idStr : equityTickers) { idStr = StringUtils.trimToNull(idStr); if (idStr != null && !idStr.startsWith("#")) { result.add(ExternalSchemes.bloombergTickerSecurityId(idStr)); } } } else { throw new OpenGammaRuntimeException("File '" + EXAMPLE_EQUITY_FILE + "' could not be found"); } } catch (final IOException ex) { throw new OpenGammaRuntimeException( "An error occurred while reading file '" + EXAMPLE_EQUITY_FILE + "'"); } finally { IOUtils.closeQuietly(inputStream); } final StringBuilder sb = new StringBuilder(); sb.append("Parsed ").append(result.size()).append(" equities:\n"); for (final ExternalId equityId : result) { sb.append("\t").append(equityId.getValue()).append("\n"); } s_logger.info(sb.toString()); return result; } }