/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.analytics.model.swaption; import org.threeten.bp.Period; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponIborDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponONDefinition; import com.opengamma.analytics.financial.instrument.index.GeneratorAttributeIR; import com.opengamma.analytics.financial.instrument.index.GeneratorInstrument; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedCompoundedONCompounded; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedIbor; 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.payment.CouponONCompoundedDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapDefinition; import com.opengamma.analytics.financial.instrument.swaption.SwaptionCashFixedCompoundedONCompoundingDefinition; import com.opengamma.analytics.financial.instrument.swaption.SwaptionCashFixedIborDefinition; import com.opengamma.analytics.financial.instrument.swaption.SwaptionPhysicalFixedCompoundedONCompoundedDefinition; import com.opengamma.analytics.financial.instrument.swaption.SwaptionPhysicalFixedIborDefinition; import com.opengamma.core.security.SecuritySource; 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.convention.frequency.SimpleFrequency; import com.opengamma.financial.security.FinancialSecurityUtils; import com.opengamma.financial.security.option.SwaptionSecurity; import com.opengamma.financial.security.swap.FixedInterestRateLeg; import com.opengamma.financial.security.swap.FloatingInterestRateLeg; import com.opengamma.financial.security.swap.SwapSecurity; import com.opengamma.id.ExternalIdBundle; import com.opengamma.util.ArgumentChecker; /** * */ public class SwaptionUtils { public static GeneratorInstrument<GeneratorAttributeIR> getSwapGenerator(final SwaptionSecurity security, final InstrumentDefinition<?> swaption, final SecuritySource securitySource) { ArgumentChecker.notNull(security, "security"); ArgumentChecker.notNull(swaption, "swaption"); ArgumentChecker.notNull(securitySource, "security source"); SwapDefinition swap; if (swaption instanceof SwaptionPhysicalFixedIborDefinition) { swap = ((SwaptionPhysicalFixedIborDefinition) swaption).getUnderlyingSwap(); } else if (swaption instanceof SwaptionCashFixedIborDefinition) { swap = ((SwaptionCashFixedIborDefinition) swaption).getUnderlyingSwap(); } else if (swaption instanceof SwaptionPhysicalFixedCompoundedONCompoundedDefinition) { swap = ((SwaptionPhysicalFixedCompoundedONCompoundedDefinition) swaption).getUnderlyingSwap(); } else if (swaption instanceof SwaptionCashFixedCompoundedONCompoundingDefinition) { swap = ((SwaptionCashFixedCompoundedONCompoundingDefinition) swaption).getUnderlyingSwap(); } else { throw new OpenGammaRuntimeException("Can only handle cash- and physically-settled ibor swaptions"); } final SwapSecurity underlyingSecurity = (SwapSecurity) securitySource.getSingle(ExternalIdBundle.of(security.getUnderlyingId())); FixedInterestRateLeg fixedLeg; FloatingInterestRateLeg floatLeg; if (underlyingSecurity.getPayLeg() instanceof FixedInterestRateLeg) { fixedLeg = (FixedInterestRateLeg) underlyingSecurity.getPayLeg(); floatLeg = (FloatingInterestRateLeg) underlyingSecurity.getReceiveLeg(); } else { fixedLeg = (FixedInterestRateLeg) underlyingSecurity.getReceiveLeg(); floatLeg = (FloatingInterestRateLeg) underlyingSecurity.getPayLeg(); } switch (floatLeg.getFloatingRateType()) { case IBOR: { AnnuityCouponIborDefinition iborLeg; if (swap.getFirstLeg() instanceof AnnuityCouponIborDefinition) { iborLeg = (AnnuityCouponIborDefinition) swap.getFirstLeg(); } else if (swap.getSecondLeg() instanceof AnnuityCouponIborDefinition) { iborLeg = (AnnuityCouponIborDefinition) swap.getSecondLeg(); } else { throw new OpenGammaRuntimeException("Could not find ibor leg for " + underlyingSecurity); } final IborIndex iborIndex = iborLeg.getIborIndex(); final Calendar calendar = iborLeg.getIborCalendar(); final DayCount fixedLegDayCount = fixedLeg.getDayCount(); final Frequency frequency = fixedLeg.getFrequency(); final Period fixedLegPeriod; if (frequency instanceof PeriodFrequency) { fixedLegPeriod = ((PeriodFrequency) frequency).getPeriod(); } else if (frequency instanceof SimpleFrequency) { fixedLegPeriod = ((SimpleFrequency) frequency).toPeriodFrequency().getPeriod(); } else { throw new OpenGammaRuntimeException("Can only handle PeriodFrequency or SimpleFrequency"); } return new GeneratorSwapFixedIbor("Swap Generator", fixedLegPeriod, fixedLegDayCount, iborIndex, calendar); } case OIS: { IndexON onIndex; Calendar calendar; if (swap.getFirstLeg() instanceof AnnuityCouponONDefinition) { final AnnuityCouponONDefinition annuityCouponONDefinition = (AnnuityCouponONDefinition) swap.getFirstLeg(); onIndex = annuityCouponONDefinition.getOvernightIndex(); calendar = annuityCouponONDefinition.getCalendar(); } else if (swap.getSecondLeg() instanceof AnnuityCouponONDefinition) { final AnnuityCouponONDefinition annuityCouponONDefinition = (AnnuityCouponONDefinition) swap.getSecondLeg(); onIndex = annuityCouponONDefinition.getOvernightIndex(); calendar = annuityCouponONDefinition.getCalendar(); } else if (swap.getFirstLeg().getNthPayment(0) instanceof CouponONCompoundedDefinition) { final CouponONCompoundedDefinition couponONDefinition = (CouponONCompoundedDefinition) swap.getFirstLeg().getNthPayment(0); onIndex = couponONDefinition.getIndex(); calendar = couponONDefinition.getCalendar(); } else if (swap.getSecondLeg().getNthPayment(0) instanceof CouponONCompoundedDefinition) { final CouponONCompoundedDefinition couponONDefinition = (CouponONCompoundedDefinition) swap.getSecondLeg().getNthPayment(0); onIndex = couponONDefinition.getIndex(); calendar = couponONDefinition.getCalendar(); } else { throw new OpenGammaRuntimeException("Could not find overnight leg for " + underlyingSecurity); } final DayCount fixedLegDayCount = fixedLeg.getDayCount(); final Frequency frequency = fixedLeg.getFrequency(); final Period fixedLegPeriod; if (frequency instanceof PeriodFrequency) { fixedLegPeriod = ((PeriodFrequency) frequency).getPeriod(); } else if (frequency instanceof SimpleFrequency) { fixedLegPeriod = ((SimpleFrequency) frequency).toPeriodFrequency().getPeriod(); } else { throw new OpenGammaRuntimeException("Can only handle PeriodFrequency or SimpleFrequency"); } final BusinessDayConvention businessDayConvention = fixedLeg.getBusinessDayConvention(); final boolean isEOM = fixedLeg.isEom(); final int spotLag = 0; //TODO if (FinancialSecurityUtils.getCurrency(underlyingSecurity).getCode().equals("BRL")) { return new GeneratorSwapFixedCompoundedONCompounded("Swap Generator", onIndex, fixedLegDayCount, businessDayConvention, isEOM, spotLag, calendar); } return new GeneratorSwapFixedON("Swap Generator", onIndex, fixedLegPeriod, fixedLegDayCount, businessDayConvention, isEOM, spotLag, calendar); } default: throw new OpenGammaRuntimeException("Cannot handle floating leg type " + floatLeg.getFloatingRateType()); } } }