/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.fxforwardcurve;
import org.apache.commons.lang.ObjectUtils;
import org.threeten.bp.LocalDate;
import org.threeten.bp.Period;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.core.value.MarketDataRequirementNames;
import com.opengamma.engine.value.ValueRequirementNames;
import com.opengamma.financial.analytics.ircurve.IndexType;
import com.opengamma.financial.analytics.ircurve.strips.DataFieldType;
import com.opengamma.id.ExternalId;
import com.opengamma.id.ExternalScheme;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.time.Tenor;
/**
* Generates FX forward and (optionally) FX spot tickers for constructing FX forward rate curves.
*/
public class BloombergFXForwardCurveInstrumentProvider implements FXForwardCurveInstrumentProvider {
/** The default data field */
private static final String DATA_FIELD = MarketDataRequirementNames.MARKET_VALUE;
/** The default data field type */
private static final DataFieldType FIELD_TYPE = DataFieldType.OUTRIGHT;
/** The default scheme */
private static final ExternalScheme SCHEME = ExternalSchemes.BLOOMBERG_TICKER;
/** The FX forward ticker prefix */
private final String _prefix;
/** The FX forward ticker postfix */
private final String _postfix;
/** The FX spot rate prefix */
private final String _spotPrefix;
/** The data field name */
private final String _dataFieldName;
/** The FX spot rate ticker */
private final String _spotName;
/** The FX spot rate external id */
private final ExternalId _spotId;
/** True if the BBG spot rate is to be used */
private final boolean _useSpotRateFromGraph;
/**
* Constructor where only FX forward ticker information is supplied. This sets the {@link #_useSpotRateFromGraph}
* field to true, which means that the FX spot rate will be supplied by {@link ValueRequirementNames#SPOT_RATE}.
* @param prefix The FX forward prefix, not null
* @param postfix The FX forward postfix, not null
* @param dataFieldName The Bloomberg data field name, not null
*/
public BloombergFXForwardCurveInstrumentProvider(final String prefix, final String postfix, final String dataFieldName) {
ArgumentChecker.notNull(prefix, "prefix");
ArgumentChecker.notNull(postfix, "postfix");
ArgumentChecker.notNull(dataFieldName, "dataFieldName");
_prefix = prefix;
_postfix = postfix;
_dataFieldName = dataFieldName;
_spotPrefix = null;
_spotName = null;
_spotId = null;
_useSpotRateFromGraph = true;
}
/**
* Constructor where the FX forward ticker and FX spot rate ticker information is supplied. This sets the
* {@link #_useSpotRateFromGraph} field to false, which means that the FX spot rate will be requested from
* the Bloomberg ticker.
* @param prefix The FX forward prefix, not null
* @param postfix The FX forward postfix, not null
* @param spotPrefix The FX spot prefix, not null
* @param dataFieldName The FX spot data field name, not null
*/
public BloombergFXForwardCurveInstrumentProvider(final String prefix, final String postfix, final String spotPrefix, final String dataFieldName) {
ArgumentChecker.notNull(prefix, "prefix");
ArgumentChecker.notNull(postfix, "postfix");
ArgumentChecker.notNull(spotPrefix, "spotPrefix");
ArgumentChecker.notNull(dataFieldName, "dataFieldName");
_prefix = prefix;
_postfix = postfix;
_spotPrefix = spotPrefix;
_dataFieldName = dataFieldName;
_spotName = spotPrefix + " " + _postfix;
_spotId = ExternalId.of(SCHEME, _spotName);
_useSpotRateFromGraph = false;
}
/**
* Gets the FX forward ticker prefix.
* @return The FX forward ticker prefix
*/
public String getPrefix() {
return _prefix;
}
/**
* Gets the FX forward ticker postfix.
* @return The FX forward ticker postfix
*/
public String getPostfix() {
return _postfix;
}
/**
* Gets the FX spot ticker prefix.
* @return The FX spot ticker prefix
*/
public String getSpotPrefix() {
if (_useSpotRateFromGraph) {
throw new IllegalStateException("This configuration does not support FX spot rate tickers");
}
return _spotPrefix;
}
@Override
public String getDataFieldName() {
return _dataFieldName;
}
/**
* Gets the spot ticker value e.g. EUR Curncy.
* @return The spot ticker value.
*/
public String getSpotName() {
if (_useSpotRateFromGraph) {
throw new IllegalStateException("This configuration does not support FX spot rate tickers");
}
return _spotName;
}
@Override
public ExternalId getSpotInstrument() {
if (_useSpotRateFromGraph) {
throw new IllegalStateException("This configuration does not support FX spot rate tickers");
}
return _spotId;
}
@Override
public String getMarketDataField() {
return DATA_FIELD;
}
@Override
public DataFieldType getDataFieldType() {
return FIELD_TYPE;
}
@Override
public boolean useSpotRateFromGraph() {
return _useSpotRateFromGraph;
}
@Override
public ExternalId getInstrument(final LocalDate curveDate, final Tenor tenor) {
final StringBuffer ticker = new StringBuffer();
ticker.append(_prefix);
final Period period = tenor.getPeriod();
if (period.getYears() != 0) {
ticker.append(period.getYears() + "Y");
} else if (period.getMonths() != 0) {
ticker.append(period.getMonths() + "M");
} else {
final int days = period.getDays();
if (days != 0) {
if (days % 7 == 0) {
ticker.append(days / 7 + "W");
} else if (days == 1) {
ticker.append("ON");
} else if (days == 2) {
ticker.append("TN");
} else if (days == 3) {
ticker.append("SN");
} else {
throw new OpenGammaRuntimeException("Cannot handle period of " + days + " days");
}
} else {
throw new OpenGammaRuntimeException("Can only handle periods of year, month, week and day");
}
}
ticker.append(" ");
ticker.append(_postfix);
return ExternalId.of(SCHEME, ticker.toString());
}
@Override
public ExternalId getInstrument(final LocalDate curveDate, final Tenor tenor, final int numQuarterlyFuturesFromTenor) {
throw new UnsupportedOperationException();
}
@Override
public ExternalId getInstrument(final LocalDate curveDate, final Tenor tenor, final int periodsPerYear, final boolean isPeriodicZeroDeposit) {
throw new UnsupportedOperationException();
}
@Override
public ExternalId getInstrument(final LocalDate curveDate, final Tenor tenor, final Tenor payTenor, final Tenor receiveTenor, final IndexType payIndexType,
final IndexType receiveIndexType) {
throw new UnsupportedOperationException();
}
@Override
public ExternalId getInstrument(final LocalDate curveDate, final Tenor tenor, final Tenor resetTenor, final IndexType indexType) {
throw new UnsupportedOperationException();
}
@Override
public ExternalId getInstrument(final LocalDate curveDate, final Tenor startTenor, final Tenor futureTenor, final int numFutureFromTenor) {
throw new UnsupportedOperationException();
}
@Override
public ExternalId getInstrument(final LocalDate curveDate, final Tenor startTenor, final int startIMMPeriods, final int endIMMPeriods) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return getPrefix().hashCode() + getPostfix().hashCode() + getDataFieldName().hashCode();
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof BloombergFXForwardCurveInstrumentProvider)) {
return false;
}
final BloombergFXForwardCurveInstrumentProvider other = (BloombergFXForwardCurveInstrumentProvider) obj;
if (!_useSpotRateFromGraph && !ObjectUtils.equals(getSpotPrefix(), other.getSpotPrefix())) {
return false;
}
return getPrefix().equals(other.getPrefix()) &&
getPostfix().equals(other.getPostfix()) &&
getDataFieldName().equals(other.getDataFieldName());
}
}