/** * 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_CRNCY; import static com.opengamma.bbg.BloombergConstants.FIELD_FUTURES_CATEGORY; import static com.opengamma.bbg.BloombergConstants.FIELD_FUT_FIRST_TRADE_DT; import static com.opengamma.bbg.BloombergConstants.FIELD_FUT_LONG_NAME; import static com.opengamma.bbg.BloombergConstants.FIELD_FUT_TRADING_HRS; import static com.opengamma.bbg.BloombergConstants.FIELD_FUT_TRADING_UNITS; import static com.opengamma.bbg.BloombergConstants.FIELD_ID_BBG_UNIQUE; import static com.opengamma.bbg.BloombergConstants.FIELD_ID_CUSIP; import static com.opengamma.bbg.BloombergConstants.FIELD_ID_ISIN; import static com.opengamma.bbg.BloombergConstants.FIELD_ID_MIC_PRIM_EXCH; import static com.opengamma.bbg.BloombergConstants.FIELD_ID_SEDOL1; import static com.opengamma.bbg.BloombergConstants.FIELD_LAST_TRADEABLE_DT; import static com.opengamma.bbg.BloombergConstants.FIELD_PARSEKYABLE_DES; import static com.opengamma.bbg.BloombergConstants.FIELD_QUOTED_CRNCY; import static com.opengamma.bbg.BloombergConstants.FIELD_QUOTE_UNITS; import static com.opengamma.bbg.util.BloombergDataUtils.isValidField; import java.util.Collections; import java.util.Map; import java.util.Set; import org.fudgemsg.FudgeMsg; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; import com.opengamma.bbg.BloombergConstants; import com.opengamma.bbg.referencedata.ReferenceDataProvider; import com.opengamma.bbg.util.BloombergDataUtils; import com.opengamma.financial.security.future.FXFutureSecurity; import com.opengamma.master.security.ManageableSecurity; import com.opengamma.util.money.Currency; import com.opengamma.util.time.Expiry; /** * Loads the data for a FX Future from Bloomberg. */ public class FXFutureLoader extends SecurityLoader { /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(FXFutureLoader.class); /** * The fields to load from Bloomberg. */ private static final Set<String> BLOOMBERG_CURRENCY_FUTURE_FIELDS = Collections.unmodifiableSet(Sets.newHashSet( FIELD_FUT_LONG_NAME, FIELD_LAST_TRADEABLE_DT, FIELD_FUT_TRADING_HRS, FIELD_FUTURES_CATEGORY, FIELD_CRNCY, FIELD_FUT_TRADING_UNITS, FIELD_QUOTE_UNITS, FIELD_QUOTED_CRNCY, FIELD_ID_MIC_PRIM_EXCH, FIELD_ID_BBG_UNIQUE, FIELD_ID_CUSIP, FIELD_ID_ISIN, FIELD_ID_SEDOL1, FIELD_PARSEKYABLE_DES, FIELD_FUT_FIRST_TRADE_DT)); /** * Maps from the QUOTE_UNITS field to the unit amount. As more units are encountered, this approach will need to be * improved. */ private static final Map<String, Double> UNIT_AMOUNT_MAP = ImmutableMap.of( "cents/CHF", 100d, "cents/100 YEN", 1d, "cents/CAD", 100d); /** * The valid Bloomberg future categories for FX Futures */ public static final Set<String> VALID_FUTURE_CATEGORIES = Collections.unmodifiableSet(Sets.newHashSet( BloombergConstants.BBG_CURRENCY_TYPE)); /** * Creates an instance. * @param referenceDataProvider the provider, not null */ public FXFutureLoader(ReferenceDataProvider referenceDataProvider) { super(s_logger, referenceDataProvider, SecurityType.FX_FUTURE); } //------------------------------------------------------------------------- @Override protected ManageableSecurity createSecurity(FudgeMsg fieldData) { String bbgUnique = fieldData.getString(FIELD_ID_BBG_UNIQUE); String category = BloombergDataUtils.removeDuplicateWhiteSpace(fieldData.getString(FIELD_FUTURES_CATEGORY), " "); String name = BloombergDataUtils.removeDuplicateWhiteSpace(fieldData.getString(FIELD_FUT_LONG_NAME), " "); String expiryDate = fieldData.getString(FIELD_LAST_TRADEABLE_DT); String futureTradingHours = fieldData.getString(FIELD_FUT_TRADING_HRS); String micExchangeCode = fieldData.getString(FIELD_ID_MIC_PRIM_EXCH); String currencyCode = fieldData.getString(FIELD_CRNCY); String quoteUnits = fieldData.getString(FIELD_QUOTE_UNITS); String tradingCurrencyCode = fieldData.getString(FIELD_FUT_TRADING_UNITS); String quotedCurrencyCode = fieldData.getString(FIELD_QUOTED_CRNCY); if (!isValidField(bbgUnique)) { logMissingData(FIELD_ID_BBG_UNIQUE, name); return null; } if (!isValidField(expiryDate)) { logMissingData(FIELD_LAST_TRADEABLE_DT, name); return null; } if (!isValidField(futureTradingHours)) { logMissingData(FIELD_FUT_TRADING_HRS, name); return null; } if (!isValidField(micExchangeCode)) { logMissingData(FIELD_ID_MIC_PRIM_EXCH, name); return null; } if (!isValidField(currencyCode)) { logMissingData(FIELD_CRNCY, name); return null; } if (!isValidField(quoteUnits)) { logMissingData(FIELD_QUOTE_UNITS, name); return null; } if (!isValidField(tradingCurrencyCode)) { logMissingData(FIELD_FUT_TRADING_UNITS, name); return null; } if (!isValidField(quotedCurrencyCode)) { logMissingData(FIELD_QUOTED_CRNCY, name); } if (!isValidField(category)) { logMissingData(FIELD_FUTURES_CATEGORY, name); } Double unitAmount = UNIT_AMOUNT_MAP.get(quoteUnits); if (unitAmount == null) { s_logger.warn("Unknown quote units: " + quoteUnits); return null; } Expiry expiry = decodeExpiry(expiryDate, futureTradingHours); if (expiry == null) { s_logger.warn("Unable to decode expiry '" + expiryDate + "' against trading hours '" + futureTradingHours + "'"); return null; } Currency currency = Currency.parse(currencyCode); Currency tradingCurrency = Currency.parse(tradingCurrencyCode); Currency quotedCurrency = Currency.parse(quotedCurrencyCode); FXFutureSecurity security = new FXFutureSecurity(expiry, micExchangeCode, micExchangeCode, currency, unitAmount, tradingCurrency, quotedCurrency, category); security.setName(name); parseIdentifiers(fieldData, security, FIELD_FUT_FIRST_TRADE_DT, FIELD_LAST_TRADEABLE_DT); return security; } private void logMissingData(String fieldName, String securityName) { s_logger.warn("Cannot construct FX Future security '" + securityName + "' as " + fieldName + " is missing"); } @Override protected Set<String> getBloombergFields() { return BLOOMBERG_CURRENCY_FUTURE_FIELDS; } }