/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.volatility.surface;
import org.threeten.bp.LocalDate;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.core.value.MarketDataRequirementNames;
import com.opengamma.id.ExternalId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.time.Tenor;
/**
* Generates Bloomberg codes for swaption volatilities given tenors.
*/
public class BloombergSwaptionVolatilitySurfaceInstrumentProvider implements SurfaceInstrumentProvider<Tenor, Tenor> {
private final String _countryPrefix;
private final String _typePrefix;
private final String _postfix;
private final boolean _zeroPadSwapMaturityTenor;
private final boolean _zeroPadSwaptionExpiryTenor;
private final String _dataFieldName; // expecting MarketDataRequirementNames.MARKET_VALUE or PX_LAST
private final String _scheme;
public BloombergSwaptionVolatilitySurfaceInstrumentProvider(final String countryPrefix, final String typePrefix, final boolean zeroPadSwapMaturityTenor, final boolean zeroPadSwaptionExpiryTenor,
final String postfix) {
this(countryPrefix, typePrefix, zeroPadSwapMaturityTenor, zeroPadSwaptionExpiryTenor, postfix, MarketDataRequirementNames.MARKET_VALUE);
}
public BloombergSwaptionVolatilitySurfaceInstrumentProvider(final String countryPrefix, final String typePrefix, final boolean zeroPadSwapMaturityTenor, final boolean zeroPadSwaptionExpiryTenor,
final String postfix, final String dataFieldName) {
this(countryPrefix, typePrefix, zeroPadSwapMaturityTenor, zeroPadSwaptionExpiryTenor, postfix, dataFieldName, ExternalSchemes.BLOOMBERG_TICKER_WEAK.getName());
}
public BloombergSwaptionVolatilitySurfaceInstrumentProvider(final String countryPrefix, final String typePrefix, final boolean zeroPadSwapMaturityTenor, final boolean zeroPadSwaptionExpiryTenor,
final String postfix, final String dataFieldName, final String scheme) {
ArgumentChecker.notNull(countryPrefix, "country prefix");
ArgumentChecker.notNull(typePrefix, "type prefix");
ArgumentChecker.notNull(postfix, "postfix");
ArgumentChecker.notNull(dataFieldName, "data field name");
ArgumentChecker.notNull(scheme, "scheme");
_countryPrefix = countryPrefix;
_typePrefix = typePrefix;
_zeroPadSwapMaturityTenor = zeroPadSwapMaturityTenor;
_zeroPadSwaptionExpiryTenor = zeroPadSwaptionExpiryTenor;
_postfix = postfix;
_dataFieldName = dataFieldName;
_scheme = scheme;
}
@Override
public ExternalId getInstrument(final Tenor swapMaturityTenor, final Tenor swaptionExpiryTenor) {
final StringBuffer ticker = new StringBuffer();
ticker.append(_countryPrefix);
ticker.append(_typePrefix);
ticker.append(tenorToCode(swaptionExpiryTenor, _zeroPadSwaptionExpiryTenor));
ticker.append(tenorToCode(swapMaturityTenor, _zeroPadSwapMaturityTenor));
ticker.append(_postfix);
return ExternalId.of(_scheme, ticker.toString());
}
@Override
public ExternalId getInstrument(final Tenor startTenor, final Tenor maturity, final LocalDate surfaceDate) {
return getInstrument(startTenor, maturity);
}
private String tenorToCode(final Tenor tenor, final boolean prepadWithZero) {
if (tenor.getPeriod().getYears() == 0) {
final int months = tenor.getPeriod().getMonths();
if (months > 0) {
final String[] monthsTable = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "1A", "1B", "1C", "1D", "1E", "1F", "1G", "1H", "1I", "1J", "1K", "1L"};
final String result = monthsTable[months - 1];
if (result.length() == 1 && prepadWithZero) {
return "0" + result;
}
return result;
}
throw new OpenGammaRuntimeException("Cannot generate encoding for tenor " + tenor);
}
if (tenor.getPeriod().getYears() < 10 && prepadWithZero) {
return "0" + Integer.toString(tenor.getPeriod().getYears());
}
return Integer.toString(tenor.getPeriod().getYears());
}
/**
* Gets the countryPrefix field.
* @return the countryPrefix
*/
public String getCountryPrefix() {
return _countryPrefix;
}
/**
* Gets the typePrefix field.
* @return the typePrefix
*/
public String getTypePrefix() {
return _typePrefix;
}
/**
* Gets the postfix field.
* @return the postfix
*/
public String getPostfix() {
return _postfix;
}
/**
* Gets the zeroPadSwaptionMaturityTenor field.
* @return the zeroPadSwaptionMaturityTenor
*/
public boolean isZeroPadSwapMaturityTenor() {
return _zeroPadSwapMaturityTenor;
}
/**
* Gets the zeroPadSwaptionExpiryTenor field.
* @return the zeroPadSwaptionExpiryTenor
*/
public boolean isZeroPadSwaptionExpiryTenor() {
return _zeroPadSwaptionExpiryTenor;
}
/**
* @return The data field name - should be PX_LAST
*/
@Override
public String getDataFieldName() {
return _dataFieldName;
}
@Override
public boolean equals(final Object o) {
if (o == null) {
return false;
}
if (!(o instanceof BloombergSwaptionVolatilitySurfaceInstrumentProvider)) {
return false;
}
final BloombergSwaptionVolatilitySurfaceInstrumentProvider other = (BloombergSwaptionVolatilitySurfaceInstrumentProvider) o;
// we can avoid using ObjectUtil.equals because we validated the strings as not null.
return getCountryPrefix().equals(other.getCountryPrefix()) &&
getPostfix().equals(other.getPostfix()) &&
getTypePrefix().equals(other.getTypePrefix()) &&
isZeroPadSwapMaturityTenor() == other.isZeroPadSwapMaturityTenor() &&
isZeroPadSwaptionExpiryTenor() == other.isZeroPadSwaptionExpiryTenor() &&
getDataFieldName().equals(other.getDataFieldName()) &&
_scheme.equals(other._scheme);
}
@Override
public int hashCode() {
return getCountryPrefix().hashCode() + getTypePrefix().hashCode() + getPostfix().hashCode() + getDataFieldName().hashCode() + _scheme.hashCode();
}
}