/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.conversion; import static com.opengamma.financial.convention.InMemoryConventionBundleMaster.simpleNameSecurityId; import java.util.ArrayList; import org.threeten.bp.Period; import org.threeten.bp.ZonedDateTime; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponCMSDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponFixedDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponIborDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponIborSpreadDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityDefinitionBuilder; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedCompoundedONCompounded; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedON; import com.opengamma.analytics.financial.instrument.index.IborIndex; import com.opengamma.analytics.financial.instrument.index.IndexON; import com.opengamma.analytics.financial.instrument.index.IndexSwap; import com.opengamma.analytics.financial.instrument.payment.CouponDefinition; import com.opengamma.analytics.financial.instrument.payment.CouponFixedDefinition; import com.opengamma.analytics.financial.instrument.payment.CouponFloatingDefinition; import com.opengamma.analytics.financial.instrument.payment.CouponIborCompoundingDefinition; import com.opengamma.analytics.financial.instrument.payment.PaymentDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapCouponFixedCouponDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapFixedCompoundedONCompoundedDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapFixedONDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapFixedONSimplifiedDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapIborIborDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapXCcyDefinition; import com.opengamma.core.holiday.HolidaySource; import com.opengamma.core.region.RegionSource; import com.opengamma.financial.analytics.fixedincome.InterestRateInstrumentType; import com.opengamma.financial.convention.ConventionBundle; import com.opengamma.financial.convention.ConventionBundleSource; import com.opengamma.financial.convention.StubType; 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.security.FinancialSecurityUtils; import com.opengamma.financial.security.FinancialSecurityVisitorAdapter; import com.opengamma.financial.security.swap.FixedInterestRateLeg; import com.opengamma.financial.security.swap.FloatingInterestRateLeg; import com.opengamma.financial.security.swap.FloatingSpreadIRLeg; import com.opengamma.financial.security.swap.ForwardSwapSecurity; import com.opengamma.financial.security.swap.InterestRateNotional; import com.opengamma.financial.security.swap.SwapLeg; import com.opengamma.financial.security.swap.SwapSecurity; import com.opengamma.id.ExternalId; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; /** * Converts swaps from {@link SwapSecurity} to the {@link InstrumentDefinition}s. * @deprecated Replaced by {@link SwapSecurityConverter}, which does not use curve name information */ @Deprecated public class SwapSecurityConverterDeprecated extends FinancialSecurityVisitorAdapter<InstrumentDefinition<?>> { /** A holiday source */ private final HolidaySource _holidaySource; /** A convention bundle source */ private final ConventionBundleSource _conventionSource; /** A region source */ private final RegionSource _regionSource; /** Is this converter being used in curve construction code */ private final boolean _forCurves; /** * @param holidaySource The holiday source, not null * @param conventionSource The convention source, not null * @param regionSource The region source, not null * @param forCurves true if the converter is used in curve construction code */ public SwapSecurityConverterDeprecated(final HolidaySource holidaySource, final ConventionBundleSource conventionSource, final RegionSource regionSource, final boolean forCurves) { ArgumentChecker.notNull(holidaySource, "holiday source"); ArgumentChecker.notNull(conventionSource, "convention source"); ArgumentChecker.notNull(regionSource, "region source"); _holidaySource = holidaySource; _conventionSource = conventionSource; _regionSource = regionSource; _forCurves = forCurves; } /** * Gets the holiday source. * @return The holiday source */ public HolidaySource getHolidaySource() { return _holidaySource; } /** * Gets the convention bundle source. * @return The convention bundle source */ public ConventionBundleSource getConventionBundleSource() { return _conventionSource; } /** * Gets the region source. * @return The region source */ public RegionSource getRegionSource() { return _regionSource; } @Override public InstrumentDefinition<?> visitForwardSwapSecurity(final ForwardSwapSecurity security) { return visitSwapSecurity(security); } @Override public InstrumentDefinition<?> visitSwapSecurity(final SwapSecurity security) { ArgumentChecker.notNull(security, "swap security"); final Currency currency = FinancialSecurityUtils.getCurrency(security); if (Currency.BRL.equals(currency)) { return getBRLSwapDefinition(security, SwapSecurityUtils.payFixed(security)); } final InterestRateInstrumentType swapType = SwapSecurityUtils.getSwapType(security); switch (swapType) { case SWAP_FIXED_IBOR: return getFixedIborSwapDefinition(security, SwapSecurityUtils.payFixed(security), false); case SWAP_FIXED_IBOR_WITH_SPREAD: return getFixedIborSwapDefinition(security, SwapSecurityUtils.payFixed(security), true); case SWAP_IBOR_IBOR: return getIborIborSwapDefinition(security); case SWAP_CMS_CMS: return getCMSCMSSwapDefinition(security); case SWAP_FIXED_CMS: return SwapSecurityUtils.payFixed(security) ? getFixedCMSSwapDefinition(security, true) : getFixedCMSSwapDefinition(security, false); case SWAP_IBOR_CMS: return getIborCMSSwapDefinition(security); case SWAP_FIXED_OIS: return getFixedOISSwapDefinition(security, SwapSecurityUtils.payFixed(security), _forCurves); case SWAP_CROSS_CURRENCY: return getCrossCurrencySwapDefinition(security); default: throw new OpenGammaRuntimeException("Cannot handle swapType " + swapType); } } private SwapDefinition getBRLSwapDefinition(final SwapSecurity swapSecurity, final boolean payFixed) { final ZonedDateTime effectiveDate = swapSecurity.getEffectiveDate(); final ZonedDateTime maturityDate = swapSecurity.getMaturityDate(); final SwapLeg payLeg = swapSecurity.getPayLeg(); final SwapLeg receiveLeg = swapSecurity.getReceiveLeg(); final FixedInterestRateLeg fixedLeg = (FixedInterestRateLeg) (payFixed ? payLeg : receiveLeg); final FloatingInterestRateLeg floatLeg = (FloatingInterestRateLeg) (payFixed ? receiveLeg : payLeg); final ExternalId regionId = payLeg.getRegionId(); final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionId); final ConventionBundle indexConvention = _conventionSource.getConventionBundle(floatLeg.getFloatingReferenceRateId()); final Currency currency = ((InterestRateNotional) payLeg.getNotional()).getCurrency(); if (indexConvention == null) { throw new OpenGammaRuntimeException("Could not get OIS index convention for " + currency + " using " + floatLeg.getFloatingReferenceRateId()); } final Integer publicationLag = indexConvention.getOvernightIndexSwapPublicationLag(); if (publicationLag == null) { throw new OpenGammaRuntimeException("Could not get ON Index publication lag for " + indexConvention.getIdentifiers()); } final ConventionBundle brlSwapConvention = _conventionSource.getConventionBundle(simpleNameSecurityId("BRL_DI_SWAP")); final IndexON index = new IndexON(floatLeg.getFloatingReferenceRateId().getValue(), currency, indexConvention.getDayCount(), publicationLag); final String name = index.getName(); final DayCount fixedLegDayCount = fixedLeg.getDayCount(); final BusinessDayConvention businessDayConvention = fixedLeg.getBusinessDayConvention(); final boolean isEOM = fixedLeg.isEom(); final int spotLag = brlSwapConvention.getSwapFixedLegSettlementDays(); final int paymentLag = brlSwapConvention.getSwapFixedLegSettlementDays(); final double notional = ((InterestRateNotional) fixedLeg.getNotional()).getAmount(); final double fixedRate = fixedLeg.getRate(); final GeneratorSwapFixedCompoundedONCompounded generator = new GeneratorSwapFixedCompoundedONCompounded(name, index, fixedLegDayCount, businessDayConvention, isEOM, spotLag, paymentLag, calendar); return SwapFixedCompoundedONCompoundedDefinition.from(effectiveDate, maturityDate, notional, generator, fixedRate, payFixed); } private SwapDefinition getFixedIborSwapDefinition(final SwapSecurity swapSecurity, final boolean payFixed, final boolean hasSpread) { final ZonedDateTime effectiveDate = swapSecurity.getEffectiveDate(); final ZonedDateTime maturityDate = swapSecurity.getMaturityDate(); final SwapLeg payLeg = swapSecurity.getPayLeg(); final SwapLeg receiveLeg = swapSecurity.getReceiveLeg(); final FixedInterestRateLeg fixedLeg = (FixedInterestRateLeg) (payFixed ? payLeg : receiveLeg); final FloatingInterestRateLeg iborLeg = (FloatingInterestRateLeg) (payFixed ? receiveLeg : payLeg); // Swap data final double signFixed = (payFixed ? -1.0 : 1.0); int nbNotional = 0; nbNotional = (swapSecurity.isExchangeInitialNotional() ? nbNotional + 1 : nbNotional); nbNotional = (swapSecurity.isExchangeFinalNotional() ? nbNotional + 1 : nbNotional); final double spread; if (hasSpread) { spread = ((FloatingSpreadIRLeg) iborLeg).getSpread(); } else { spread = 0; } // Ibor Leg final ExternalId regionIdIbor = fixedLeg.getRegionId(); final Calendar calendarIbor = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionIdIbor); final Currency currencyIbor = ((InterestRateNotional) iborLeg.getNotional()).getCurrency(); final ConventionBundle iborIndexConvention = _conventionSource.getConventionBundle(iborLeg.getFloatingReferenceRateId()); if (iborIndexConvention == null) { throw new OpenGammaRuntimeException("Could not get Ibor index convention for " + currencyIbor + " using " + iborLeg.getFloatingReferenceRateId() + " from swap " + swapSecurity.getExternalIdBundle()); } final Frequency freqIbor = iborLeg.getFrequency(); Period tenorIbor; if (Frequency.NEVER_NAME.equals(freqIbor.getName())) { // If NEVER, then treated as a compounded Ibor coupon over the annuity length final ConventionBundle conventionIbor = _conventionSource.getConventionBundle(iborLeg.getFloatingReferenceRateId()); tenorIbor = conventionIbor.getPeriod(); } else { tenorIbor = ConversionUtils.getTenor(freqIbor); } final int spotLag = iborIndexConvention.getSettlementDays(); final IborIndex indexIbor = new IborIndex(currencyIbor, tenorIbor, spotLag, iborIndexConvention.getDayCount(), iborIndexConvention.getBusinessDayConvention(), iborIndexConvention.isEOMConvention(), iborIndexConvention.getName()); final double iborLegNotional = ((InterestRateNotional) iborLeg.getNotional()).getAmount(); final AnnuityDefinition<? extends CouponDefinition> iborLegDefinition; if (Frequency.NEVER_NAME.equals(freqIbor.getName())) { // If NEVER, then treated as a compounded Ibor coupon over the annuity length final CouponDefinition[] payments = new CouponDefinition[nbNotional + 1]; int loopnot = 0; if (swapSecurity.isExchangeInitialNotional()) { payments[0] = new CouponFixedDefinition(currencyIbor, effectiveDate, effectiveDate, effectiveDate, 1.0, signFixed * iborLegNotional, 1.0); loopnot++; } payments[loopnot] = CouponIborCompoundingDefinition.from(-signFixed * iborLegNotional, effectiveDate, maturityDate, indexIbor, StubType.SHORT_START, indexIbor.getBusinessDayConvention(), indexIbor.isEndOfMonth(), calendarIbor); // TODO: add spread and compounding type if (swapSecurity.isExchangeFinalNotional()) { payments[loopnot + 1] = new CouponFixedDefinition(currencyIbor, maturityDate, maturityDate, maturityDate, 1.0, -signFixed * iborLegNotional, 1.0); } iborLegDefinition = new AnnuityDefinition<>(payments, calendarIbor); } else { iborLegDefinition = AnnuityDefinitionBuilder.couponIborSpreadWithNotional(effectiveDate, maturityDate, iborLegNotional, spread, indexIbor, !payFixed, calendarIbor, StubType.SHORT_START, 0, swapSecurity.isExchangeInitialNotional(), swapSecurity.isExchangeFinalNotional()); } // Fixed Leg final ExternalId regionIdFixed = fixedLeg.getRegionId(); final Calendar calendarFixed = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionIdFixed); final Frequency freqFixed = fixedLeg.getFrequency(); final Currency currencyFixed = ((InterestRateNotional) fixedLeg.getNotional()).getCurrency(); final double fixedLegNotional = ((InterestRateNotional) fixedLeg.getNotional()).getAmount(); final AnnuityCouponFixedDefinition fixedLegDefinition; if (Frequency.NEVER_NAME.equals(freqFixed.getName())) { // If NEVER, then treated as a zero-coupon and coupon not used. final int nbPayment = Math.max(nbNotional, 1); // Implementation note: If zero-coupon with no notional, create a fake coupon of 0. final double accruedEnd = (nbNotional == 0 ? 0.0 : 1.0); final CouponFixedDefinition[] notional = new CouponFixedDefinition[nbPayment]; int loopnot = 0; if (swapSecurity.isExchangeInitialNotional()) { notional[0] = new CouponFixedDefinition(currencyIbor, effectiveDate, effectiveDate, effectiveDate, 1.0, -signFixed * fixedLegNotional, 1.0); loopnot++; } if (swapSecurity.isExchangeFinalNotional() || (nbNotional == 0)) { notional[loopnot] = new CouponFixedDefinition(currencyIbor, maturityDate, maturityDate, maturityDate, accruedEnd, signFixed * fixedLegNotional, 1.0); } fixedLegDefinition = new AnnuityCouponFixedDefinition(notional, calendarFixed); } else { final Period tenorFixed = ConversionUtils.getTenor(freqFixed); fixedLegDefinition = AnnuityDefinitionBuilder.couponFixedWithNotional(currencyFixed, effectiveDate, maturityDate, tenorFixed, calendarFixed, fixedLeg.getDayCount(), fixedLeg.getBusinessDayConvention(), fixedLeg.isEom(), fixedLegNotional, fixedLeg.getRate(), payFixed, StubType.SHORT_START, 0, swapSecurity.isExchangeInitialNotional(), swapSecurity.isExchangeFinalNotional()); } return new SwapCouponFixedCouponDefinition(fixedLegDefinition, iborLegDefinition); } private SwapDefinition getFixedOISSwapDefinition(final SwapSecurity swapSecurity, final boolean payFixed, final boolean forCurve) { final ZonedDateTime effectiveDate = swapSecurity.getEffectiveDate(); final ZonedDateTime maturityDate = swapSecurity.getMaturityDate(); final SwapLeg payLeg = swapSecurity.getPayLeg(); final SwapLeg receiveLeg = swapSecurity.getReceiveLeg(); final FixedInterestRateLeg fixedLeg = (FixedInterestRateLeg) (payFixed ? payLeg : receiveLeg); final FloatingInterestRateLeg floatLeg = (FloatingInterestRateLeg) (payFixed ? receiveLeg : payLeg); final ConventionBundle indexConvention = _conventionSource.getConventionBundle(floatLeg.getFloatingReferenceRateId()); final Currency currency = ((InterestRateNotional) payLeg.getNotional()).getCurrency(); if (indexConvention == null) { throw new OpenGammaRuntimeException("Could not get OIS index convention for " + currency + " using " + floatLeg.getFloatingReferenceRateId()); } final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, indexConvention.getRegion()); final String currencyString = currency.getCode(); final Integer publicationLag = indexConvention.getOvernightIndexSwapPublicationLag(); if (publicationLag == null) { throw new OpenGammaRuntimeException("Could not get ON Index publication lag for " + indexConvention.getIdentifiers()); } final Period paymentFrequency = ConversionUtils.getTenor(floatLeg.getFrequency()); final IndexON index = new IndexON(floatLeg.getFloatingReferenceRateId().getValue(), currency, indexConvention.getDayCount(), publicationLag); final GeneratorSwapFixedON generator = new GeneratorSwapFixedON(currencyString + "_OIS_Convention", index, paymentFrequency, fixedLeg.getDayCount(), fixedLeg.getBusinessDayConvention(), fixedLeg.isEom(), 0, 1 - publicationLag, calendar); // TODO: The payment lag is not available at the security level! final double notionalFixed = ((InterestRateNotional) fixedLeg.getNotional()).getAmount(); final double notionalOIS = ((InterestRateNotional) floatLeg.getNotional()).getAmount(); if (forCurve) { return SwapFixedONSimplifiedDefinition.from(effectiveDate, maturityDate, notionalFixed, notionalOIS, generator, fixedLeg.getRate(), payFixed); } return SwapFixedONDefinition.from(effectiveDate, maturityDate, notionalFixed, notionalOIS, generator, fixedLeg.getRate(), payFixed); } private SwapIborIborDefinition getIborIborSwapDefinition(final SwapSecurity swapSecurity) { final ZonedDateTime effectiveDate = swapSecurity.getEffectiveDate(); final ZonedDateTime maturityDate = swapSecurity.getMaturityDate(); final SwapLeg payLeg = swapSecurity.getPayLeg(); final SwapLeg receiveLeg = swapSecurity.getReceiveLeg(); final FloatingInterestRateLeg floatPayLeg = (FloatingInterestRateLeg) payLeg; final FloatingInterestRateLeg floatReceiveLeg = (FloatingInterestRateLeg) receiveLeg; final ExternalId regionId = payLeg.getRegionId(); final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionId); final Currency currency = ((InterestRateNotional) payLeg.getNotional()).getCurrency(); if (floatPayLeg instanceof FloatingSpreadIRLeg) { final AnnuityCouponIborSpreadDefinition payLegDefinition = getIborSwapLegDefinition(effectiveDate, maturityDate, (FloatingSpreadIRLeg) floatPayLeg, calendar, currency, true); if (floatReceiveLeg instanceof FloatingSpreadIRLeg) { final AnnuityCouponIborSpreadDefinition receiveLegDefinition = getIborSwapLegDefinition(effectiveDate, maturityDate, (FloatingSpreadIRLeg) floatReceiveLeg, calendar, currency, false); return SwapIborIborDefinition.from(payLegDefinition, receiveLegDefinition); } final AnnuityCouponIborDefinition receiveLegDefinition = getIborSwapLegDefinition(effectiveDate, maturityDate, floatReceiveLeg, calendar, currency, false); return SwapIborIborDefinition.from(payLegDefinition, receiveLegDefinition); } final AnnuityCouponIborDefinition payLegDefinition = getIborSwapLegDefinition(effectiveDate, maturityDate, floatPayLeg, calendar, currency, true); if (floatReceiveLeg instanceof FloatingSpreadIRLeg) { final AnnuityCouponIborSpreadDefinition receiveLegDefinition = getIborSwapLegDefinition(effectiveDate, maturityDate, (FloatingSpreadIRLeg) floatReceiveLeg, calendar, currency, false); return SwapIborIborDefinition.from(payLegDefinition, receiveLegDefinition); } final AnnuityCouponIborDefinition receiveLegDefinition = getIborSwapLegDefinition(effectiveDate, maturityDate, floatReceiveLeg, calendar, currency, false); return SwapIborIborDefinition.from(payLegDefinition, receiveLegDefinition); } private SwapDefinition getCMSCMSSwapDefinition(final SwapSecurity swapSecurity) { final ZonedDateTime effectiveDate = swapSecurity.getEffectiveDate(); final ZonedDateTime maturityDate = swapSecurity.getMaturityDate(); final SwapLeg payLeg = swapSecurity.getPayLeg(); final SwapLeg receiveLeg = swapSecurity.getReceiveLeg(); final FloatingInterestRateLeg floatPayLeg = (FloatingInterestRateLeg) payLeg; final FloatingInterestRateLeg floatReceiveLeg = (FloatingInterestRateLeg) receiveLeg; final ExternalId regionId = payLeg.getRegionId(); final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionId); final Currency currency = ((InterestRateNotional) payLeg.getNotional()).getCurrency(); final AnnuityCouponCMSDefinition cmsPayLeg = getCMSwapLegDefinition(effectiveDate, maturityDate, floatPayLeg, calendar, currency, true); final AnnuityCouponCMSDefinition cmsReceiveLeg = getCMSwapLegDefinition(effectiveDate, maturityDate, floatReceiveLeg, calendar, currency, false); return new SwapDefinition(cmsPayLeg, cmsReceiveLeg); } private SwapDefinition getFixedCMSSwapDefinition(final SwapSecurity swapSecurity, final boolean payFixed) { final ZonedDateTime effectiveDate = swapSecurity.getEffectiveDate(); final ZonedDateTime maturityDate = swapSecurity.getMaturityDate(); final SwapLeg payLeg = swapSecurity.getPayLeg(); final SwapLeg receiveLeg = swapSecurity.getReceiveLeg(); final FixedInterestRateLeg fixedLeg = (FixedInterestRateLeg) (payFixed ? payLeg : receiveLeg); final FloatingInterestRateLeg floatingLeg = (FloatingInterestRateLeg) (payFixed ? receiveLeg : payLeg); final ExternalId regionId = payLeg.getRegionId(); final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionId); final Currency currency = ((InterestRateNotional) payLeg.getNotional()).getCurrency(); final AnnuityCouponFixedDefinition fixedAnnuity = getFixedSwapLegDefinition(effectiveDate, maturityDate, fixedLeg, calendar, payFixed); final AnnuityCouponCMSDefinition cmsAnnuity = getCMSwapLegDefinition(effectiveDate, maturityDate, floatingLeg, calendar, currency, !payFixed); return payFixed ? new SwapDefinition(fixedAnnuity, cmsAnnuity) : new SwapDefinition(cmsAnnuity, fixedAnnuity); } private SwapDefinition getIborCMSSwapDefinition(final SwapSecurity swapSecurity) { final ZonedDateTime effectiveDate = swapSecurity.getEffectiveDate(); final ZonedDateTime maturityDate = swapSecurity.getMaturityDate(); final SwapLeg payLeg = swapSecurity.getPayLeg(); final SwapLeg receiveLeg = swapSecurity.getReceiveLeg(); final FloatingInterestRateLeg floatPayLeg = (FloatingInterestRateLeg) payLeg; final FloatingInterestRateLeg floatReceiveLeg = (FloatingInterestRateLeg) receiveLeg; final boolean payIbor = floatPayLeg.getFloatingRateType().isIbor(); final boolean receiveIbor = floatReceiveLeg.getFloatingRateType().isIbor(); if (receiveIbor == payIbor) { throw new OpenGammaRuntimeException("This should never happen"); } final FloatingInterestRateLeg iborLeg = payIbor ? floatPayLeg : floatReceiveLeg; final FloatingInterestRateLeg cmsLeg = payIbor ? floatReceiveLeg : floatPayLeg; final ExternalId regionId = payLeg.getRegionId(); final Calendar calendar = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionId); final Currency currency = ((InterestRateNotional) payLeg.getNotional()).getCurrency(); final AnnuityDefinition<? extends CouponFloatingDefinition> iborAnnuity = getIborSwapLegDefinition(effectiveDate, maturityDate, iborLeg, calendar, currency, payIbor); final AnnuityCouponCMSDefinition cmsAnnuity = getCMSwapLegDefinition(effectiveDate, maturityDate, cmsLeg, calendar, currency, !payIbor); return payIbor ? new SwapDefinition(iborAnnuity, cmsAnnuity) : new SwapDefinition(cmsAnnuity, iborAnnuity); // Implementation note: In the converter, the pay leg is expected to be first. } private static AnnuityCouponFixedDefinition getFixedSwapLegDefinition(final ZonedDateTime effectiveDate, final ZonedDateTime maturityDate, final FixedInterestRateLeg fixedLeg, final Calendar calendar, final boolean isPayer) { final double notional = ((InterestRateNotional) fixedLeg.getNotional()).getAmount(); final BusinessDayConvention businessDay = fixedLeg.getBusinessDayConvention(); if (businessDay == null) { throw new OpenGammaRuntimeException("Could not get Business Day for " + fixedLeg); } final boolean isEOM = fixedLeg.isEom(); final Frequency freqFixed = fixedLeg.getFrequency(); final Period tenorFixed = ConversionUtils.getTenor(freqFixed); return AnnuityCouponFixedDefinition.from(((InterestRateNotional) fixedLeg.getNotional()).getCurrency(), effectiveDate, maturityDate, tenorFixed, calendar, fixedLeg.getDayCount(), businessDay, isEOM, notional, fixedLeg.getRate(), isPayer); } private AnnuityCouponIborSpreadDefinition getIborSwapLegDefinition(final ZonedDateTime effectiveDate, final ZonedDateTime maturityDate, final FloatingSpreadIRLeg iborLeg, final Calendar calendar, final Currency currency, final boolean isPayer) { final ConventionBundle iborIndexConvention = _conventionSource.getConventionBundle(iborLeg.getFloatingReferenceRateId()); if (iborIndexConvention == null) { throw new OpenGammaRuntimeException("Could not get Ibor index convention for " + currency + " using " + iborLeg.getFloatingReferenceRateId()); } final Frequency freqIbor = iborLeg.getFrequency(); final Period tenorIbor = ConversionUtils.getTenor(freqIbor); final IborIndex iborIndex = new IborIndex(currency, tenorIbor, iborIndexConvention.getSettlementDays(), iborIndexConvention.getDayCount(), iborIndexConvention.getBusinessDayConvention(), iborIndexConvention.isEOMConvention()); final double iborLegNotional = ((InterestRateNotional) iborLeg.getNotional()).getAmount(); final double spread = iborLeg.getSpread(); return AnnuityCouponIborSpreadDefinition.from(effectiveDate, maturityDate, tenorIbor, iborLegNotional, iborIndex, isPayer, iborLeg.getBusinessDayConvention(), iborLeg.isEom(), iborLeg.getDayCount(), spread, calendar); } private AnnuityCouponIborDefinition getIborSwapLegDefinition(final ZonedDateTime effectiveDate, final ZonedDateTime maturityDate, final FloatingInterestRateLeg iborLeg, final Calendar calendar, final Currency currency, final boolean isPayer) { final ConventionBundle iborIndexConvention = _conventionSource.getConventionBundle(iborLeg.getFloatingReferenceRateId()); if (iborIndexConvention == null) { throw new OpenGammaRuntimeException("Could not get Ibor index convention for " + currency + " using " + iborLeg.getFloatingReferenceRateId()); } final Frequency freqIbor = iborLeg.getFrequency(); final Period tenorIbor = ConversionUtils.getTenor(freqIbor); final IborIndex iborIndex = new IborIndex(currency, tenorIbor, iborIndexConvention.getSettlementDays(), iborIndexConvention.getDayCount(), iborIndexConvention.getBusinessDayConvention(), iborIndexConvention.isEOMConvention()); final double iborLegNotional = ((InterestRateNotional) iborLeg.getNotional()).getAmount(); return AnnuityCouponIborDefinition.from(effectiveDate, maturityDate, tenorIbor, iborLegNotional, iborIndex, isPayer, iborLeg.getBusinessDayConvention(), iborLeg.isEom(), iborLeg.getDayCount(), calendar); } private AnnuityCouponCMSDefinition getCMSwapLegDefinition(final ZonedDateTime effectiveDate, final ZonedDateTime maturityDate, final FloatingInterestRateLeg floatLeg, final Calendar calendar, final Currency currency, final boolean isPayer) { final double notional = ((InterestRateNotional) floatLeg.getNotional()).getAmount(); final Frequency freq = floatLeg.getFrequency(); final Period tenorPayment = ConversionUtils.getTenor(freq); final ConventionBundle swapIndexConvention = _conventionSource.getConventionBundle(floatLeg.getFloatingReferenceRateId()); if (swapIndexConvention == null) { throw new OpenGammaRuntimeException("Could not get swap index convention for " + floatLeg.getFloatingReferenceRateId().toString()); } final ConventionBundle iborIndexConvention = _conventionSource.getConventionBundle(swapIndexConvention.getSwapFloatingLegInitialRate()); if (iborIndexConvention == null) { throw new OpenGammaRuntimeException("Could not get ibor index convention for " + swapIndexConvention.getSwapFloatingLegInitialRate()); } final IborIndex iborIndex = new IborIndex(currency, tenorPayment, iborIndexConvention.getSettlementDays(), iborIndexConvention.getDayCount(), iborIndexConvention.getBusinessDayConvention(), iborIndexConvention.isEOMConvention()); final Period fixedLegPaymentPeriod = ConversionUtils.getTenor(swapIndexConvention.getSwapFixedLegFrequency()); final IndexSwap swapIndex = new IndexSwap(fixedLegPaymentPeriod, swapIndexConvention.getSwapFixedLegDayCount(), iborIndex, swapIndexConvention.getPeriod(), calendar); return AnnuityCouponCMSDefinition.from(effectiveDate, maturityDate, notional, swapIndex, tenorPayment, floatLeg.getDayCount(), isPayer, calendar); } private SwapDefinition getCrossCurrencySwapDefinition(final SwapSecurity security) { final ZonedDateTime settlementDate = security.getEffectiveDate(); final ZonedDateTime maturityDate = security.getMaturityDate(); final SwapLeg[] swapLeg = new SwapLeg[2]; swapLeg[0] = security.getPayLeg(); swapLeg[1] = security.getReceiveLeg(); final boolean[] payer = {true, false }; final double[] notional = new double[2]; final Currency[] currency = new Currency[2]; final ExternalId[] regionId = new ExternalId[2]; final Calendar[] calendar = new Calendar[2]; // TODO: Calendar need to be merged to have common payment dates for (int loopleg = 0; loopleg < 2; loopleg++) { notional[loopleg] = ((InterestRateNotional) swapLeg[loopleg].getNotional()).getAmount(); currency[loopleg] = ((InterestRateNotional) swapLeg[loopleg].getNotional()).getCurrency(); regionId[loopleg] = swapLeg[loopleg].getRegionId(); calendar[loopleg] = CalendarUtils.getCalendar(_regionSource, _holidaySource, regionId[0]); } final ArrayList<AnnuityDefinition<? extends PaymentDefinition>> legDefinition = new ArrayList<>(); for (int loopleg = 0; loopleg < 2; loopleg++) { if (swapLeg[loopleg] instanceof FloatingInterestRateLeg) { // Leg is Ibor double spread = 0.0; if (swapLeg[loopleg] instanceof FloatingSpreadIRLeg) { spread = ((FloatingSpreadIRLeg) swapLeg[loopleg]).getSpread(); } final FloatingInterestRateLeg legFloat = (FloatingInterestRateLeg) swapLeg[loopleg]; final ConventionBundle iborIndexConvention = _conventionSource.getConventionBundle(legFloat.getFloatingReferenceRateId()); if (iborIndexConvention == null) { throw new OpenGammaRuntimeException("Could not get Ibor index convention for " + currency[0] + " using " + legFloat.getFloatingReferenceRateId()); } final Period tenorIbor = iborIndexConvention.getPeriod(); final IborIndex iborIndex = new IborIndex(currency[loopleg], tenorIbor, iborIndexConvention.getSettlementDays(), iborIndexConvention.getDayCount(), iborIndexConvention.getBusinessDayConvention(), iborIndexConvention.isEOMConvention()); legDefinition.add(AnnuityDefinitionBuilder.couponIborSpreadWithNotional(settlementDate, maturityDate, notional[loopleg], spread, iborIndex, payer[loopleg], calendar[loopleg], StubType.SHORT_START, 0, security.isExchangeInitialNotional(), security.isExchangeFinalNotional())); } else { if (swapLeg[loopleg] instanceof FixedInterestRateLeg) { // Leg is Fixed final FixedInterestRateLeg legFixed = (FixedInterestRateLeg) swapLeg[loopleg]; final BusinessDayConvention businessDay = legFixed.getBusinessDayConvention(); if (businessDay == null) { throw new OpenGammaRuntimeException("Could not get Business Day for " + legFixed); } final boolean isEOM = legFixed.isEom(); final Frequency freqFixed = legFixed.getFrequency(); final Period tenorFixed = ConversionUtils.getTenor(freqFixed); legDefinition.add(AnnuityDefinitionBuilder.couponFixedWithNotional(currency[loopleg], settlementDate, maturityDate, tenorFixed, calendar[loopleg], legFixed.getDayCount(), businessDay, isEOM, notional[loopleg], legFixed.getRate(), payer[loopleg], StubType.SHORT_START, 0, security.isExchangeInitialNotional(), security.isExchangeFinalNotional())); } else { throw new OpenGammaRuntimeException("X Ccy Swap legs should be Fixed or Floating legs"); } } } return new SwapXCcyDefinition(legDefinition.get(0), legDefinition.get(1)); } }