package com.opengamma.analytics.financial.instrument.annuity; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; import org.testng.annotations.Test; import org.threeten.bp.Period; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.index.IndexON; import com.opengamma.analytics.financial.instrument.index.IndexONMaster; import com.opengamma.analytics.financial.instrument.payment.CouponONArithmeticAverageSpreadDefinition; import com.opengamma.analytics.financial.schedule.ScheduleCalculator; import com.opengamma.financial.convention.StubType; 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.util.test.TestGroup; import com.opengamma.util.time.DateUtils; /** * Test. */ @Test(groups = TestGroup.UNIT) public class AnnuityCouponArithmeticAverageONSpreadDefinitionTest { private static final IndexON FEDFUND = IndexONMaster.getInstance().getIndex("FED FUND"); private static final ZonedDateTime EFFECTIVE_DATE = DateUtils.getUTCDate(2013, 9, 9); private static final Period LEG_TENOR = Period.ofYears(10); private static final Period PAY_TENOR = Period.ofMonths(3); private static final double NOTIONAL = 100000000; // 100m private static final double SPREAD = 0.0010; // 10bps private static final int PAY_LAG = 2; private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventions.FOLLOWING; private static final Calendar CALENDAR = new MondayToFridayCalendar("Weekend"); private static final double TOLERANCE_NOTIONAL = 1E-2; private static final double TOLERANCE_RATE = 1.0E-10; @Test public void from() { final ZonedDateTime maturity = EFFECTIVE_DATE.plus(LEG_TENOR); final AnnuityDefinition<CouponONArithmeticAverageSpreadDefinition> leg = AnnuityCouponArithmeticAverageONSpreadDefinition.from(EFFECTIVE_DATE, maturity, NOTIONAL, SPREAD, true, PAY_TENOR, FEDFUND, PAY_LAG, BUSINESS_DAY, true, CALENDAR, StubType.SHORT_START); final int nbCoupon = leg.getNumberOfPayments(); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition", nbCoupon, 40); // nb coupons: 10Y quarterly for (int loopc = 0; loopc < nbCoupon; loopc++) { assertTrue("AnnuityCouponArithmeticAverageONSpreadDefinition: Payer", leg.getNthPayment(loopc).getNotional() < 0); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition: Notional", leg.getNthPayment(loopc).getNotional(), -NOTIONAL, TOLERANCE_NOTIONAL); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition: Spread", leg.getNthPayment(loopc).getSpread(), SPREAD, TOLERANCE_RATE); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition: Pay lag", leg.getNthPayment(loopc).getPaymentDate(), ScheduleCalculator.getAdjustedDate(leg.getNthPayment(loopc).getAccrualEndDate(), PAY_LAG, CALENDAR)); } } @Test public void fromStub() { final ZonedDateTime maturity = EFFECTIVE_DATE.plus(LEG_TENOR).plusMonths(1); final AnnuityDefinition<CouponONArithmeticAverageSpreadDefinition> legShortStart = AnnuityCouponArithmeticAverageONSpreadDefinition.from(EFFECTIVE_DATE, maturity, NOTIONAL, SPREAD, true, PAY_TENOR, FEDFUND, PAY_LAG, BUSINESS_DAY, true, CALENDAR, StubType.SHORT_START); final AnnuityDefinition<CouponONArithmeticAverageSpreadDefinition> legShortStart2 = AnnuityCouponArithmeticAverageONSpreadDefinition.from(EFFECTIVE_DATE, maturity, NOTIONAL, SPREAD, true, PAY_TENOR, FEDFUND, PAY_LAG, BUSINESS_DAY, true, CALENDAR); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition: Default", legShortStart, legShortStart2); final int nbCouponShortStart = legShortStart.getNumberOfPayments(); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition", 41, nbCouponShortStart); // nb coupons: 10Y+1M quarterly assertTrue("AnnuityCouponArithmeticAverageONSpreadDefinition: Short start", legShortStart.getNthPayment(0).getAccrualStartDate().getMonth().plus(1) == legShortStart.getNthPayment(0).getAccrualEndDate().getMonth()); final AnnuityDefinition<CouponONArithmeticAverageSpreadDefinition> legShortEnd = AnnuityCouponArithmeticAverageONSpreadDefinition.from(EFFECTIVE_DATE, maturity, NOTIONAL, SPREAD, true, PAY_TENOR, FEDFUND, PAY_LAG, BUSINESS_DAY, true, CALENDAR, StubType.SHORT_END); final int nbCouponShortEnd = legShortEnd.getNumberOfPayments(); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition", 41, nbCouponShortEnd); // nb coupons: 10Y+1M quarterly assertTrue("AnnuityCouponArithmeticAverageONSpreadDefinition: Short end", legShortEnd.getNthPayment(nbCouponShortEnd - 1).getAccrualStartDate().getMonth().plus(1) == legShortEnd.getNthPayment(nbCouponShortEnd - 1).getAccrualEndDate().getMonth()); final AnnuityDefinition<CouponONArithmeticAverageSpreadDefinition> legLongStart = AnnuityCouponArithmeticAverageONSpreadDefinition.from(EFFECTIVE_DATE, maturity, NOTIONAL, SPREAD, true, PAY_TENOR, FEDFUND, PAY_LAG, BUSINESS_DAY, true, CALENDAR, StubType.LONG_START); final int nbCouponLongStart = legLongStart.getNumberOfPayments(); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition", 40, nbCouponLongStart); // nb coupons: 10Y+1M quarterly assertTrue("AnnuityCouponArithmeticAverageONSpreadDefinition: Short start", legLongStart.getNthPayment(0).getAccrualStartDate().getMonth().plus(4) == legLongStart.getNthPayment(0).getAccrualEndDate().getMonth()); final AnnuityDefinition<CouponONArithmeticAverageSpreadDefinition> legLongEnd = AnnuityCouponArithmeticAverageONSpreadDefinition.from(EFFECTIVE_DATE, maturity, NOTIONAL, SPREAD, true, PAY_TENOR, FEDFUND, PAY_LAG, BUSINESS_DAY, true, CALENDAR, StubType.LONG_END); final int nbCouponLongEnd = legLongEnd.getNumberOfPayments(); assertEquals("AnnuityCouponArithmeticAverageONSpreadDefinition", 40, nbCouponLongEnd); // nb coupons: 10Y+1M quarterly assertTrue("AnnuityCouponArithmeticAverageONSpreadDefinition: Short end", legLongEnd.getNthPayment(nbCouponLongEnd - 1).getAccrualStartDate().getMonth().plus(4) == legLongEnd.getNthPayment(nbCouponLongEnd - 1).getAccrualEndDate().getMonth()); } }