/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.sesame;
import java.util.ArrayList;
import java.util.Collection;
import org.threeten.bp.LocalDate;
import org.threeten.bp.Period;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeries;
import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesSource;
import com.opengamma.core.value.MarketDataRequirementNames;
import com.opengamma.financial.analytics.timeseries.HistoricalTimeSeriesBundle;
import com.opengamma.financial.convention.frequency.PeriodFrequency;
import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.financial.security.FinancialSecurityVisitorAdapter;
import com.opengamma.financial.security.fra.ForwardRateAgreementSecurity;
import com.opengamma.financial.security.future.BondFutureSecurity;
import com.opengamma.financial.security.future.DeliverableSwapFutureSecurity;
import com.opengamma.financial.security.future.FederalFundsFutureSecurity;
import com.opengamma.financial.security.future.InterestRateFutureSecurity;
import com.opengamma.financial.security.irs.FloatingInterestRateSwapLeg;
import com.opengamma.financial.security.irs.InterestRateSwapSecurity;
import com.opengamma.financial.security.option.BondFutureOptionSecurity;
import com.opengamma.financial.security.option.IRFutureOptionSecurity;
import com.opengamma.financial.security.option.SwaptionSecurity;
import com.opengamma.id.ExternalId;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.util.money.Currency;
import com.opengamma.util.result.FailureStatus;
import com.opengamma.util.result.Result;
/**
* Function implementation that provides a historical time-series bundle.
* @deprecated use {@link DefaultFixingsFn}
*/
@Deprecated
public class DefaultHistoricalTimeSeriesFn implements HistoricalTimeSeriesFn {
private static final HistoricalTimeSeriesBundle EMPTY_TIME_SERIES_BUNDLE = new HistoricalTimeSeriesBundle();
private static final Period ONE_MONTH = Period.ofMonths(1);
private final HistoricalTimeSeriesSource _htsSource;
private final String _resolutionKey;
public DefaultHistoricalTimeSeriesFn(HistoricalTimeSeriesSource htsSource, String resolutionKey) {
_htsSource = htsSource;
_resolutionKey = resolutionKey;
}
@Override
public Result<HistoricalTimeSeriesBundle> getFixingsForSecurity(Environment env, FinancialSecurity security) {
final FixingRetriever retriever = new FixingRetriever(env.getValuationDate());
try {
return security.accept(retriever);
} catch (Exception ex) {
return Result.failure(ex);
}
}
/**
* Class that returns a timeseries bundle of the fixing timeseries required by a security.
*/
private final class FixingRetriever extends FinancialSecurityVisitorAdapter<Result<HistoricalTimeSeriesBundle>> {
/**
* end date of the fixing series required
*/
private final LocalDate _valuationDate;
/**
* @param valuationDate the valuation date
*/
private FixingRetriever(LocalDate valuationDate) {
_valuationDate = valuationDate;
}
/**
* Returns a time series bundle of the previous month's market values for the specified security.
* @param dataField the data field, usually Market_Value
* @param period the period of time to return data for
* @param ids the externalIdBundles to get series for
* @return a historical time series bundle
*/
private Result<HistoricalTimeSeriesBundle> getTimeSeriesBundle(String dataField, LocalDate start, Period period,
ExternalIdBundle... ids) {
final HistoricalTimeSeriesBundle bundle = new HistoricalTimeSeriesBundle();
Result<?> result = Result.success(true);
for (ExternalIdBundle id : ids) {
Result<HistoricalTimeSeries> series = getPreviousPeriodValues(dataField, id, period, start);
if (series.isSuccess()) {
bundle.add(dataField, id, series.getValue());
} else {
result = Result.failure(result, series);
}
}
if (result.isSuccess()) {
return Result.success(bundle);
}
return Result.failure(result);
}
/**
* Returns a time series bundle of the previous month's market values for the specified security.
* @param dataField the data field, usually Market_Value
* @param period the period of time to return data for
* @param ids the externalIdBundles to get series for
* @return a historical time series bundle
*/
private Result<HistoricalTimeSeriesBundle> getTimeSeriesBundle(String dataField, Period period, ExternalIdBundle... ids) {
return getTimeSeriesBundle(dataField, _valuationDate, period, ids);
}
/**
* Returns a time series of the previous periods values for the specified external id
* @param field the name of the value used to lookup.
* @param id the external id of used to lookup the field values.
* @param length the length of time to get values for.
* @param date the date of time to get values for.
* @return the time series result
*/
private Result<HistoricalTimeSeries> getPreviousPeriodValues(String field, ExternalIdBundle id, Period length,
LocalDate date) {
final boolean includeStart = true;
final boolean includeEnd = true;
LocalDate periodStartDate = (date.isBefore(_valuationDate) ? date : _valuationDate).minus(length);
LocalDate periodEndDate = date.isAfter(_valuationDate) ? date : _valuationDate;
return getHistoricalTimeSeriesResult(field, id, _resolutionKey, periodStartDate,
includeStart, periodEndDate, includeEnd);
}
@Override
public Result<HistoricalTimeSeriesBundle> visitFederalFundsFutureSecurity(FederalFundsFutureSecurity security) {
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, ONE_MONTH,
security.getExternalIdBundle(), security.getUnderlyingId().toBundle());
}
@Override
public Result<HistoricalTimeSeriesBundle> visitInterestRateFutureSecurity(InterestRateFutureSecurity security) {
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, ONE_MONTH, security.getExternalIdBundle());
}
@Override
public Result<HistoricalTimeSeriesBundle> visitIRFutureOptionSecurity(IRFutureOptionSecurity security) {
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, ONE_MONTH, security.getExternalIdBundle());
}
@Override
public Result<HistoricalTimeSeriesBundle> visitSwaptionSecurity(SwaptionSecurity security) {
if (security.getCurrency().equals(Currency.BRL)) {
throw new UnsupportedOperationException("Fixing series for Brazilian swaptions not yet implemented");
}
return Result.success(EMPTY_TIME_SERIES_BUNDLE);
}
@Override
public Result<HistoricalTimeSeriesBundle> visitBondFutureSecurity(BondFutureSecurity security) {
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, ONE_MONTH, security.getExternalIdBundle());
}
@Override
public Result<HistoricalTimeSeriesBundle> visitDeliverableSwapFutureSecurity(DeliverableSwapFutureSecurity security) {
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, ONE_MONTH, security.getExternalIdBundle());
}
@Override
public Result<HistoricalTimeSeriesBundle> visitBondFutureOptionSecurity(BondFutureOptionSecurity security) {
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, ONE_MONTH, security.getExternalIdBundle());
}
@Override
public Result<HistoricalTimeSeriesBundle> visitInterestRateSwapSecurity(final InterestRateSwapSecurity security) {
Collection<ExternalIdBundle> ids = new ArrayList<>();
for (final FloatingInterestRateSwapLeg leg : security.getLegs(FloatingInterestRateSwapLeg.class)) {
ExternalId id = leg.getFloatingReferenceRateId();
ids.add(id.toBundle());
}
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, security.getEffectiveDate(),
Period.ofYears(1), ids.toArray(new ExternalIdBundle[ids.size()]));
}
@Override
public Result<HistoricalTimeSeriesBundle> visitForwardRateAgreementSecurity(
final ForwardRateAgreementSecurity security) {
ForwardRateAgreementSecurity fra = (ForwardRateAgreementSecurity) security;
ExternalIdBundle id = fra.getUnderlyingId().toBundle();
PeriodFrequency period = PeriodFrequency.convertToPeriodFrequency(fra.getIndexFrequency());
return getTimeSeriesBundle(MarketDataRequirementNames.MARKET_VALUE, period.getPeriod(), id);
}
}
/**
* Wraps the timeseries call and return a Result
* @param field the field
* @param id the id
* @param resolutionKey the resolution key
* @param startDate the start date
* @param includeStart should include start
* @param endDate the end date
* @param includeEnd should include end
* @return the time series Result
*/
private Result<HistoricalTimeSeries> getHistoricalTimeSeriesResult(String field, ExternalIdBundle id, String resolutionKey, LocalDate startDate,
boolean includeStart, LocalDate endDate, boolean includeEnd) {
HistoricalTimeSeries series = _htsSource.getHistoricalTimeSeries(field, id, resolutionKey, startDate, includeStart, endDate, includeEnd);
if (series != null) {
if (series.getTimeSeries().isEmpty()) {
return Result.failure(FailureStatus.MISSING_DATA, "Time series for {} is empty", id);
} else {
return Result.success(series);
}
}
return Result.failure(FailureStatus.MISSING_DATA, "Couldn't get time series for {}", id);
}
}