private FRASecurity getFRA(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues, final Tenor tenor) {
final ExternalId fraIdentifier = strip.getSecurity();
final int months = tenor.getPeriod().getMonths();
final ExternalId underlyingId = getUnderlyingId(spec, strip);
Period fraPeriod;
final Currency ccy = spec.getCurrency();
BusinessDayConvention businessDayConvention;
boolean eom;
Calendar calendar;
ExternalId underlyingIdentifier;
int settlementDays;
if (underlyingId == null) {
s_logger.info("Could not get convention for underlying from {}; trying tenor-based convention", strip);
final ConventionBundle fraConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months
+ "M_FRA"));
if (fraConvention == null) {
throw new OpenGammaRuntimeException("Could not get convention for " + fraIdentifier + ": tried "
+ ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months + "M_FRA"));
}
underlyingIdentifier = fraConvention.getSwapFloatingLegInitialRate();
final ConventionBundle iborConvention = _conventionBundleSource.getConventionBundle(underlyingIdentifier);
underlyingIdentifier = fraConvention.getSwapFloatingLegInitialRate();
fraPeriod = iborConvention.getPeriod();
businessDayConvention = iborConvention.getBusinessDayConvention();
eom = iborConvention.isEOMConvention();
calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, fraConvention.getSwapFloatingLegRegion());
settlementDays = iborConvention.getSettlementDays();
} else {
ConventionBundle fraConvention = _conventionBundleSource.getConventionBundle(underlyingId);
if (fraConvention == null || fraConvention.getIdentifiers().size() != 1) {
s_logger.info("Could not get unique convention for underlying from {}; trying tenor-based convention", strip);
fraConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months
+ "M_FRA"));
if (fraConvention == null) {
throw new OpenGammaRuntimeException("Could not get convention for " + fraIdentifier + ": tried "
+ ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months + "M_FRA"));
}
final ConventionBundle iborConvention = _conventionBundleSource.getConventionBundle(fraConvention.getSwapFloatingLegInitialRate());
fraPeriod = iborConvention.getPeriod();
businessDayConvention = fraConvention.getSwapFloatingLegBusinessDayConvention();
eom = fraConvention.isEOMConvention();
calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, fraConvention.getSwapFloatingLegRegion());
underlyingIdentifier = underlyingId;
settlementDays = fraConvention.getSwapFloatingLegSettlementDays();
} else {
fraPeriod = fraConvention.getPeriod();
businessDayConvention = fraConvention.getBusinessDayConvention();
eom = fraConvention.isEOMConvention();
calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, fraConvention.getRegion());
underlyingIdentifier = Iterables.getOnlyElement(fraConvention.getIdentifiers());
settlementDays = fraConvention.getSettlementDays();
}
}
final ZonedDateTime curveDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); // TODO: review?
final ZonedDateTime spotDate = ScheduleCalculator.getAdjustedDate(curveDate, settlementDays, calendar);
final Period endPeriod = strip.getMaturity().getPeriod();
final ZonedDateTime endDate = ScheduleCalculator.getAdjustedDate(spotDate, endPeriod, businessDayConvention, calendar, eom);
final Period startPeriod = endPeriod.minus(fraPeriod).normalized(); // TODO: check period >0?
final ZonedDateTime startDate = ScheduleCalculator.getAdjustedDate(spotDate, startPeriod, businessDayConvention, calendar, eom);
final ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate(startDate, -settlementDays, calendar);
if (marketValues.getDataPoint(strip.getSecurity()) == null) {
throw new OpenGammaRuntimeException("Could not get market data for " + strip);
}