/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.integration.copier.portfolio.rowparser; import java.math.BigDecimal; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.bp.LocalDate; import org.threeten.bp.LocalTime; import org.threeten.bp.ZoneOffset; import org.threeten.bp.format.DateTimeFormatter; import com.google.common.collect.ImmutableMap; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.core.position.Counterparty; import com.opengamma.core.security.Security; import com.opengamma.financial.security.FinancialSecurity; import com.opengamma.financial.security.FinancialSecurityUtils; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.id.ExternalScheme; import com.opengamma.integration.copier.portfolio.writer.SingleSheetPositionWriter; import com.opengamma.master.position.ManageablePosition; import com.opengamma.master.position.ManageableTrade; import com.opengamma.master.security.ManageableSecurity; import com.opengamma.provider.security.SecurityProvider; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; /** * A row parser that reads in a ticker for an exchange-traded security, a quantity for a position, and * optionally a trade date, premium and counterparty for a trade. */ public class ExchangeTradedRowParser extends RowParser { public enum DateFormat { ISO(DateTimeFormatter.ISO_DATE, DateTimeFormatter.BASIC_ISO_DATE), UK(DateTimeFormatter.ofPattern("dd/MM/yyyy"), DateTimeFormatter.ofPattern("dd-MM-yyyy")), US(DateTimeFormatter.ofPattern("MM/dd/yyyy"), DateTimeFormatter.ofPattern("MM-dd-yyyy")); private final DateTimeFormatter _primaryFormatter; private final DateTimeFormatter _secondaryFormatter; private DateFormat(DateTimeFormatter primaryFormatter, DateTimeFormatter secondaryFormatter) { _primaryFormatter = primaryFormatter; _secondaryFormatter = secondaryFormatter; } } private static final Logger s_logger = LoggerFactory.getLogger(ExchangeTradedRowParser.class); private static final String TICKER = "ticker"; private static final String ATTRIBUTES = "attributes"; private static final String QUANTITY = "quantity"; private static final String TRADE_DATE = "trade date"; private static final String PREMIUM = "premium"; private static final String PREMIUM_CURRENCY = "premiumcurrency"; private static final String PREMIUM_DATE = "premiumdate"; private static final String COUNTERPARTY = "counterparty"; private String[] _columns = {TICKER, QUANTITY, TRADE_DATE, PREMIUM, COUNTERPARTY, ATTRIBUTES}; private SecurityProvider _securityProvider; public ExchangeTradedRowParser(SecurityProvider securityProvider, DateFormat dateFormat) { super(dateFormat._primaryFormatter, dateFormat._secondaryFormatter); ArgumentChecker.notNull(securityProvider, "securityProvider"); _securityProvider = securityProvider; } public ExchangeTradedRowParser(SecurityProvider securityProvider, DateTimeFormatter dateFormatter) { super(dateFormatter); ArgumentChecker.notNull(securityProvider, "securityProvider"); _securityProvider = securityProvider; } private static final ExternalScheme[] s_schemeWaterfall = { ExternalSchemes.BLOOMBERG_TICKER, ExternalSchemes.BLOOMBERG_TCM, ExternalSchemes.BLOOMBERG_BUID, ExternalSchemes.CUSIP, ExternalSchemes.ISIN }; @Override public ManageableSecurity[] constructSecurity(Map<String, String> row) { ArgumentChecker.notNull(row, "row"); String idStr = getWithException(row, TICKER); if (idStr == null) { s_logger.error("Ticker column contained no value, skipping row"); return new ManageableSecurity[] {}; } try { ExternalIdBundle id = ExternalId.parse(idStr).toBundle(); Security security = _securityProvider.getSecurity(id); if (security != null && security instanceof ManageableSecurity) { return new ManageableSecurity[] {(ManageableSecurity) security}; } } catch (IllegalArgumentException iae) { for (ExternalScheme scheme : s_schemeWaterfall) { ExternalIdBundle id = ExternalId.of(scheme, idStr).toBundle(); Security security = _securityProvider.getSecurity(id); if (security != null && security instanceof ManageableSecurity) { return new ManageableSecurity[] {(ManageableSecurity) security}; } } } return new ManageableSecurity[] {}; } @Override public ManageablePosition constructPosition(Map<String, String> row, ManageableSecurity security) { // Create position using the quantity field ArgumentChecker.notNull(row, "row"); ArgumentChecker.notNull(security, "security"); if (row.containsKey(QUANTITY)) { return new ManageablePosition( BigDecimal.valueOf(Integer.parseInt(getWithException(row, QUANTITY))), security.getExternalIdBundle() ); } else { return new ManageablePosition( BigDecimal.ONE, security.getExternalIdBundle() ); } } @Override public ManageableTrade constructTrade(Map<String, String> row, ManageableSecurity security, ManageablePosition position) { ArgumentChecker.notNull(row, "row"); ArgumentChecker.notNull(security, "security"); ArgumentChecker.notNull(position, "position"); // Create trade using trade date, premium and counterparty if available in current row if (row.containsKey(TRADE_DATE) && row.containsKey(PREMIUM) && row.containsKey(COUNTERPARTY)) { LocalDate tradeDate = getDateWithException(row, TRADE_DATE); ExternalId counterpartyId = ExternalId.of(Counterparty.DEFAULT_SCHEME, getWithException(row, COUNTERPARTY)); ManageableTrade result = new ManageableTrade( position.getQuantity(), security.getExternalIdBundle(), tradeDate, LocalTime.of(11, 11).atOffset(ZoneOffset.UTC), counterpartyId); result.setPremium(Double.parseDouble(row.get(PREMIUM))); if (row.containsKey(PREMIUM_CURRENCY)) { result.setPremiumCurrency(Currency.parse(getWithException(row, PREMIUM_CURRENCY))); } else { if (security instanceof FinancialSecurity) { Currency currency = FinancialSecurityUtils.getCurrency(security); if (currency != null) { result.setPremiumCurrency(currency); } } } if (row.containsKey(PREMIUM_DATE)) { result.setPremiumDate(getDateWithException(row, PREMIUM_DATE)); } return result; } else { return null; } } @Override public Map<String, String> constructRow(ManageableTrade trade) { Map<String, String> map = new HashMap<>(); addValueIfNotNull(map, QUANTITY, trade.getQuantity()); addValueIfNotNull(map, TRADE_DATE, trade.getTradeDate()); addValueIfNotNull(map, PREMIUM, trade.getPremium()); return map; } @Override public Map<String, String> constructRow(ManageablePosition position) { BigDecimal quantity = position.getQuantity(); if (quantity != null) { return Collections.singletonMap(QUANTITY, quantity.toString()); } return null; } @Override public Map<String, String> constructRow(ManageableSecurity[] securities) { if (securities.length < 1) { return null; } String ticker = securities[0].getExternalIdBundle().getValue(ExternalSchemes.BLOOMBERG_TICKER); if (ticker != null) { String attributes = SingleSheetPositionWriter.attributesToString(securities[0].getAttributes()); return ImmutableMap.of( TICKER, ticker, ATTRIBUTES, attributes ); } return null; } @Override public String[] getColumns() { return _columns; } }