/** * 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_EXCH_CODE; import static com.opengamma.bbg.BloombergConstants.FIELD_FUT_VAL_PT; import static com.opengamma.bbg.BloombergConstants.FIELD_ID_BBG_UNIQUE; import static com.opengamma.bbg.BloombergConstants.FIELD_MARKET_SECTOR_DES; import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_EXERCISE_TYP; import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_EXPIRE_DT; import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_PUT_CALL; import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_STRIKE_PX; import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_TICK_VAL; import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_UNDERLYING_SECURITY_DES; import static com.opengamma.bbg.BloombergConstants.FIELD_OPT_UNDL_CRNCY; import static com.opengamma.bbg.BloombergConstants.FIELD_PARSEKYABLE_DES; import static com.opengamma.bbg.BloombergConstants.FIELD_PRIMARY_EXCHANGE_NAME; import static com.opengamma.bbg.BloombergConstants.FIELD_TICKER; import static com.opengamma.bbg.BloombergConstants.FIELD_UNDL_ID_BB_UNIQUE; import java.util.HashSet; import java.util.Set; import org.fudgemsg.FudgeMsg; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.bp.LocalDate; import com.google.common.collect.ImmutableSet; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.bbg.referencedata.ReferenceDataProvider; import com.opengamma.bbg.security.BloombergSecurityProvider; import com.opengamma.bbg.util.BloombergDataUtils; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.financial.security.option.EquityIndexFutureOptionSecurity; import com.opengamma.financial.security.option.ExerciseType; import com.opengamma.financial.security.option.OptionType; import com.opengamma.financial.timeseries.exchange.DefaultExchangeDataProvider; import com.opengamma.financial.timeseries.exchange.ExchangeDataProvider; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.master.security.ManageableSecurity; import com.opengamma.util.money.Currency; import com.opengamma.util.time.DateUtils; import com.opengamma.util.time.Expiry; /** * Loads the data for an Equity Index Option from Bloomberg. */ public class EquityIndexFutureOptionLoader extends SecurityLoader { /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(EquityIndexFutureOptionLoader.class); /** * The fields to load from Bloomberg. */ private static final Set<String> BLOOMBERG_EQUITY_FUTURE_OPTION_FIELDS = ImmutableSet.of( FIELD_TICKER, FIELD_EXCH_CODE, FIELD_PARSEKYABLE_DES, FIELD_MARKET_SECTOR_DES, FIELD_OPT_EXERCISE_TYP, FIELD_OPT_STRIKE_PX, FIELD_OPT_PUT_CALL, FIELD_OPT_UNDERLYING_SECURITY_DES, FIELD_OPT_UNDL_CRNCY, FIELD_OPT_EXPIRE_DT, FIELD_ID_BBG_UNIQUE, FIELD_OPT_TICK_VAL, FIELD_FUT_VAL_PT, FIELD_UNDL_ID_BB_UNIQUE); /** * The valid Bloomberg security types for Equity Index Future Option * NOTE: THESE ARE ACTUALLY FUTURES_CATEGORY TYPES NOT SECURITY_TYP TYPES. */ public static final Set<String> VALID_SECURITY_TYPES = ImmutableSet.of("Equity Index", "Weekly Index Options"); private static final FutureOptionMarginResolver MARGIN_RESOLVER = new FutureOptionMarginResolver(); private static final ExchangeDataProvider s_exchangeData = DefaultExchangeDataProvider.getInstance(); /** * Creates an instance. * @param referenceDataProvider the provider, not null */ public EquityIndexFutureOptionLoader(ReferenceDataProvider referenceDataProvider) { super(s_logger, referenceDataProvider, SecurityType.EQUITY_INDEX_FUTURE_OPTION); } //------------------------------------------------------------------------- @Override protected ManageableSecurity createSecurity(FudgeMsg fieldData) { String rootTicker = fieldData.getString(FIELD_TICKER); String exchange = fieldData.getString(FIELD_EXCH_CODE); String exchangeDescription = fieldData.getString(FIELD_PRIMARY_EXCHANGE_NAME); String optionExerciseType = fieldData.getString(FIELD_OPT_EXERCISE_TYP); double optionStrikePrice = fieldData.getDouble(FIELD_OPT_STRIKE_PX); double pointValue = fieldData.getDouble(FIELD_FUT_VAL_PT); String putOrCall = fieldData.getString(FIELD_OPT_PUT_CALL); String underlingTicker = fieldData.getString(FIELD_OPT_UNDERLYING_SECURITY_DES); String currency = fieldData.getString(FIELD_OPT_UNDL_CRNCY); String expiryDate = fieldData.getString(FIELD_OPT_EXPIRE_DT); String bbgUniqueID = fieldData.getString(FIELD_ID_BBG_UNIQUE); String underlyingUniqueID = fieldData.getString(FIELD_UNDL_ID_BB_UNIQUE); String secDes = fieldData.getString(FIELD_PARSEKYABLE_DES); if (!BloombergDataUtils.isValidField(rootTicker)) { s_logger.warn("option root ticker is missing, cannot construct irFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(bbgUniqueID)) { s_logger.warn("bloomberg UniqueID is missing, cannot construct EquityIndexFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(underlyingUniqueID)) { s_logger.warn("bloomberg UniqueID for Underlying Security is missing, cannot construct EquityIndexFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(putOrCall)) { s_logger.warn("option type is missing, cannot construct EquityIndexFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(exchange)) { s_logger.warn("exchange is missing, cannot construct EquityIndexFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(expiryDate)) { s_logger.warn("option expiry date is missing, cannot construct EquityIndexFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(underlingTicker)) { s_logger.warn("option underlying ticker is missing, cannot construct EquityIndexFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(currency)) { s_logger.warn("option currency is missing, cannot construct EquityIndexFutureOption security"); return null; } if (!BloombergDataUtils.isValidField(optionExerciseType)) { s_logger.warn("option exercise type is missing, cannot construct EquityIndexFutureOption security"); return null; } OptionType optionType = getOptionType(putOrCall); //get year month day from expiryDate in the yyyy-mm-dd format LocalDate expiryLocalDate = null; try { expiryLocalDate = LocalDate.parse(expiryDate); } catch (Exception e) { throw new OpenGammaRuntimeException(expiryDate + " 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)); // TODO kirk 2009-11-03 -- Do something better with the underlying ticker, since we have it. /* String underlyingTicker = null; underlying = underlying.trim(); if (!underlying.endsWith("Equity") && secType.equals(BLOOMBERG_EQUITY_OPTION_SECURITY_TYPE)) { underlyingTicker = underlying + " Equity"; } else { underlyingTicker = underlying; } Set<DomainSpecificIdentifier> underlyingIdentifiers = new HashSet<DomainSpecificIdentifier>(); underlyingIdentifiers.add(new DomainSpecificIdentifier(IdentificationDomain.BLOOMBERG_TICKER, underlyingTicker)); underlyingIdentifiers.add(new DomainSpecificIdentifier(IdentificationDomain.BLOOMBERG_BUID, underlyingUniqueID)); SecurityKey underlingKey = new SecurityKeyImpl(Collections.unmodifiableSet(underlyingIdentifiers)); */ Currency ogCurrency = Currency.parse(currency); Set<ExternalId> identifiers = new HashSet<ExternalId>(); identifiers.add(ExternalSchemes.bloombergBuidSecurityId(bbgUniqueID)); if (BloombergDataUtils.isValidField(secDes)) { identifiers.add(ExternalSchemes.bloombergTickerSecurityId(secDes)); } final ExerciseType exerciseType = getExerciseType(optionExerciseType); // currently we will pick up the unified bbg exchange code - we try to map to MIC via the description if (exchangeDescription != null) { final String exchangeMIC = s_exchangeData.getExchangeFromDescription(exchangeDescription).getMic(); if (exchangeMIC != null) { exchange = exchangeMIC; } } final EquityIndexFutureOptionSecurity security = new EquityIndexFutureOptionSecurity( exchange, expiry, exerciseType, ExternalSchemes.bloombergBuidSecurityId(underlyingUniqueID), pointValue, MARGIN_RESOLVER.isMargined(exchange), ogCurrency, optionStrikePrice, optionType); security.setExternalIdBundle(ExternalIdBundle.of(identifiers)); security.setUniqueId(BloombergSecurityProvider.createUniqueId(bbgUniqueID)); //build option display name StringBuilder buf = new StringBuilder(rootTicker) .append(" ") .append(expiryDate) .append(optionType == OptionType.CALL ? " C " : " P ") .append(optionStrikePrice); security.setName(buf.toString()); return security; } @Override protected Set<String> getBloombergFields() { return BLOOMBERG_EQUITY_FUTURE_OPTION_FIELDS; } }