/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.instrument.swap; import org.threeten.bp.Period; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.InstrumentDefinitionVisitor; import com.opengamma.analytics.financial.instrument.annuity.AnnuityDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityDefinitionBuilder; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapXCcyIborIbor; import com.opengamma.analytics.financial.instrument.payment.CouponDefinition; import com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity; import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment; import com.opengamma.analytics.financial.interestrate.swap.derivative.Swap; import com.opengamma.financial.convention.StubType; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.timeseries.precise.zdt.ZonedDateTimeDoubleTimeSeries; import com.opengamma.util.ArgumentChecker; /** * Class describing a Ibor+Spread for Ibor+Spread payments swap. The two legs can be in different currencies. */ public class SwapXCcyIborIborDefinition extends SwapDefinition { /** * Constructor of the ibor-ibor swap from its two legs. * @param firstLeg The first Ibor leg. * @param secondLeg The second Ibor leg. */ public SwapXCcyIborIborDefinition(final AnnuityDefinition<CouponDefinition> firstLeg, final AnnuityDefinition<CouponDefinition> secondLeg) { super(firstLeg, secondLeg); } /** * Builder from the settlement date and a generator. The legs have different notionals. * The notionals are paid on the settlement date and final payment date of each leg. * @param settlementDate The settlement date. * @param tenor The swap tenor. * @param generator The Ibor/Ibor swap generator. * @param notional1 The first leg notional. * @param notional2 The second leg notional. * @param spread The spread to be applied to the first leg. * @param isPayer The payer flag for the first leg. * @param calendar1 The holiday calendar for the first leg. * @param calendar2 The holiday calendar for the second leg. * @return The swap. */ public static SwapXCcyIborIborDefinition from(final ZonedDateTime settlementDate, final Period tenor, final GeneratorSwapXCcyIborIbor generator, final double notional1, final double notional2, final double spread, final boolean isPayer, final Calendar calendar1, final Calendar calendar2) { ArgumentChecker.notNull(settlementDate, "settlement date"); ArgumentChecker.notNull(tenor, "Tenor"); ArgumentChecker.notNull(generator, "Swap generator"); // TODO: create a mechanism for the simultaneous payments on both legs, i.e. joint calendar final ZonedDateTime maturityDate = settlementDate.plus(tenor); return from(settlementDate, maturityDate, generator, notional1, notional2, spread, 0.0, isPayer); } /** * Builder from the settlement date and a generator. The legs have different notionals. * The notionals are paid on the settlement date and final payment date of each leg. * @param settlementDate The settlement date. * @param maturityDate The swap maturity date. * @param generator The Ibor/Ibor swap generator. * @param notional1 The first leg notional. * @param notional2 The second leg notional. * @param spread1 The spread to be applied to the first leg. * @param spread2 The spread to be applied to the second leg. * @param isPayer The payer flag for the first leg. * @return The swap. */ public static SwapXCcyIborIborDefinition from(final ZonedDateTime settlementDate, final ZonedDateTime maturityDate, final GeneratorSwapXCcyIborIbor generator, final double notional1, final double notional2, final double spread1, final double spread2, final boolean isPayer) { ArgumentChecker.notNull(settlementDate, "settlement date"); ArgumentChecker.notNull(maturityDate, "Maturity date"); ArgumentChecker.notNull(generator, "Swap generator"); // TODO: create a mechanism for the simultaneous payments on both legs, i.e. joint calendar final AnnuityDefinition<CouponDefinition> firstLegNotional = AnnuityDefinitionBuilder.couponIborSpreadWithNotional(settlementDate, maturityDate, notional1, spread1, generator.getIborIndex1(), isPayer, generator.getCalendar1(), StubType.SHORT_START, 0, true, true); final AnnuityDefinition<CouponDefinition> secondLegNotional = AnnuityDefinitionBuilder.couponIborSpreadWithNotional(settlementDate, maturityDate, notional2, spread2, generator.getIborIndex2(), !isPayer, generator.getCalendar2(), StubType.SHORT_START, 0, true, true); return new SwapXCcyIborIborDefinition(firstLegNotional, secondLegNotional); } @Override public <U, V> V accept(final InstrumentDefinitionVisitor<U, V> visitor, final U data) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitSwapXCcyIborIborDefinition(this, data); } @Override public <V> V accept(final InstrumentDefinitionVisitor<?, V> visitor) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitSwapXCcyIborIborDefinition(this); } @Override public Swap<Payment, Payment> toDerivative(final ZonedDateTime date) { final Annuity<Payment> firstLeg = (Annuity<Payment>) getFirstLeg().toDerivative(date); final Annuity<Payment> secondLeg = (Annuity<Payment>) getSecondLeg().toDerivative(date); return new Swap<>(firstLeg, secondLeg); } @Override public Swap<Payment, Payment> toDerivative(final ZonedDateTime date, final ZonedDateTimeDoubleTimeSeries[] indexDataTS) { ArgumentChecker.notNull(indexDataTS, "index data time series array"); ArgumentChecker.isTrue(indexDataTS.length > 1, "index data time series must contain at least two elements"); final Annuity<Payment> firstLeg = (Annuity<Payment>) getFirstLeg().toDerivative(date, indexDataTS[0]); final Annuity<Payment> secondLeg = (Annuity<Payment>) getSecondLeg().toDerivative(date, indexDataTS[1]); return new Swap<>(firstLeg, secondLeg); } }