/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.bbg.normalization; import java.util.Collections; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.bbg.loader.BloombergEquityScaleResolver; import com.opengamma.bbg.loader.BloombergFXForwardScaleResolver; import com.opengamma.bbg.loader.BloombergSecurityTypeResolver; import com.opengamma.bbg.loader.SecurityType; import com.opengamma.bbg.loader.SecurityTypeResolver; import com.opengamma.bbg.referencedata.ReferenceDataProvider; import com.opengamma.id.ExternalIdBundle; import com.opengamma.id.ExternalScheme; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.ehcache.EHCacheUtils; /** * Classifies Bloomberg rates based on the security type to determine the necessary normalization factor. */ public class BloombergRateClassifier { /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(BloombergRateClassifier.class); private static final String CACHE_KEY = "bbg-classifier-cache"; private final SecurityTypeResolver _securityTypeResolver; private final BloombergFXForwardScaleResolver _fwdScaleResolver; private final Cache _cache; private final ExternalScheme _bbgScheme; private final BloombergEquityScaleResolver _equityScaleResolver; /** * Constructs an instance. * * @param referenceDataProvider the underlying reference data provider, not null * @param cacheManager the cache manager, not null * @param bbgScheme the scheme that should be used to subscribe, not null */ public BloombergRateClassifier(ReferenceDataProvider referenceDataProvider, CacheManager cacheManager, ExternalScheme bbgScheme) { ArgumentChecker.notNull(referenceDataProvider, "referenceDataProvider"); ArgumentChecker.notNull(cacheManager, "cacheManager"); ArgumentChecker.notNull(bbgScheme, "bbgScheme"); _securityTypeResolver = new BloombergSecurityTypeResolver(referenceDataProvider); _fwdScaleResolver = new BloombergFXForwardScaleResolver(referenceDataProvider, bbgScheme); _equityScaleResolver = new BloombergEquityScaleResolver(referenceDataProvider, bbgScheme); EHCacheUtils.addCache(cacheManager, CACHE_KEY); _cache = EHCacheUtils.getCacheFromManager(cacheManager, CACHE_KEY); _bbgScheme = bbgScheme; } /** * Gets the normalization factor for a given security: 1, 100 or 10000. * <p> * The normalization factor is the multiple by which the market data is greater than the normalized value. * * @param buid the BUID value of the security, not null * @return the normalization factor, or null if the security cannot be classified */ public Integer getNormalizationFactor(String buid) { ArgumentChecker.notNull(buid, "buid"); Element e = _cache.get(buid); if (e != null) { s_logger.debug("Obtained normalization factor for security " + buid + " from cache"); return (Integer) e.getObjectValue(); } try { Integer normalizationFactor = getNormalizationFactorCore(buid); s_logger.debug("Generated normalization factor {} for security {}", normalizationFactor, buid); e = new Element(buid, normalizationFactor); _cache.put(e); return normalizationFactor; } catch (Exception ex) { s_logger.warn("Error obtaining normalization factor for security " + buid, ex); throw new OpenGammaRuntimeException("Error obtaining normalization factor for security " + buid, ex); } } private Integer getNormalizationFactorCore(String buid) { ExternalIdBundle buidBundle = ExternalIdBundle.of(_bbgScheme, buid); SecurityType securityType = _securityTypeResolver.getSecurityType(Collections.singleton(buidBundle)).get(buidBundle); if (securityType == null) { s_logger.warn("Unable to determine security type for BUID " + buid); return null; } switch (securityType) { case BASIS_SWAP: return 10000; case FORWARD_CROSS: case FX_FORWARD: Integer bbgFwdScale = _fwdScaleResolver.getBloombergFXForwardScale(Collections.singleton(buidBundle)).get(buidBundle); return getForwardScale(bbgFwdScale); case BILL: case BOND: case CASH: case CREDIT_DEFAULT_SWAP: case FRA: case INTEREST_RATE_FUTURE: case BOND_FUTURE: case IR_FUTURE_OPTION: case BOND_FUTURE_OPTION: case RATE: case INDEX: case SWAP: case VOLATILITY_QUOTE: case CD: case INFLATION_SWAP: return 100; case EQUITY_FUTURE: return 1; case INDEX_FUTURE: return 1; case EQUITY: Integer equityScale = _equityScaleResolver.getBloombergEquityScale(Collections.singleton(buidBundle)).get(buidBundle); return equityScale; default: return 1; } } private Integer getForwardScale(int bbgFwdScale) { switch(bbgFwdScale) { case 0: return 1; case 1: return 10; case 2: return 100; case 3: return 1000; case 4: return 10000; default: s_logger.warn("Unable to handle forward scale {}", bbgFwdScale); return null; } } }