/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.instrument.payment; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; import org.testng.annotations.Test; import org.threeten.bp.LocalDateTime; import org.threeten.bp.Period; import org.threeten.bp.ZoneOffset; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedON; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedONMaster; import com.opengamma.analytics.financial.instrument.index.IndexON; import com.opengamma.analytics.financial.interestrate.TestsDataSetsSABR; import com.opengamma.analytics.financial.interestrate.YieldCurveBundle; import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixed; import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponON; import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment; import com.opengamma.analytics.financial.interestrate.payments.method.CouponFixedDiscountingMethod; import com.opengamma.analytics.financial.provider.description.MulticurveProviderDiscountDataSets; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount; import com.opengamma.analytics.financial.schedule.ScheduleCalculator; import com.opengamma.analytics.util.time.TimeCalculator; import com.opengamma.financial.convention.businessday.BusinessDayConvention; import com.opengamma.financial.convention.businessday.BusinessDayConventions; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.financial.convention.calendar.MondayToFridayCalendar; import com.opengamma.financial.convention.daycount.DayCount; import com.opengamma.financial.convention.daycount.DayCounts; import com.opengamma.timeseries.DoubleTimeSeries; import com.opengamma.timeseries.precise.zdt.ImmutableZonedDateTimeDoubleTimeSeries; import com.opengamma.util.money.Currency; import com.opengamma.util.money.CurrencyAmount; import com.opengamma.util.money.MultipleCurrencyAmount; import com.opengamma.util.test.TestGroup; import com.opengamma.util.time.DateUtils; /** * Tests related to the OIS coupon definition. */ @SuppressWarnings("deprecation") @Test(groups = TestGroup.UNIT) public class CouponONDefinitionTest { private static final int EUR_SETTLEMENT_DAYS = 2; private static final BusinessDayConvention EUR_BUSINESS_DAY = BusinessDayConventions.MODIFIED_FOLLOWING; private static final boolean EUR_IS_EOM = true; //EUR Eonia private static final String EUR_OIS_NAME = "EUR EONIA"; private static final Currency EUR_CUR = Currency.EUR; private static final Calendar EUR_CALENDAR = new MondayToFridayCalendar("EUR"); private static final int EUR_PUBLICATION_LAG = 0; private static final DayCount EUR_DAY_COUNT = DayCounts.ACT_360; private static final IndexON EUR_OIS = new IndexON(EUR_OIS_NAME, EUR_CUR, EUR_DAY_COUNT, EUR_PUBLICATION_LAG); // Coupon EONIA 3m private static final ZonedDateTime TRADE_DATE = DateUtils.getUTCDate(2011, 9, 7); private static final ZonedDateTime SPOT_DATE = ScheduleCalculator.getAdjustedDate(TRADE_DATE, EUR_SETTLEMENT_DAYS, EUR_CALENDAR); private static final Period CPN_TENOR = Period.ofDays(7); // 1 week private static final ZonedDateTime START_ACCRUAL_DATE = SPOT_DATE; private static final ZonedDateTime EUR_END_ACCRUAL_DATE = ScheduleCalculator.getAdjustedDate(START_ACCRUAL_DATE, CPN_TENOR, EUR_BUSINESS_DAY, EUR_CALENDAR, EUR_IS_EOM); private static final ZonedDateTime EUR_LAST_FIXING_DATE = ScheduleCalculator.getAdjustedDate(EUR_END_ACCRUAL_DATE, -1, EUR_CALENDAR); // Overnight private static final ZonedDateTime EUR_LAST_PUBLICATION_DATE = ScheduleCalculator.getAdjustedDate(EUR_LAST_FIXING_DATE, EUR_PUBLICATION_LAG, EUR_CALENDAR); // Lag private static final ZonedDateTime EUR_PAYMENT_DATE = ScheduleCalculator.getAdjustedDate(EUR_LAST_PUBLICATION_DATE, EUR_SETTLEMENT_DAYS, EUR_CALENDAR); // Payment is wrt last publication date private static final double EUR_PAYMENT_YEAR_FRACTION = EUR_DAY_COUNT.getDayCountFraction(START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE); private static final double NOTIONAL = 100000000; private static final double EUR_FIXING_YEAR_FRACTION = EUR_DAY_COUNT.getDayCountFraction(START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE); private static final CouponONDefinition EONIA_COUPON_DEFINITION = new CouponONDefinition(EUR_CUR, EUR_PAYMENT_DATE, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_CALENDAR); @Test(expectedExceptions = IllegalArgumentException.class) public void nullIndex() { new CouponONDefinition(EUR_CUR, EUR_PAYMENT_DATE, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, null, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_CALENDAR); } @Test(expectedExceptions = IllegalArgumentException.class) public void nullStartFixing() { new CouponONDefinition(EUR_CUR, EUR_PAYMENT_DATE, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, null, EUR_END_ACCRUAL_DATE, EUR_CALENDAR); } @Test(expectedExceptions = IllegalArgumentException.class) public void nullEndFixing() { new CouponONDefinition(EUR_CUR, EUR_PAYMENT_DATE, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, START_ACCRUAL_DATE, null, EUR_CALENDAR); } @Test(expectedExceptions = IllegalArgumentException.class) public void inmcompatibleCurrency() { new CouponONDefinition(Currency.USD, EUR_PAYMENT_DATE, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, START_ACCRUAL_DATE, EUR_END_ACCRUAL_DATE, EUR_CALENDAR); } @Test public void getter() { assertEquals("CouponOISSimplified definition: getter", EUR_OIS, EONIA_COUPON_DEFINITION.getIndex()); final ZonedDateTime[] FixingDateArray = EONIA_COUPON_DEFINITION.getFixingPeriodDate(); final ZonedDateTime firstFixingPeriod = FixingDateArray[0]; final ZonedDateTime lastFixingPeriodEndDate = FixingDateArray[FixingDateArray.length - 1]; assertEquals("CouponOISSimplified definition: getter", START_ACCRUAL_DATE, firstFixingPeriod); assertEquals("CouponOISSimplified definition: getter", lastFixingPeriodEndDate, EUR_END_ACCRUAL_DATE); assertEquals("CouponOISSimplified definition: getter", EUR_LAST_FIXING_DATE, LocalDateTime.of(2011, 9, 15, 0, 0, 0, 0).atZone(ZoneOffset.UTC)); assertEquals("CouponOISSimplified definition: getter", lastFixingPeriodEndDate, LocalDateTime.of(2011, 9, 16, 0, 0, 0, 0).atZone(ZoneOffset.UTC)); double aftot = 0.0; for (int loopperiod = 0; loopperiod < EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor().length; loopperiod++) { aftot += EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[loopperiod]; } assertEquals("CouponOISSimplified definition: getter", EUR_FIXING_YEAR_FRACTION, aftot, 1.0E-10); } @Test /** * Tests the builder from financial details. */ public void from() { final CouponONDefinition cpnFrom = CouponONDefinition.from(EUR_OIS, SPOT_DATE, CPN_TENOR, NOTIONAL, EUR_SETTLEMENT_DAYS, EUR_BUSINESS_DAY, EUR_IS_EOM, EUR_CALENDAR); assertEquals("CouponOISSimplified definition: from", cpnFrom, EONIA_COUPON_DEFINITION); } @Test /** * Tests the toDerivative method. */ public void toDerivativeNoFixing() { final CouponON cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(TRADE_DATE); final double paymentTime = TimeCalculator.getTimeBetween(TRADE_DATE, EUR_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(TRADE_DATE, START_ACCRUAL_DATE); final double fixingEndTime = TimeCalculator.getTimeBetween(TRADE_DATE, EUR_END_ACCRUAL_DATE); final CouponON cpnExpected = new CouponON(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, fixingStartTime, fixingEndTime, EUR_FIXING_YEAR_FRACTION, NOTIONAL); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. */ public void toDerivativeFixingBeforeStart() { final ZonedDateTime referenceDate = ScheduleCalculator.getAdjustedDate(TRADE_DATE, 1, EUR_CALENDAR); final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7) }, new double[] {0.01 }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(referenceDate, START_ACCRUAL_DATE); final double fixingEndTime = TimeCalculator.getTimeBetween(referenceDate, EUR_END_ACCRUAL_DATE); final CouponON cpnExpected = new CouponON(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, fixingStartTime, fixingEndTime, EUR_FIXING_YEAR_FRACTION, NOTIONAL); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. */ public void toDerivativeFixingOnStartNotYetFixed() { final ZonedDateTime referenceDate = SPOT_DATE; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8) }, new double[] { 0.01, 0.01 }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(referenceDate, START_ACCRUAL_DATE); final double fixingEndTime = TimeCalculator.getTimeBetween(referenceDate, EUR_END_ACCRUAL_DATE); final CouponON cpnExpected = new CouponON(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, fixingStartTime, fixingEndTime, EUR_FIXING_YEAR_FRACTION, NOTIONAL); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. */ public void toDerivativeFixingOnStartFixed() { final ZonedDateTime referenceDate = SPOT_DATE; final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9) }, new double[] {fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final ZonedDateTime startFixingLeft = ScheduleCalculator.getAdjustedDate(referenceDate, 1, EUR_CALENDAR); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(referenceDate, startFixingLeft); final double fixingEndTime = TimeCalculator.getTimeBetween(referenceDate, EUR_END_ACCRUAL_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]); double yearFractionLeft = 0.0; for (int loopperiod = 1; loopperiod < EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor().length; loopperiod++) { yearFractionLeft += EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[loopperiod]; } final CouponON cpnExpected = new CouponON(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, fixingStartTime, fixingEndTime, yearFractionLeft, notionalIncreased); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. */ public void toDerivativeFixingMiddleNotYetFixed() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 13); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12) }, new double[] {fixingRate, fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final ZonedDateTime startFixingLeft = referenceDate; final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(referenceDate, startFixingLeft); final double fixingEndTime = TimeCalculator.getTimeBetween(referenceDate, EUR_END_ACCRUAL_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[1]); double yearFractionLeft = 0.0; for (int loopperiod = 2; loopperiod < EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor().length; loopperiod++) { yearFractionLeft += EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[loopperiod]; } final CouponON cpnExpected = new CouponON(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, fixingStartTime, fixingEndTime, yearFractionLeft, notionalIncreased); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. */ public void toDerivativeFixingMiddleFixed() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 13); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13) }, new double[] {fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final ZonedDateTime startFixingLeft = ScheduleCalculator.getAdjustedDate(referenceDate, 1, EUR_CALENDAR); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(referenceDate, startFixingLeft); final double fixingEndTime = TimeCalculator.getTimeBetween(referenceDate, EUR_END_ACCRUAL_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[1]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[2]); double yearFractionLeft = 0.0; for (int loopperiod = 3; loopperiod < EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor().length; loopperiod++) { yearFractionLeft += EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[loopperiod]; } final CouponON cpnExpected = new CouponON(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, fixingStartTime, fixingEndTime, yearFractionLeft, notionalIncreased); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. */ public void toDerivativeFixingSecondLastFixed() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 15); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13), DateUtils.getUTCDate(2011, 9, 14), DateUtils.getUTCDate(2011, 9, 15) }, new double[] { fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[1]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[2]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[3]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[4]); final CouponFixed cpnExpected = new CouponFixed(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, (notionalIncreased / NOTIONAL - 1.0) / EUR_PAYMENT_YEAR_FRACTION); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. Reference date is after the last fixing date and all the fixing are known. */ public void toDerivativeFixingLast() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 16); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13), DateUtils.getUTCDate(2011, 9, 14), DateUtils.getUTCDate(2011, 9, 15) }, new double[] { fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[1]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[2]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[3]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[4]); final CouponFixed cpnExpected = new CouponFixed(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, (notionalIncreased / NOTIONAL - 1.0) / EUR_PAYMENT_YEAR_FRACTION); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } // TODO: add a couple of test on the last fixing date, with and without the fixing present. @Test /** * Tests the toDerivative method. */ public void toDerivativeAfterLast() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 19); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13), DateUtils.getUTCDate(2011, 9, 14), DateUtils.getUTCDate(2011, 9, 15) }, new double[] { fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, EUR_PAYMENT_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[1]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[2]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[3]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[4]); final CouponFixed cpnExpected = new CouponFixed(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, (notionalIncreased / NOTIONAL - 1.0) / EUR_PAYMENT_YEAR_FRACTION); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method on the payment date. valuation is at noon, payment set at midnight... */ public void toDerivativeJustAfterPayment() { final ZonedDateTime valuationTimeIsNoon = DateUtils.getUTCDate(2011, 9, 19, 12, 0); assertTrue("valuationTimeIsNoon used to be after paymentDate, which was midnight. Confirm behaviour", valuationTimeIsNoon.isAfter(EONIA_COUPON_DEFINITION.getPaymentDate())); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13), DateUtils.getUTCDate(2011, 9, 14), DateUtils.getUTCDate(2011, 9, 15) }, new double[] { fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = EONIA_COUPON_DEFINITION.toDerivative(valuationTimeIsNoon, fixingTS); final double paymentTime = TimeCalculator.getTimeBetween(valuationTimeIsNoon, EUR_PAYMENT_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[1]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[2]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[3]) * (1 + fixingRate * EONIA_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[4]); final CouponFixed cpnExpected = new CouponFixed(EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, (notionalIncreased / NOTIONAL - 1.0) / EUR_PAYMENT_YEAR_FRACTION); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); // Test pricing, too. Notice that the value of a coupon on its payment date is non-zero final MulticurveProviderDiscount curves = MulticurveProviderDiscountDataSets.createMulticurveEurUsd(); final MultipleCurrencyAmount pvConverted = com.opengamma.analytics.financial.interestrate.payments.provider.CouponFixedDiscountingMethod.getInstance().presentValue((CouponFixed) cpnConverted, curves); final MultipleCurrencyAmount pvExpected = com.opengamma.analytics.financial.interestrate.payments.provider.CouponFixedDiscountingMethod.getInstance().presentValue(cpnExpected, curves); assertEquals("CouponOIS definition: toDerivative", pvConverted, pvExpected); assertEquals("CouponOIS definition: toDerivative", pvConverted, MultipleCurrencyAmount.of(EUR_CUR, 19445.833380471457)); } @Test(expectedExceptions = IllegalArgumentException.class) /** * Tests the toDerivative method: after payment date */ public void toDerivativeAfterPayment() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 20); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13), DateUtils.getUTCDate(2011, 9, 14), DateUtils.getUTCDate(2011, 9, 15) }, new double[] { fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); EONIA_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); } private static final Calendar NYC = new MondayToFridayCalendar("NYC"); private static final GeneratorSwapFixedON USD_GENERATOR = GeneratorSwapFixedONMaster.getInstance().getGenerator("USD1YFEDFUND", NYC); private static final IndexON USD_FEDFUND = USD_GENERATOR.getIndex(); private static final ZonedDateTime USD_END_ACCRUAL_DATE = ScheduleCalculator.getAdjustedDate(START_ACCRUAL_DATE, CPN_TENOR, USD_GENERATOR.getBusinessDayConvention(), NYC, USD_GENERATOR.isEndOfMonth()); private static ZonedDateTime USD_LAST_FIXING_DATE = ScheduleCalculator.getAdjustedDate(USD_END_ACCRUAL_DATE, -1, NYC); // Overnight static { USD_LAST_FIXING_DATE = ScheduleCalculator.getAdjustedDate(USD_LAST_FIXING_DATE, USD_GENERATOR.getIndex().getPublicationLag(), NYC); // Lag } private static final ZonedDateTime USD_PAYMENT_DATE = ScheduleCalculator.getAdjustedDate(USD_LAST_FIXING_DATE, USD_GENERATOR.getSpotLag(), NYC); private static final double USD_PAYMENT_YEAR_FRACTION = USD_GENERATOR.getFixedLegDayCount().getDayCountFraction(START_ACCRUAL_DATE, USD_END_ACCRUAL_DATE); private static final double USD_FIXING_YEAR_FRACTION = USD_GENERATOR.getFixedLegDayCount().getDayCountFraction(START_ACCRUAL_DATE, USD_END_ACCRUAL_DATE); private static final CouponONDefinition OIS_COUPON_DEFINITION = new CouponONDefinition(USD_FEDFUND.getCurrency(), USD_PAYMENT_DATE, START_ACCRUAL_DATE, USD_END_ACCRUAL_DATE, USD_PAYMENT_YEAR_FRACTION, NOTIONAL, USD_FEDFUND, START_ACCRUAL_DATE, USD_END_ACCRUAL_DATE, EUR_CALENDAR); @Test /** * Tests the toDerivative method. */ public void toDerivativeUSDNoFixingOnFirst() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 12); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(new ZonedDateTime[] {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8) }, new double[] { fixingRate, fixingRate }); final Payment cpnConverted = OIS_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final ZonedDateTime startFixingLeft = DateUtils.getUTCDate(2011, 9, 9); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, USD_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(referenceDate, startFixingLeft); final double fixingEndTime = TimeCalculator.getTimeBetween(referenceDate, USD_END_ACCRUAL_DATE); final double notionalIncreased = NOTIONAL; final double yearFractionLeft = USD_FIXING_YEAR_FRACTION; final CouponON cpnExpected = new CouponON(USD_FEDFUND.getCurrency(), paymentTime, USD_PAYMENT_YEAR_FRACTION, NOTIONAL, USD_FEDFUND, fixingStartTime, fixingEndTime, yearFractionLeft, notionalIncreased); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } @Test /** * Tests the toDerivative method. */ public void toDerivativeUSDFixingOnFirst() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 12); final ZonedDateTime[] fixingZDTs = {DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12) }; final double[] fixingRates = {0.01, 0.011, 0.012, 0.13 }; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(fixingZDTs, fixingRates); final Payment cpnConverted = OIS_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final ZonedDateTime startFixingLeft = DateUtils.getUTCDate(2011, 9, 12); final double paymentTime = TimeCalculator.getTimeBetween(referenceDate, USD_PAYMENT_DATE); final double fixingStartTime = TimeCalculator.getTimeBetween(referenceDate, startFixingLeft); final double fixingEndTime = TimeCalculator.getTimeBetween(referenceDate, USD_END_ACCRUAL_DATE); final double notionalIncreased = NOTIONAL * (1 + fixingRates[2] * OIS_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[0]); double yearFractionLeft = 0.0; for (int loopperiod = 1; loopperiod < OIS_COUPON_DEFINITION.getFixingPeriodAccrualFactor().length; loopperiod++) { yearFractionLeft += OIS_COUPON_DEFINITION.getFixingPeriodAccrualFactor()[loopperiod]; } final CouponON cpnExpected = new CouponON(USD_FEDFUND.getCurrency(), paymentTime, USD_PAYMENT_YEAR_FRACTION, NOTIONAL, USD_FEDFUND, fixingStartTime, fixingEndTime, yearFractionLeft, notionalIncreased); assertEquals("CouponOISSimplified definition: toDerivative", cpnExpected, cpnConverted); } }