/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.ircurve; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.bp.LocalDate; import org.threeten.bp.LocalTime; import org.threeten.bp.Period; import org.threeten.bp.ZoneId; import org.threeten.bp.ZoneOffset; import org.threeten.bp.ZonedDateTime; import com.google.common.collect.Iterables; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.schedule.ScheduleCalculator; import com.opengamma.core.holiday.HolidaySource; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.core.marketdatasnapshot.SnapshotDataBundle; import com.opengamma.core.region.Region; import com.opengamma.core.region.RegionSource; import com.opengamma.core.security.Security; import com.opengamma.core.security.SecuritySource; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.financial.analytics.conversion.CalendarUtils; import com.opengamma.financial.convention.ConventionBundle; import com.opengamma.financial.convention.ConventionBundleSource; import com.opengamma.financial.convention.InMemoryConventionBundleMaster; 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.convention.frequency.Frequency; import com.opengamma.financial.convention.frequency.PeriodFrequency; import com.opengamma.financial.security.cash.CashSecurity; import com.opengamma.financial.security.deposit.PeriodicZeroDepositSecurity; import com.opengamma.financial.security.fra.FRASecurity; import com.opengamma.financial.security.future.FutureSecurity; import com.opengamma.financial.security.swap.FixedInterestRateLeg; import com.opengamma.financial.security.swap.FloatingInterestRateLeg; import com.opengamma.financial.security.swap.FloatingRateType; import com.opengamma.financial.security.swap.FloatingSpreadIRLeg; import com.opengamma.financial.security.swap.InterestRateNotional; import com.opengamma.financial.security.swap.SwapSecurity; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.util.money.Currency; import com.opengamma.util.time.DateUtils; import com.opengamma.util.time.Tenor; /** * Converts specifications into fully resolved security definitions */ public class FixedIncomeStripIdentifierAndMaturityBuilder { private static final Logger s_logger = LoggerFactory.getLogger(FixedIncomeStripIdentifierAndMaturityBuilder.class); private static final LocalTime CASH_EXPIRY_TIME = LocalTime.of(11, 00); private final RegionSource _regionSource; private final ConventionBundleSource _conventionBundleSource; private final SecuritySource _secSource; private final HolidaySource _holidaySource; // TODO: Don't accept a SecuritySource here; use the ComputationTargetResolver public FixedIncomeStripIdentifierAndMaturityBuilder(final RegionSource regionSource, final ConventionBundleSource conventionBundleSource, final SecuritySource secSource, final HolidaySource holidaySource) { _regionSource = regionSource; _conventionBundleSource = conventionBundleSource; _secSource = secSource; _holidaySource = holidaySource; } public InterpolatedYieldCurveSpecificationWithSecurities resolveToSecurity(final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues) { final Collection<FixedIncomeStripWithSecurity> securityStrips = new TreeSet<>(); final LocalDate curveDate = curveSpecification.getCurveDate(); for (final FixedIncomeStripWithIdentifier strip : curveSpecification.getStrips()) { final InstrumentHandler handler = getInstrumentHandler(strip); final Security security = handler.getSecurity(this, curveSpecification, marketValues, strip); final ZonedDateTime maturity = handler.getMaturity(this, curveDate, strip, security); final Tenor resolvedTenor = Tenor.of(Period.between(curveDate, maturity.toLocalDate())); securityStrips.add(new FixedIncomeStripWithSecurity(strip.getStrip(), resolvedTenor, maturity, strip.getSecurity(), security)); } return new InterpolatedYieldCurveSpecificationWithSecurities(curveDate, curveSpecification.getName(), curveSpecification.getCurrency(), curveSpecification.getInterpolator(), curveSpecification.interpolateYield(), securityStrips); } // TODO: Implement the "getRequirements" methods and use this to make sure that target resolver caches are pre-populated at execution time public Set<ValueRequirement> getResolutionRequirements(final InterpolatedYieldCurveSpecification curveSpecification) { final Set<ValueRequirement> requirements = new HashSet<>(); for (final FixedIncomeStripWithIdentifier strip : curveSpecification.getStrips()) { final InstrumentHandler handler = getInstrumentHandler(strip); requirements.addAll(handler.getRequirements(this, curveSpecification, strip)); } return requirements; } private abstract static class InstrumentHandler { public abstract Security getSecurity(FixedIncomeStripIdentifierAndMaturityBuilder self, InterpolatedYieldCurveSpecification curveSpecification, SnapshotDataBundle marketValues, FixedIncomeStripWithIdentifier strip); public abstract ZonedDateTime getMaturity(FixedIncomeStripIdentifierAndMaturityBuilder self, LocalDate curveDate, FixedIncomeStripWithIdentifier strip, Security security); public abstract Set<ValueRequirement> getRequirements(FixedIncomeStripIdentifierAndMaturityBuilder self, InterpolatedYieldCurveSpecification curveSpecification, FixedIncomeStripWithIdentifier strip); } private static final InstrumentHandler s_cash = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final CashSecurity cashSecurity = self.getCash(curveSpecification, strip, marketValues); if (cashSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve cash curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return cashSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final CashSecurity cashSecurity = (CashSecurity) security; final Region region = self._regionSource.getHighestLevelRegion(cashSecurity.getRegionId()); ZoneId timeZone = region.getTimeZone(); timeZone = ensureZone(timeZone); return curveDate.plus(strip.getMaturity().getPeriod()).atTime(CASH_EXPIRY_TIME).atZone(timeZone); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_fra3m = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final FRASecurity fraSecurity = self.getFRA(curveSpecification, strip, marketValues, Tenor.THREE_MONTHS); if (fraSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve FRA curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return fraSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final FRASecurity fraSecurity = (FRASecurity) security; return fraSecurity.getEndDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_fra6m = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final FRASecurity fraSecurity = self.getFRA(curveSpecification, strip, marketValues, Tenor.SIX_MONTHS); if (fraSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve FRA curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return fraSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final FRASecurity fraSecurity = (FRASecurity) security; return fraSecurity.getEndDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_fra = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final FRASecurity fraSecurity = self.getFRA(curveSpecification, strip, marketValues, Tenor.THREE_MONTHS); if (fraSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve FRA curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return fraSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final FRASecurity fraSecurity = (FRASecurity) security; return fraSecurity.getEndDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_future = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { // TODO: jim 17-Aug-2010 -- we need to sort out the zoned date time related to the expiry. final FutureSecurity futureSecurity = self.getFuture(strip); if (futureSecurity == null) { throw new OpenGammaRuntimeException("Security source did not contain future curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return futureSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final FutureSecurity futureSecurity = (FutureSecurity) security; return futureSecurity.getExpiry().getExpiry().plusMonths(3); //TODO shouldn't hard-code to 3 - find out why comparator in FixedIncomeStrip isn't working properly } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_libor = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final CashSecurity rateSecurity = self.getCash(curveSpecification, strip, marketValues); if (rateSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve Libor curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return rateSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final CashSecurity rateSecurity = (CashSecurity) security; final Region region2 = self._regionSource.getHighestLevelRegion(rateSecurity.getRegionId()); ZoneId timeZone2 = region2.getTimeZone(); timeZone2 = ensureZone(timeZone2); return curveDate.plus(strip.getMaturity().getPeriod()).atTime(CASH_EXPIRY_TIME).atZone(timeZone2); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_euribor = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final CashSecurity rateSecurity = self.getCash(curveSpecification, strip, marketValues); if (rateSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve Euribor curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return rateSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final CashSecurity rateSecurity = (CashSecurity) security; final Region region2 = self._regionSource.getHighestLevelRegion(rateSecurity.getRegionId()); ZoneId timeZone2 = region2.getTimeZone(); timeZone2 = ensureZone(timeZone2); return curveDate.plus(strip.getMaturity().getPeriod()).atTime(CASH_EXPIRY_TIME).atZone(timeZone2); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_cdor = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final CashSecurity rateSecurity = self.getCash(curveSpecification, strip, marketValues); if (rateSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve CDOR curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return rateSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final CashSecurity rateSecurity = (CashSecurity) security; final Region region2 = self._regionSource.getHighestLevelRegion(rateSecurity.getRegionId()); ZoneId timeZone2 = region2.getTimeZone(); timeZone2 = ensureZone(timeZone2); return curveDate.plus(strip.getMaturity().getPeriod()).atTime(CASH_EXPIRY_TIME).atZone(timeZone2); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_cibor = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final CashSecurity rateSecurity = self.getCash(curveSpecification, strip, marketValues); if (rateSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve CIBOR curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return rateSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final CashSecurity rateSecurity = (CashSecurity) security; final Region region2 = self._regionSource.getHighestLevelRegion(rateSecurity.getRegionId()); ZoneId timeZone2 = region2.getTimeZone(); timeZone2 = ensureZone(timeZone2); return curveDate.plus(strip.getMaturity().getPeriod()).atTime(CASH_EXPIRY_TIME).atZone(timeZone2); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_stibor = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final CashSecurity rateSecurity = self.getCash(curveSpecification, strip, marketValues); if (rateSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve STIBOR curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return rateSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final CashSecurity rateSecurity = (CashSecurity) security; final Region region2 = self._regionSource.getHighestLevelRegion(rateSecurity.getRegionId()); ZoneId timeZone2 = region2.getTimeZone(); timeZone2 = ensureZone(timeZone2); return curveDate.plus(strip.getMaturity().getPeriod()).atTime(CASH_EXPIRY_TIME).atZone(timeZone2); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_swap = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { // In case there's any old curve definitions hanging around - assume that all swaps are 3m // TODO get defaults from convention? (e.g. USD = 3m, EUR = 6M) final SwapSecurity swapSecurity = self.getSwap(curveSpecification, strip, marketValues, Tenor.THREE_MONTHS); if (swapSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve swap curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return swapSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final SwapSecurity swapSecurity = (SwapSecurity) security; return swapSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_swap3m = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final SwapSecurity swapSecurity = self.getSwap(curveSpecification, strip, marketValues, Tenor.THREE_MONTHS); if (swapSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve swap curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return swapSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final SwapSecurity swapSecurity = (SwapSecurity) security; return swapSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_swap6m = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final SwapSecurity swapSecurity = self.getSwap(curveSpecification, strip, marketValues, Tenor.SIX_MONTHS); if (swapSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve swap curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return swapSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final SwapSecurity swapSecurity = (SwapSecurity) security; return swapSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_swap12m = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final SwapSecurity swapSecurity = self.getSwap(curveSpecification, strip, marketValues, Tenor.ONE_YEAR); if (swapSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve swap curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return swapSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final SwapSecurity swapSecurity = (SwapSecurity) security; return swapSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_swap28d = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final SwapSecurity swapSecurity = self.get28DaySwap(curveSpecification, strip, marketValues); if (swapSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve swap curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return swapSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final SwapSecurity swapSecurity = (SwapSecurity) security; return swapSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_tenorSwap = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final SwapSecurity tenorSwapSecurity = self.getTenorSwap(curveSpecification, strip, marketValues); if (tenorSwapSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve swap curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return tenorSwapSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final SwapSecurity tenorSwapSecurity = (SwapSecurity) security; return tenorSwapSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_oisSwap = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { return self.getOISSwap(curveSpecification, strip, marketValues); } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { return curveDate.plus(strip.getMaturity().getPeriod()).atTime(11, 00).atZone(ZoneOffset.UTC); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_periodicZeroDeposit = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final PeriodicZeroDepositSecurity depositSecurity = getPeriodicZeroDeposit(curveSpecification, strip, marketValues); return depositSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final PeriodicZeroDepositSecurity depositSecurity = (PeriodicZeroDepositSecurity) security; return depositSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static final InstrumentHandler s_basisSwap = new InstrumentHandler() { @Override public Security getSecurity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final SnapshotDataBundle marketValues, final FixedIncomeStripWithIdentifier strip) { final SwapSecurity basisSwapSecurity = self.getBasisSwap(curveSpecification, strip, marketValues); if (basisSwapSecurity == null) { throw new OpenGammaRuntimeException("Could not resolve basis swap curve instrument " + strip.getSecurity() + " from strip " + strip + " in " + curveSpecification); } return basisSwapSecurity; } @Override public ZonedDateTime getMaturity(final FixedIncomeStripIdentifierAndMaturityBuilder self, final LocalDate curveDate, final FixedIncomeStripWithIdentifier strip, final Security security) { final SwapSecurity basisSwapSecurity = (SwapSecurity) security; return basisSwapSecurity.getMaturityDate(); } @Override public Set<ValueRequirement> getRequirements(final FixedIncomeStripIdentifierAndMaturityBuilder self, final InterpolatedYieldCurveSpecification curveSpecification, final FixedIncomeStripWithIdentifier strip) { // TODO: Implement this throw new UnsupportedOperationException("TODO"); } }; private static InstrumentHandler getInstrumentHandler(final FixedIncomeStripWithIdentifier strip) { switch (strip.getInstrumentType()) { case CASH: return s_cash; case FRA_3M: return s_fra3m; case FRA_6M: return s_fra6m; case FRA: return s_fra; case FUTURE: return s_future; case LIBOR: return s_libor; case EURIBOR: return s_euribor; case CDOR: return s_cdor; case CIBOR: return s_cibor; case STIBOR: return s_stibor; case SWAP: return s_swap; case SWAP_3M: return s_swap3m; case SWAP_6M: return s_swap6m; case SWAP_12M: return s_swap12m; case SWAP_28D: return s_swap28d; case TENOR_SWAP: return s_tenorSwap; case OIS_SWAP: return s_oisSwap; case PERIODIC_ZERO_DEPOSIT: return s_periodicZeroDeposit; case BASIS_SWAP: return s_basisSwap; default: throw new OpenGammaRuntimeException("Unhandled type of instrument in curve definition " + strip.getInstrumentType()); } } private CashSecurity getCash(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues) { final ConventionBundle cashConvention = _conventionBundleSource.getConventionBundle(strip.getSecurity()); if (cashConvention == null) { throw new OpenGammaRuntimeException("No convention for cash " + strip.getSecurity() + " so can't establish business day convention"); } if (cashConvention.getRegion() == null) { throw new OpenGammaRuntimeException("Region for strip " + strip + " was null"); } final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, cashConvention.getRegion()); if (calendar == null) { throw new OpenGammaRuntimeException("Calendar was null"); } final ZonedDateTime curveDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); final ZonedDateTime startDate = ScheduleCalculator.getAdjustedDate(curveDate, cashConvention.getSettlementDays(), calendar); final ZonedDateTime endDate = ScheduleCalculator.getAdjustedDate(startDate, cashConvention.getPeriod(), cashConvention.getBusinessDayConvention(), calendar, cashConvention.isEOMConvention()); final Double rate = marketValues.getDataPoint(strip.getSecurity()); if (rate == null) { throw new OpenGammaRuntimeException("No market data for " + strip.getSecurity()); } final CashSecurity sec = new CashSecurity(spec.getCurrency(), spec.getRegion(), startDate, endDate, cashConvention.getDayCount(), rate, 1.0d); sec.setExternalIdBundle(ExternalIdBundle.of(strip.getSecurity())); return sec; } 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); } return new FRASecurity(ccy, spec.getRegion(), startDate, endDate, marketValues.getDataPoint(strip.getSecurity()), 1.0d, underlyingIdentifier, fixingDate); } private FutureSecurity getFuture(final FixedIncomeStripWithIdentifier strip) { return (FutureSecurity) _secSource.getSingle(ExternalIdBundle.of(strip.getSecurity())); } private SwapSecurity getSwap(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues, final Tenor resetTenor) { if (spec.getCurrency().equals(Currency.BRL)) { return getBRLSwap(spec, strip, marketValues); } final ExternalId swapIdentifier = strip.getSecurity(); final Double rate = marketValues.getDataPoint(swapIdentifier); if (rate == null) { throw new OpenGammaRuntimeException("No market data for " + swapIdentifier); } final long months = resetTenor.getPeriod().toTotalMonths(); final ConventionBundle fixedLegConvention = getFixedLegConvention(spec, strip, swapIdentifier); final ZonedDateTime curveDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); final String counterparty = ""; Calendar calendar; ExternalId floatingRateId; FloatingInterestRateLeg iborLeg; final ExternalId underlyingId = getUnderlyingId(spec, strip); if (underlyingId == null) { s_logger.info("Could not get convention for underlying from {}; trying tenor-based convention", strip); final ExternalId id = ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months + "M_SWAP"); ConventionBundle floatingLegConvention = _conventionBundleSource.getConventionBundle(id); if (floatingLegConvention == null) { floatingLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months + "_SWAP")); if (floatingLegConvention == null) { throw new OpenGammaRuntimeException("Could not get floating leg convention for swap strip " + strip); } } calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, floatingLegConvention.getSwapFloatingLegRegion()); floatingRateId = floatingLegConvention.getSwapFloatingLegInitialRate(); if (floatingRateId == null) { throw new OpenGammaRuntimeException("Could not get floating rate id from convention"); } iborLeg = new FloatingInterestRateLeg(floatingLegConvention.getSwapFloatingLegDayCount(), floatingLegConvention.getSwapFloatingLegFrequency(), floatingLegConvention.getSwapFloatingLegRegion(), floatingLegConvention.getSwapFloatingLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, floatingRateId, FloatingRateType.IBOR); } else { final ConventionBundle underlyingConvention = _conventionBundleSource.getConventionBundle(underlyingId); if (underlyingConvention == null || underlyingConvention.getIdentifiers().size() != 1) { s_logger.info("Could not get unique convention for underlying from {}; trying tenor-based convention", strip); ConventionBundle floatingLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months + "M_SWAP")); if (floatingLegConvention == null) { floatingLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_" + months + "_SWAP")); if (floatingLegConvention == null) { throw new OpenGammaRuntimeException("Could not get floating leg convention for swap strip " + strip); } } calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, floatingLegConvention.getSwapFloatingLegRegion()); floatingRateId = floatingLegConvention.getSwapFloatingLegInitialRate(); if (floatingRateId == null) { throw new OpenGammaRuntimeException("Could not get floating rate id from convention"); } iborLeg = new FloatingInterestRateLeg(floatingLegConvention.getSwapFloatingLegDayCount(), floatingLegConvention.getSwapFloatingLegFrequency(), floatingLegConvention.getSwapFloatingLegRegion(), floatingLegConvention.getSwapFloatingLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, floatingRateId, FloatingRateType.IBOR); } else { calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, underlyingConvention.getRegion()); final ExternalId underlyingTicker = Iterables.getOnlyElement(underlyingConvention.getIdentifiers()); iborLeg = new FloatingInterestRateLeg(underlyingConvention.getDayCount(), PeriodFrequency.of(underlyingConvention.getPeriod()), underlyingConvention.getRegion(), underlyingConvention.getBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, underlyingTicker, FloatingRateType.IBOR); } } final ZonedDateTime spotDate = ScheduleCalculator.getAdjustedDate(curveDate, fixedLegConvention.getSwapFixedLegSettlementDays(), calendar); final ZonedDateTime maturityDate = spotDate.plus(strip.getMaturity().getPeriod()); final FixedInterestRateLeg fixedLeg = new FixedInterestRateLeg(fixedLegConvention.getSwapFixedLegDayCount(), fixedLegConvention.getSwapFixedLegFrequency(), fixedLegConvention.getSwapFixedLegRegion(), fixedLegConvention.getSwapFixedLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, rate); final SwapSecurity swap = new SwapSecurity(curveDate, spotDate, maturityDate, counterparty, iborLeg, fixedLeg); swap.setExternalIdBundle(ExternalIdBundle.of(swapIdentifier)); return swap; } private SwapSecurity getBRLSwap(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues) { final ExternalId swapIdentifier = strip.getSecurity(); final Double rate = marketValues.getDataPoint(swapIdentifier); if (rate == null) { throw new OpenGammaRuntimeException("No market data for " + swapIdentifier); } final ZonedDateTime curveDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); final ConventionBundle convention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, "BRL_DI_SWAP")); final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, convention.getSwapFloatingLegRegion()); final ZonedDateTime spotDate = ScheduleCalculator.getAdjustedDate(curveDate, convention.getSwapFixedLegSettlementDays(), calendar); final ZonedDateTime maturityDate = spotDate.plus(strip.getMaturity().getPeriod()); final FixedInterestRateLeg fixedLeg = new FixedInterestRateLeg(convention.getSwapFixedLegDayCount(), convention.getSwapFixedLegFrequency(), convention.getSwapFixedLegRegion(), convention.getSwapFixedLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, rate); final FloatingInterestRateLeg iborLeg = new FloatingInterestRateLeg(convention.getSwapFloatingLegDayCount(), convention.getSwapFloatingLegFrequency(), convention.getSwapFloatingLegRegion(), convention.getSwapFloatingLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, convention.getSwapFloatingLegInitialRate(), FloatingRateType.OIS); //convention type is wrong but it's ignored in the converter anyway. final String counterparty = ""; final SwapSecurity swap = new SwapSecurity(curveDate, spotDate, maturityDate, counterparty, iborLeg, fixedLeg); swap.setExternalIdBundle(ExternalIdBundle.of(swapIdentifier)); return swap; } private SwapSecurity get28DaySwap(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues) { final ExternalId swapIdentifier = strip.getSecurity(); final Double rate = marketValues.getDataPoint(swapIdentifier); if (rate == null) { throw new OpenGammaRuntimeException("No market data for " + swapIdentifier); } final ConventionBundle fixedLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_28D_SWAP")); if (fixedLegConvention == null) { throw new OpenGammaRuntimeException("Could not get fixed leg convention for " + swapIdentifier); } final ZonedDateTime curveDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); final String counterparty = ""; Calendar calendar; ExternalId floatingRateId; FloatingInterestRateLeg iborLeg; final ExternalId underlyingId = getUnderlyingId(spec, strip); if (underlyingId == null) { s_logger.info("Could not get convention for underlying from {}; trying tenor-based convention", strip); final ExternalId id = ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_28D_SWAP"); final ConventionBundle floatingLegConvention = _conventionBundleSource.getConventionBundle(id); if (floatingLegConvention == null) { throw new OpenGammaRuntimeException("Could not get floating leg convention for swap strip " + strip); } calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, floatingLegConvention.getSwapFloatingLegRegion()); floatingRateId = floatingLegConvention.getSwapFloatingLegInitialRate(); if (floatingRateId == null) { throw new OpenGammaRuntimeException("Could not get floating rate id from convention"); } iborLeg = new FloatingInterestRateLeg(floatingLegConvention.getSwapFloatingLegDayCount(), floatingLegConvention.getSwapFloatingLegFrequency(), floatingLegConvention.getSwapFloatingLegRegion(), floatingLegConvention.getSwapFloatingLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, floatingRateId, FloatingRateType.IBOR); } else { final ConventionBundle underlyingConvention = _conventionBundleSource.getConventionBundle(underlyingId); if (underlyingConvention == null || underlyingConvention.getIdentifiers().size() != 1) { s_logger.info("Could not get unique convention for underlying from {}; trying tenor-based convention", strip); final ConventionBundle floatingLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_28D_SWAP")); if (floatingLegConvention == null) { throw new OpenGammaRuntimeException("Could not get floating leg convention for swap strip " + strip); } calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, floatingLegConvention.getSwapFloatingLegRegion()); floatingRateId = floatingLegConvention.getSwapFloatingLegInitialRate(); if (floatingRateId == null) { throw new OpenGammaRuntimeException("Could not get floating rate id from convention"); } iborLeg = new FloatingInterestRateLeg(floatingLegConvention.getSwapFloatingLegDayCount(), floatingLegConvention.getSwapFloatingLegFrequency(), floatingLegConvention.getSwapFloatingLegRegion(), floatingLegConvention.getSwapFloatingLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, floatingRateId, FloatingRateType.IBOR); } else { calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, underlyingConvention.getRegion()); final ExternalId underlyingTicker = Iterables.getOnlyElement(underlyingConvention.getIdentifiers()); iborLeg = new FloatingInterestRateLeg(underlyingConvention.getDayCount(), PeriodFrequency.of(underlyingConvention.getPeriod()), underlyingConvention.getRegion(), underlyingConvention.getBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, underlyingTicker, FloatingRateType.IBOR); } } final ZonedDateTime spotDate = ScheduleCalculator.getAdjustedDate(curveDate, fixedLegConvention.getSwapFixedLegSettlementDays(), calendar); final ZonedDateTime maturityDate = spotDate.plus(strip.getMaturity().getPeriod()); final FixedInterestRateLeg fixedLeg = new FixedInterestRateLeg(fixedLegConvention.getSwapFixedLegDayCount(), fixedLegConvention.getSwapFixedLegFrequency(), fixedLegConvention.getSwapFixedLegRegion(), fixedLegConvention.getSwapFixedLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, rate); final SwapSecurity swap = new SwapSecurity(curveDate, spotDate, maturityDate, counterparty, iborLeg, fixedLeg); swap.setExternalIdBundle(ExternalIdBundle.of(swapIdentifier)); return swap; } private SwapSecurity getBasisSwap(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues) { final ExternalId swapIdentifier = strip.getSecurity(); final ZonedDateTime curveDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); final FixedIncomeStrip fixedIncomeStrip = strip.getStrip(); final IndexType payIndexType = fixedIncomeStrip.getPayIndexType(); final Tenor payTenor = fixedIncomeStrip.getPayTenor(); final IndexType receiveIndexType = fixedIncomeStrip.getReceiveIndexType(); final Tenor receiveTenor = fixedIncomeStrip.getReceiveTenor(); final String ccy = spec.getCurrency().getCode(); final ExternalId payFloatingReferenceRateId = ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, payIndexType + "_" + ccy + "_" + payTenor.getPeriod().toString()); final ExternalId receiveFloatingReferenceRateId = ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, receiveIndexType + "_" + ccy + "_" + receiveTenor.getPeriod().toString()); final ConventionBundle payConvention = _conventionBundleSource.getConventionBundle(payFloatingReferenceRateId); final ConventionBundle receiveConvention = _conventionBundleSource.getConventionBundle(receiveFloatingReferenceRateId); final Calendar payCalendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, payConvention.getRegion()); final ZonedDateTime paySpotDate = ScheduleCalculator.getAdjustedDate(curveDate, payConvention.getSettlementDays(), payCalendar); final ZonedDateTime payMaturityDate = paySpotDate.plus(strip.getMaturity().getPeriod()); final String counterparty = ""; final InterestRateNotional notional = new InterestRateNotional(spec.getCurrency(), 1); final ExternalId payRegionIdentifier = payConvention.getRegion(); final DayCount payDayCount = payConvention.getDayCount(); final Frequency payFrequency = PeriodFrequency.of(fixedIncomeStrip.getPayTenor().getPeriod()); final BusinessDayConvention payBusinessDayConvention = payConvention.getBusinessDayConvention(); final FloatingRateType payFloatingRateType = getFloatingTypeFromIndexType(fixedIncomeStrip.getPayIndexType()); final ExternalId receiveRegionIdentifier = receiveConvention.getRegion(); final DayCount receiveDayCount = receiveConvention.getDayCount(); final Frequency receiveFrequency = PeriodFrequency.of(fixedIncomeStrip.getReceiveTenor().getPeriod()); final BusinessDayConvention receiveBusinessDayConvention = receiveConvention.getBusinessDayConvention(); final FloatingRateType receiveFloatingRateType = getFloatingTypeFromIndexType(fixedIncomeStrip.getReceiveIndexType()); final double spread = marketValues.getDataPoint(swapIdentifier); // Implementation note: By convention the spread is on the first leg (shorter tenor) final FloatingSpreadIRLeg payLeg = new FloatingSpreadIRLeg(payDayCount, payFrequency, payRegionIdentifier, payBusinessDayConvention, notional, false, payFloatingReferenceRateId, payFloatingRateType, spread); final FloatingInterestRateLeg receiveLeg = new FloatingInterestRateLeg(receiveDayCount, receiveFrequency, receiveRegionIdentifier, receiveBusinessDayConvention, notional, false, receiveFloatingReferenceRateId, receiveFloatingRateType); //TODO don't use pay spot date and maturity date automatically final SwapSecurity swap = new SwapSecurity(curveDate, paySpotDate, payMaturityDate, counterparty, payLeg, receiveLeg); swap.setExternalIdBundle(ExternalIdBundle.of(swapIdentifier)); return swap; } private SwapSecurity getTenorSwap(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues) { final ExternalId swapIdentifier = strip.getSecurity(); final Double rate = marketValues.getDataPoint(swapIdentifier); final LocalDate curveDate = spec.getCurveDate(); final ZonedDateTime tradeDate = curveDate.atTime(11, 00).atZone(ZoneOffset.UTC); final ZonedDateTime effectiveDate = DateUtils.previousWeekDay(curveDate.plusDays(3)).atTime(11, 00).atZone(ZoneOffset.UTC); final ZonedDateTime maturityDate = curveDate.plus(strip.getMaturity().getPeriod()).atTime(11, 00).atZone(ZoneOffset.UTC); final ConventionBundle convention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_TENOR_SWAP")); final String counterparty = ""; final ConventionBundle payLegFloatRateConvention = _conventionBundleSource.getConventionBundle(convention.getBasisSwapPayFloatingLegInitialRate()); final ConventionBundle receiveLegFloatRateConvention = _conventionBundleSource.getConventionBundle(convention.getBasisSwapReceiveFloatingLegInitialRate()); final ExternalId payLegFloatRateBloombergTicker = payLegFloatRateConvention.getIdentifiers().getExternalId(ExternalSchemes.BLOOMBERG_TICKER); final ExternalId receiveLegFloatRateBloombergTicker = receiveLegFloatRateConvention.getIdentifiers().getExternalId(ExternalSchemes.BLOOMBERG_TICKER); if (rate == null) { throw new OpenGammaRuntimeException("Could not get spread; was trying " + swapIdentifier); } final double spread = rate; // REVIEW: jim 25-Aug-2010 -- we need to change the swap to take settlement days. final SwapSecurity swap = new SwapSecurity(tradeDate, effectiveDate, maturityDate, counterparty, new FloatingInterestRateLeg(convention.getBasisSwapPayFloatingLegDayCount(), convention.getBasisSwapPayFloatingLegFrequency(), convention.getBasisSwapPayFloatingLegRegion(), convention.getBasisSwapPayFloatingLegBusinessDayConvention(), new InterestRateNotional( spec.getCurrency(), 1), false, payLegFloatRateBloombergTicker, FloatingRateType.IBOR), new FloatingSpreadIRLeg(convention.getBasisSwapReceiveFloatingLegDayCount(), convention.getBasisSwapReceiveFloatingLegFrequency(), convention.getBasisSwapReceiveFloatingLegRegion(), convention.getBasisSwapReceiveFloatingLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, receiveLegFloatRateBloombergTicker, FloatingRateType.IBOR, spread)); swap.setExternalIdBundle(ExternalIdBundle.of(swapIdentifier)); return swap; } private SwapSecurity getOISSwap(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues) { final FixedIncomeStrip underlyingStrip = strip.getStrip(); final ExternalId swapIdentifier = strip.getSecurity(); final ConventionBundle swapConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_OIS_SWAP")); if (swapConvention == null) { throw new OpenGammaRuntimeException("Could not get convention for id " + ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_OIS_SWAP")); } if (!swapConvention.getSwapFloatingLegFrequency().equals(swapConvention.getSwapFixedLegFrequency())) { throw new OpenGammaRuntimeException("Payment frequencies for the fixed and floating legs did not match"); } final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, swapConvention.getSwapFloatingLegRegion()); final ZonedDateTime curveDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); final ZonedDateTime spotDate = ScheduleCalculator.getAdjustedDate(curveDate, swapConvention.getSwapFixedLegSettlementDays(), calendar); final ZonedDateTime maturityDate = spotDate.plus(strip.getMaturity().getPeriod()); final String counterparty = ""; final Double rate = marketValues.getDataPoint(swapIdentifier); if (rate == null) { throw new OpenGammaRuntimeException("rate was null on " + strip + " from " + spec); } Frequency floatingFrequency; final ExternalId floatingReferenceRateId; if (underlyingStrip.getResetTenor() != null) { final Period resetTenor = underlyingStrip.getResetTenor().getPeriod(); floatingFrequency = PeriodFrequency.of(resetTenor); final IndexType indexType = underlyingStrip.getIndexType(); floatingReferenceRateId = ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, indexType + "_" + resetTenor.toString()); } else { floatingFrequency = swapConvention.getSwapFloatingLegFrequency(); if (floatingFrequency == null) { throw new OpenGammaRuntimeException("Could not get floating leg frequency from convention"); } floatingReferenceRateId = swapConvention.getSwapFloatingLegInitialRate(); if (floatingReferenceRateId == null) { throw new OpenGammaRuntimeException("Could not get floating reference rate from convention"); } } final FloatingInterestRateLeg oisLeg = new FloatingInterestRateLeg(swapConvention.getSwapFloatingLegDayCount(), floatingFrequency, swapConvention.getSwapFloatingLegRegion(), swapConvention.getSwapFloatingLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, floatingReferenceRateId, FloatingRateType.OIS); final FixedInterestRateLeg fixedLeg = new FixedInterestRateLeg(swapConvention.getSwapFixedLegDayCount(), swapConvention.getSwapFixedLegFrequency(), swapConvention.getSwapFixedLegRegion(), swapConvention.getSwapFixedLegBusinessDayConvention(), new InterestRateNotional(spec.getCurrency(), 1), false, rate); final SwapSecurity swap = new SwapSecurity(curveDate, spotDate, maturityDate, counterparty, oisLeg, fixedLeg); swap.setExternalIdBundle(ExternalIdBundle.of(swapIdentifier)); return swap; } private static PeriodicZeroDepositSecurity getPeriodicZeroDeposit(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final SnapshotDataBundle marketValues) { final ExternalId id = strip.getSecurity(); final Currency currency = spec.getCurrency(); final ZonedDateTime startDate = spec.getCurveDate().atStartOfDay(ZoneOffset.UTC); final ZonedDateTime maturityDate = startDate.plus(strip.getMaturity().getPeriod()); final double rate = marketValues.getDataPoint(id); final int compoundingPeriodsPerYear = strip.getStrip().getPeriodsPerYear(); final ExternalId region = spec.getRegion(); final PeriodicZeroDepositSecurity deposit = new PeriodicZeroDepositSecurity(currency, startDate, maturityDate, rate, compoundingPeriodsPerYear, region); deposit.setExternalIdBundle(ExternalIdBundle.of(id)); return deposit; } private static ZoneId ensureZone(final ZoneId zone) { if (zone != null) { return zone; } return ZoneOffset.UTC; } private static FloatingRateType getFloatingTypeFromIndexType(final IndexType indexType) { switch (indexType) { case Libor: return FloatingRateType.IBOR; case Euribor: return FloatingRateType.IBOR; case BBSW: return FloatingRateType.IBOR; } throw new OpenGammaRuntimeException("Cannot handle index type " + indexType); } private static ExternalId getUnderlyingId(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip) { if (strip.getStrip().getIndexType() == null) { return null; } final String tenorString = strip.getStrip().getResetTenor().getPeriod().toTotalMonths() + "m"; final String fixingRateName = spec.getCurrency().getCode() + " " + strip.getStrip().getIndexType().name().toUpperCase() + " " + tenorString; return ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, fixingRateName); } private ConventionBundle getFixedLegConvention(final InterpolatedYieldCurveSpecification spec, final FixedIncomeStripWithIdentifier strip, final ExternalId swapIdentifier) { ConventionBundle fixedLegConvention; switch (strip.getStrip().getInstrumentType()) { case SWAP_3M: fixedLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_3M_SWAP")); if (fixedLegConvention != null) { return fixedLegConvention; } case SWAP_6M: fixedLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_6M_SWAP")); if (fixedLegConvention != null) { return fixedLegConvention; } case SWAP_12M: fixedLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_12M_SWAP")); if (fixedLegConvention != null) { return fixedLegConvention; } default: fixedLegConvention = _conventionBundleSource.getConventionBundle(ExternalId.of(InMemoryConventionBundleMaster.SIMPLE_NAME_SCHEME, spec.getCurrency().getCode() + "_SWAP")); if (fixedLegConvention != null) { return fixedLegConvention; } } throw new OpenGammaRuntimeException("Could not get fixed leg convention for " + swapIdentifier); } }