/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.curve;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.DataNotFoundException;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.instrument.InstrumentDefinition;
import com.opengamma.analytics.financial.instrument.cash.CashDefinition;
import com.opengamma.analytics.financial.instrument.cash.DepositIborDefinition;
import com.opengamma.analytics.financial.schedule.ScheduleCalculator;
import com.opengamma.core.convention.ConventionSource;
import com.opengamma.core.holiday.HolidaySource;
import com.opengamma.core.link.ConventionLink;
import com.opengamma.core.link.SecurityLink;
import com.opengamma.core.marketdatasnapshot.SnapshotDataBundle;
import com.opengamma.core.region.RegionSource;
import com.opengamma.core.security.SecuritySource;
import com.opengamma.financial.analytics.conversion.CalendarUtils;
import com.opengamma.financial.analytics.ircurve.strips.CashNode;
import com.opengamma.financial.convention.DepositConvention;
import com.opengamma.financial.convention.IborIndexConvention;
import com.opengamma.financial.convention.businessday.BusinessDayConvention;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.financial.security.index.IborIndex;
import com.opengamma.id.ExternalId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
import com.opengamma.util.time.Tenor;
/**
* Convert a cash node into an Instrument definition.
* The dates of the deposits are computed in the following way:
* - The spot date is computed from the valuation date adding the "Settlement Days"
* (i.e. the number of business days) of the convention.
* - The start date is computed from the spot date adding the "StartTenor" of the node
* and using the business-day-convention, calendar and EOM of the convention.
* - The end date is computed from the start date adding the "MaturityTenor" of the
* node and using the business-day-convention, calendar and EOM of the convention.
* The deposit notional is 1.
*/
public class CashNodeConverter extends CurveNodeVisitorAdapter<InstrumentDefinition<?>> {
/** The holiday source */
private final HolidaySource _holidaySource;
/** The region source */
private final RegionSource _regionSource;
/** The market data */
private final SnapshotDataBundle _marketData;
/** The market data id */
private final ExternalId _dataId;
/** The valuation time */
private final ZonedDateTime _valuationTime;
/**
* @param securitySource The security source, not required
* @param conventionSource The convention source, not required
* @param holidaySource The holiday source, not null
* @param regionSource The region source, not null
* @param marketData The market data, not null
* @param dataId The id of the market data, not null
* @param valuationTime The valuation time, not null
* @deprecated use constructor without securitySource and conventionSource
*/
@Deprecated
public CashNodeConverter(
SecuritySource securitySource,
ConventionSource conventionSource,
HolidaySource holidaySource,
RegionSource regionSource,
SnapshotDataBundle marketData,
ExternalId dataId,
ZonedDateTime valuationTime) {
this(holidaySource, regionSource, marketData, dataId, valuationTime);
}
public CashNodeConverter(
HolidaySource holidaySource,
RegionSource regionSource,
SnapshotDataBundle marketData,
ExternalId dataId,
ZonedDateTime valuationTime) {
_holidaySource = ArgumentChecker.notNull(holidaySource, "holidaySource");
_regionSource = ArgumentChecker.notNull(regionSource, "regionSource");
_marketData = ArgumentChecker.notNull(marketData, "marketData");
_dataId = ArgumentChecker.notNull(dataId, "dataId");
_valuationTime = ArgumentChecker.notNull(valuationTime, "valuationTime");
}
@Override
public InstrumentDefinition<?> visitCashNode(CashNode cashNode) {
Tenor startTenor = cashNode.getStartTenor();
Tenor maturityTenor = cashNode.getMaturityTenor();
Double rate = _marketData.getDataPoint(_dataId);
if (rate == null) {
throw new OpenGammaRuntimeException("Could not get market data for " + _dataId);
}
// Deposit
try {
DepositConvention depositConvention =
ConventionLink.resolvable(cashNode.getConvention(), DepositConvention.class).resolve();
Currency currency = depositConvention.getCurrency();
Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, depositConvention.getRegionCalendar());
BusinessDayConvention businessDayConvention = depositConvention.getBusinessDayConvention();
boolean isEOM = depositConvention.isIsEOM();
DayCount dayCount = depositConvention.getDayCount();
int settlementDays = depositConvention.getSettlementDays();
ZonedDateTime spotDate = ScheduleCalculator.getAdjustedDate(_valuationTime, settlementDays, calendar);
ZonedDateTime startDate =
ScheduleCalculator.getAdjustedDate(spotDate, startTenor, businessDayConvention, calendar, isEOM);
ZonedDateTime endDate =
ScheduleCalculator.getAdjustedDate(startDate, maturityTenor, businessDayConvention, calendar, isEOM);
double accrualFactor = dayCount.getDayCountFraction(startDate, endDate);
return new CashDefinition(currency, startDate, endDate, 1, rate, accrualFactor);
} catch (DataNotFoundException e) {
// If the convention is not found in the convention source
// then try with the security source.
IborIndex indexSecurity = SecurityLink.resolvable(cashNode.getConvention().toBundle(), IborIndex.class).resolve();
IborIndexConvention indexConvention =
ConventionLink.resolvable(indexSecurity.getConventionId(), IborIndexConvention.class).resolve();
Currency currency = indexConvention.getCurrency();
Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, indexConvention.getRegionCalendar());
BusinessDayConvention businessDayConvention = indexConvention.getBusinessDayConvention();
boolean isEOM = indexConvention.isIsEOM();
DayCount dayCount = indexConvention.getDayCount();
int settlementDays = indexConvention.getSettlementDays();
ZonedDateTime spotDate = ScheduleCalculator.getAdjustedDate(_valuationTime, settlementDays, calendar);
ZonedDateTime startDate =
ScheduleCalculator.getAdjustedDate(spotDate, startTenor, businessDayConvention, calendar, isEOM);
ZonedDateTime endDate =
ScheduleCalculator.getAdjustedDate(startDate, maturityTenor, businessDayConvention, calendar, isEOM);
double accrualFactor = dayCount.getDayCountFraction(startDate, endDate);
com.opengamma.analytics.financial.instrument.index.IborIndex index =
ConverterUtils.indexIbor(indexSecurity.getName(), indexConvention, indexSecurity.getTenor());
return new DepositIborDefinition(currency, startDate, endDate, 1, rate, accrualFactor, index);
}
}
}