BloombergDataUtils { public static ExternalId futureBundleToGenericFutureTicker(ExternalIdBundle bundle, ZonedDateTime now, OffsetTime futureExpiryTime, ZoneId futureExpiryTimeZone) { ZonedDateTime nextExpiry = now.toLocalDate().with(s_monthlyExpiryAdjuster).atTime(now.toLocalTime()).atZone(now.getZone()); ExternalId bbgTicker = bundle.getExternalId(ExternalSchemes.BLOOMBERG_TICKER); if (bbgTicker == null) { throw new OpenGammaRuntimeException("Could not find a Bloomberg Ticker in the supplied bundle " + bundle.toString()); } final String code = bbgTicker.getValue(); final String marketSector = splitTickerAtMarketSector(code).getSecond(); try { String typeCode; String monthCode; int year; if (code.length() > 4 && code.charAt(4) == ' ') { typeCode = code.substring(0, 2); monthCode = code.substring(2, 3); year = Integer.parseInt(code.substring(3, 4)); final int thisYear = now.getYear(); if ((thisYear % 10) > year) { year = ((thisYear / 10) * 10) + 10 + year; } else if ((thisYear % 10) == year) { final Month month = s_monthCode.inverse().get(monthCode); if (month == null) { throw new OpenGammaRuntimeException("Invalid month code " + monthCode); } LocalDate nextExpiryIfThisYear = LocalDate.of((((thisYear / 10) * 10) + year), month, 1).with(s_monthlyExpiryAdjuster); ZonedDateTime nextExpiryDateTimeIfThisYear = nextExpiryIfThisYear.atTime(futureExpiryTime).atZoneSimilarLocal(futureExpiryTimeZone); if (now.isAfter(nextExpiryDateTimeIfThisYear)) { year = ((thisYear / 10) * 10) + 10 + year; } else { year = ((thisYear / 10) * 10) + year; } } else { year = ((thisYear / 10) * 10) + year; } } else if (code.length() > 5 && code.charAt(5) == ' ') { typeCode = code.substring(0, 2); monthCode = code.substring(2, 3); s_logger.warn("Parsing retired futures code format {}", code); year = Integer.parseInt(code.substring(3, 5)); if (year > 70) { year += 1900; } else { year += 2000; } } else { s_logger.warn("Unknown futures code format {}", code); return null; } LocalDate expiryDate = LocalDate.of(year, s_monthCode.inverse().get(monthCode), 1).with(s_monthlyExpiryAdjuster); ZonedDateTime expiry = expiryDate.atTime(futureExpiryTime).atZoneSimilarLocal(futureExpiryTimeZone); int quarters = (int) nextExpiry.periodUntil(expiry, MONTHS) / 3; int genericFutureNumber = quarters + 1; StringBuilder sb = new StringBuilder(); sb.append(typeCode); sb.append(genericFutureNumber); sb.append(" "); sb.append(marketSector); return ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, sb.toString()); } catch (final NumberFormatException nfe) { s_logger.error("Could not parse futures code {}", code); } return null; } private  BloombergDataUtils(); static Collection<NormalizationRuleSet> getDefaultNormalizationRules(final ReferenceDataProvider referenceDataProvider, final CacheManager cacheManager, ExternalScheme bbgScheme); static HistoricalTimeSeriesFieldAdjustmentMap createFieldAdjustmentMap(final ReferenceDataProvider referenceDataProvider, final CacheManager cacheManager); static MarketDataAvailabilityFilter createAvailabilityFilter(); static FudgeMsg parseElement(final Element element); static Object parseValue(final Element valueElement); static String getSingleBUID(final ReferenceDataProvider refDataProvider, final String securityDes); static Map<String, String> getBUID(final ReferenceDataProvider refDataProvider, final Set<String> bloombergKeys); static Set<String> getIndexMembers(final ReferenceDataProvider refDataProvider, final String indexTicker); static Set<ExternalId> getOptionChain(final ReferenceDataProvider refDataProvider, final String securityID); static Set<ExternalId> getFuturechain(final ReferenceDataProvider refDataProvider, final String securityID); static boolean isValidField(final String name); static ExternalIdBundleWithDates parseIdentifiers(final FudgeMsg fieldData, final String firstTradeDateField, final String lastTradeDateField); static ExternalIdBundleWithDates addTwoDigitYearCode(final ExternalIdBundleWithDates bundleWithDates); static Set<ExternalIdBundle> getCurrentIdentifiers(final PositionMaster positionMaster); static String removeDuplicateWhiteSpace(final String field, final String replacement); static Set<ExternalId> identifierLoader(final Reader reader); static BiMap<String, ExternalIdBundle> convertToBloombergBuidKeys(final Collection<ExternalIdBundle> identifiers, final ReferenceDataProvider refDataProvider); static Pair<String, String> splitTickerAtMarketSector(final String ticker); static boolean isValidBloombergTicker(final String ticker); static ExternalId generateEquityOptionTicker(final String underlyingTicker, final Expiry expiry, final OptionType optionType, final double strike); static String dateToBbgCode(final LocalDate date); static ExternalId ricToBbgFuture(final String ric); static ExternalId ricToBbgFutureOption(final String ric, final boolean isCall, final double strike, final LocalDate expiry); static ExternalId futureBundleToGenericFutureTicker(ExternalIdBundle bundle, ZonedDateTime now, OffsetTime futureExpiryTime, ZoneId futureExpiryTimeZone); static String resolveDataProvider(final String dataProvider); static String resolveObservationTime(String dataProvider); static String toBloombergDate(LocalDate localDate); static String futureMonthCode(final Month month); static final List<String> STANDARD_FIELDS_LIST; static final Set<String> STANDARD_FIELDS_SET; }
@Test public void testFutureBundleToGenericFutureTicker() { ZonedDateTime now = LocalDateTime.of(2012, 8, 25, 14, 32, 00, 00).atZone(ZoneId.of("Europe/London")); ExternalId testInput1 = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "EDZ2 Comdty"); ExternalId expectedOutput1 = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "ED2 Comdty"); ExternalId actualOutput1 = BloombergDataUtils.futureBundleToGenericFutureTicker(testInput1.toBundle(), now, LocalTime.of(15, 00).atOffset(ZoneOffset.ofHours(1)), ZoneId.of("Europe/London")); assertEquals(expectedOutput1, actualOutput1); ExternalId testInput2 = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "EDZ1 Comdty"); ExternalId expectedOutput2 = ExternalId.of(ExternalSchemes.BLOOMBERG_TICKER, "ED37 Comdty"); ExternalId actualOutput2 = BloombergDataUtils.futureBundleToGenericFutureTicker(testInput2.toBundle(), now, LocalTime.of(15, 00).atOffset(ZoneOffset.ofHours(1)), ZoneId.of("Europe/London")); assertEquals(expectedOutput2, actualOutput2); }