public static void fromFudgeMsg(
     FudgeDeserializer deserializer, FudgeMsg msg, FXOptionSecurity object) {
   FinancialSecurityFudgeBuilder.fromFudgeMsg(deserializer, msg, object);
   object.setPutCurrency(msg.getValue(Currency.class, PUT_CURRENCY_FIELD_NAME));
   object.setCallCurrency(msg.getValue(Currency.class, CALL_CURRENCY_FIELD_NAME));
   object.setPutAmount(msg.getDouble(PUT_AMOUNT_FIELD_NAME));
   object.setCallAmount(msg.getDouble(CALL_AMOUNT_FIELD_NAME));
   object.setExpiry(
       ExpiryFudgeBuilder.fromFudgeMsg(deserializer, msg.getMessage(EXPIRY_FIELD_NAME)));
   object.setSettlementDate(
       ZonedDateTimeFudgeBuilder.fromFudgeMsg(
           deserializer, msg.getMessage(SETTLEMENT_DATE_FIELD_NAME)));
   object.setLongShort(LongShort.ofLong(msg.getBoolean(IS_LONG_FIELD_NAME)));
 }
 @Override
 public MoneynessPiecewiseSABRSurfaceFitter buildObject(
     final FudgeDeserializer deserializer, final FudgeMsg message) {
   final boolean useLogTime = message.getBoolean(TIME_FIELD_NAME);
   final boolean useIntegratedVar = message.getBoolean(SPACE_FIELD_NAME);
   final double lambda = message.getDouble(LAMBDA_FIELD_NAME);
   return new MoneynessPiecewiseSABRSurfaceFitter(useLogTime, useIntegratedVar, lambda);
 }
 @Override
 public BloombergEquityFutureOptionVolatilitySurfaceInstrumentProvider buildObject(
     final FudgeDeserializer deserializer, final FudgeMsg message) {
   String futureOptionPrefix = message.getString(PREFIX_FIELD_NAME);
   // backward compatibility
   if (futureOptionPrefix == null) {
     futureOptionPrefix = message.getString("futureOptionPrefix");
   }
   String postfix = message.getString(POSTFIX_FIELD_NAME);
   // backward compatibility
   if (postfix == null) {
     postfix = message.getString("postfix");
   }
   String dataFieldName = message.getString(DATA_FIELD_NAME);
   // backward compatibility
   if (dataFieldName == null) {
     dataFieldName = message.getString("dataFieldName");
   }
   final Double useCallAboveValue = message.getDouble(CALL_FIELD_NAME);
   if (message.hasField(EXCHANGE_ID_FIELD_NAME)) {
     final String exchangeId = message.getString(EXCHANGE_ID_FIELD_NAME);
     if (message.hasField(TICKER_SCHEME_NAME)) {
       final String tickerScheme = message.getString(TICKER_SCHEME_NAME);
       return new BloombergEquityFutureOptionVolatilitySurfaceInstrumentProvider(
           futureOptionPrefix,
           postfix,
           dataFieldName,
           useCallAboveValue,
           exchangeId,
           tickerScheme);
     }
     return new BloombergEquityFutureOptionVolatilitySurfaceInstrumentProvider(
         futureOptionPrefix, postfix, dataFieldName, useCallAboveValue, exchangeId);
   }
   if (message.hasField(TICKER_SCHEME_NAME)) { // this will never be hit, but better to be safe
     final String tickerScheme = message.getString(TICKER_SCHEME_NAME);
     return new BloombergEquityFutureOptionVolatilitySurfaceInstrumentProvider(
         futureOptionPrefix,
         postfix,
         dataFieldName,
         useCallAboveValue,
         DEFAULT_EXCHANGE_ID,
         tickerScheme);
   }
   return new BloombergEquityFutureOptionVolatilitySurfaceInstrumentProvider(
       futureOptionPrefix, postfix, dataFieldName, useCallAboveValue, DEFAULT_EXCHANGE_ID);
 }
  // -------------------------------------------------------------------------
  protected ManageablePortfolio generatePortfolio(final String portfolioName) {
    final ReferenceDataProvider referenceDataProvider =
        getToolContext().getBloombergReferenceDataProvider();

    final ManageablePortfolio portfolio = new ManageablePortfolio(portfolioName);

    // Is this a hack?
    final ManageablePortfolioNode rootNode = portfolio.getRootNode();
    portfolio.setRootNode(rootNode);

    //    String indexTickerSuffix = " Index";

    final Set<String> memberEquities = new HashSet<String>();

    for (final Entry<String, String> entry : INDEXES_TO_EXCHANGE.entrySet()) {

      final String indexTickerSuffix = " Index";

      final String underlying = entry.getKey();
      final String ticker = underlying + indexTickerSuffix;

      // don't add index (delete at some point)
      //      addNodes(rootNode, ticker, false, INDEX_OPTION_PERIODS);

      final Set<String> indexMembers =
          BloombergDataUtils.getIndexMembers(referenceDataProvider, ticker);
      for (final String member : indexMembers) {
        final String symbol = getBloombergEquitySymbol(entry.getValue(), member);
        // time series errors for Walmart
        // Todo: investegate & fix
        if ("WMT US Equity".equals(symbol)) {
          continue;
        }
        memberEquities.add(symbol);
      }
    }

    // Sort the symbols for the current index by market cap (highest to lowest), skipping any in the
    // list of EXCLUDED_SECTORS
    final TreeMap<Double, String> equityByMarketCap = new TreeMap<Double, String>();
    final Map<String, FudgeMsg> refDataMap =
        referenceDataProvider.getReferenceData(
            memberEquities,
            Sets.newHashSet(
                BloombergFields.CURRENT_MARKET_CAP_FIELD,
                BloombergConstants.FIELD_GICS_SUB_INDUSTRY));
    for (final String equity : memberEquities) {
      final FudgeMsg fieldData = refDataMap.get(equity);
      if (fieldData == null) {
        throw new OpenGammaRuntimeException("Information not found for equity: " + equity);
      }
      final String gicsCodeString = fieldData.getString(BloombergConstants.FIELD_GICS_SUB_INDUSTRY);
      if (gicsCodeString == null) {
        continue;
      }
      final GICSCode gicsCode = GICSCode.of(gicsCodeString);
      if (EXCLUDED_SECTORS.contains(gicsCode.getSectorDescription())) {
        continue;
      }
      final Double marketCap = fieldData.getDouble(BloombergFields.CURRENT_MARKET_CAP_FIELD);
      if (marketCap != null) {
        equityByMarketCap.put(marketCap, equity);
      }
    }

    // Add a given number of symbols (MEMBERS_DEPTH) to the portfolio and store in a List
    // When adding to the portfolio, add a collar of options with PVs distributed equally +/- around
    // 0
    int count = 0;
    final List<String> chosenEquities = new ArrayList<String>();
    for (final Entry<Double, String> entry : equityByMarketCap.descendingMap().entrySet()) {
      try {
        addNodes(rootNode, entry.getValue(), true, MEMBER_OPTION_PERIODS);
        chosenEquities.add(entry.getValue());
        if (++count >= _numMembers) {
          break;
        }
      } catch (final RuntimeException e) {
        s_logger.warn("Caught exception", e);
      }
    }
    s_logger.info("Generated collar portfolio for {}", chosenEquities);
    return portfolio;
  }