/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.instrument.annuity;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.util.Arrays;
import org.testng.annotations.Test;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.instrument.index.IborIndex;
import com.opengamma.analytics.financial.instrument.payment.CouponFixedDefinition;
import com.opengamma.analytics.financial.instrument.payment.CouponIborDefinition;
import com.opengamma.analytics.financial.instrument.payment.PaymentDefinition;
import com.opengamma.analytics.financial.instrument.payment.PaymentFixedDefinition;
import com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixed;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFloating;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment;
import com.opengamma.analytics.financial.interestrate.payments.derivative.PaymentFixed;
import com.opengamma.analytics.financial.schedule.NoHolidayCalendar;
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.DayCounts;
import com.opengamma.timeseries.precise.zdt.ImmutableZonedDateTimeDoubleTimeSeries;
import com.opengamma.timeseries.precise.zdt.ZonedDateTimeDoubleTimeSeries;
import com.opengamma.util.money.Currency;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.DateUtils;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public class AnnuityDefinitionTest {
private static final Calendar CALENDAR = new NoHolidayCalendar();
private static final PaymentFixedDefinition[] FIXED_PAYMENTS;
private static final PaymentDefinition[] FIXED_FLOAT_PAYMENTS;
private static final Currency CCY = Currency.AUD;
private static final AnnuityDefinition<PaymentFixedDefinition> FIXED_DEFINITION;
private static final AnnuityDefinition<PaymentDefinition> FIXED_FLOAT_DEFINITION;
private static ZonedDateTime FIXING_DATE;
private static final double FIXING_RATE = 0.02;
private static ZonedDateTimeDoubleTimeSeries FIXING_TS;
private static final double ACCRUAL_FACTOR = 1. / 12;
private static final double FLOAT_NOTIONAL = 1234;
static {
final int n = 10;
FIXED_PAYMENTS = new PaymentFixedDefinition[n];
FIXED_FLOAT_PAYMENTS = new PaymentDefinition[n];
ZonedDateTime date = DateUtils.getUTCDate(2011, 1, 1);
final IborIndex index = new IborIndex(CCY, Period.ofMonths(3), 0, DayCounts.ACT_360,
BusinessDayConventions.FOLLOWING, false, "Ibor");
for (int i = 0; i < n; i++) {
FIXED_PAYMENTS[i] = new PaymentFixedDefinition(CCY, date, 1000);
FIXED_FLOAT_PAYMENTS[i] = (i < 8 ? new CouponFixedDefinition(CCY, date, date.minusMonths(1), date, ACCRUAL_FACTOR, 1000, 0.05) : CouponIborDefinition.from(date, date.minusMonths(1), date,
ACCRUAL_FACTOR, FLOAT_NOTIONAL, date.minusMonths(1), index, new MondayToFridayCalendar("A")));
if (i == 8) {
FIXING_DATE = date.minusMonths(1);
}
date = date.plusMonths(1);
}
FIXED_DEFINITION = new AnnuityDefinition<>(FIXED_PAYMENTS, CALENDAR);
FIXED_FLOAT_DEFINITION = new AnnuityDefinition<>(FIXED_FLOAT_PAYMENTS, CALENDAR);
FIXING_TS = ImmutableZonedDateTimeDoubleTimeSeries.of(FIXING_DATE, FIXING_RATE);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullPayments() {
new AnnuityDefinition<>((PaymentFixedDefinition[]) null, null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testWithNullPayment() {
final PaymentFixedDefinition[] payments = Arrays.copyOf(FIXED_PAYMENTS, FIXED_PAYMENTS.length);
payments[0] = null;
new AnnuityDefinition<>(payments, null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testEmptyPayments() {
new AnnuityDefinition<>(new PaymentFixedDefinition[0], null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testDifferentCurrencyPayments() {
final PaymentFixedDefinition[] payments = Arrays.copyOf(FIXED_PAYMENTS, FIXED_PAYMENTS.length);
payments[0] = new PaymentFixedDefinition(Currency.CAD, DateUtils.getUTCDate(2011, 1, 1), 1000);
new AnnuityDefinition<>(payments, null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testConversionNullDate1() {
FIXED_DEFINITION.toDerivative(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testConversionNullDate2() {
FIXED_DEFINITION.toDerivative(null, FIXING_TS);
}
@Test
public void testObject() {
assertEquals(FIXED_PAYMENTS, FIXED_DEFINITION.getPayments());
for (int i = 0; i < FIXED_PAYMENTS.length; i++) {
assertEquals(FIXED_PAYMENTS[i], FIXED_DEFINITION.getNthPayment(i));
}
assertEquals(CCY, FIXED_DEFINITION.getCurrency());
assertEquals(FIXED_PAYMENTS.length, FIXED_DEFINITION.getNumberOfPayments());
AnnuityDefinition<PaymentFixedDefinition> other = new AnnuityDefinition<>(FIXED_PAYMENTS, CALENDAR);
assertEquals(FIXED_DEFINITION, other);
assertEquals(FIXED_DEFINITION.hashCode(), other.hashCode());
final PaymentFixedDefinition[] payments = Arrays.copyOf(FIXED_PAYMENTS, FIXED_PAYMENTS.length);
payments[0] = new PaymentFixedDefinition(CCY, DateUtils.getUTCDate(2011, 1, 1), 10000);
other = new AnnuityDefinition<>(payments, CALENDAR);
assertFalse(other.equals(FIXED_DEFINITION));
}
@Test
public void testPayer() {
assertFalse(FIXED_DEFINITION.isPayer());
PaymentFixedDefinition[] payments = new PaymentFixedDefinition[FIXED_PAYMENTS.length];
for (int i = 0; i < FIXED_PAYMENTS.length; i++) {
payments[i] = new PaymentFixedDefinition(CCY, DateUtils.getUTCDate(2011, 1, 1), -1000);
}
assertTrue(new AnnuityDefinition<>(payments, CALENDAR).isPayer());
payments = Arrays.copyOf(FIXED_PAYMENTS, FIXED_PAYMENTS.length);
payments[0] = new PaymentFixedDefinition(CCY, DateUtils.getUTCDate(2011, 1, 1), 0);
assertFalse(FIXED_DEFINITION.isPayer());
}
@Test
public void testConversionFixed() {
final ZonedDateTime date = DateUtils.getUTCDate(2011, 5, 10);
final Annuity<? extends Payment> annuity1 = FIXED_DEFINITION.toDerivative(date);
final Annuity<? extends Payment> annuity2 = FIXED_DEFINITION.toDerivative(date, FIXING_TS);
assertEquals(FIXED_DEFINITION.getNumberOfPayments(), 10);
assertEquals(annuity1.getNumberOfPayments(), 5);
for (int i = 0; i < annuity1.getNumberOfPayments(); i++) {
assertTrue(annuity1.getNthPayment(i) instanceof PaymentFixed);
assertEquals(annuity1.getNthPayment(i), FIXED_DEFINITION.getNthPayment(i + 5).toDerivative(date));
assertEquals(annuity2.getNthPayment(i), FIXED_DEFINITION.getNthPayment(i + 5).toDerivative(date));
}
}
@Test
public void testConversionFixedFloat() {
final ZonedDateTime date = DateUtils.getUTCDate(2011, 5, 10);
final Annuity<? extends Payment> annuity = FIXED_FLOAT_DEFINITION.toDerivative(date, FIXING_TS);
assertEquals(FIXED_DEFINITION.getNumberOfPayments(), 10);
assertEquals(annuity.getNumberOfPayments(), 5);
for (int i = 0; i < annuity.getNumberOfPayments(); i++) {
if (i < 3) {
assertTrue(annuity.getNthPayment(i) instanceof CouponFixed);
assertEquals(annuity.getNthPayment(i), FIXED_FLOAT_DEFINITION.getNthPayment(i + 5).toDerivative(date));
} else {
assertTrue(annuity.getNthPayment(i) instanceof CouponFloating);
assertEquals(annuity.getNthPayment(i), FIXED_FLOAT_DEFINITION.getNthPayment(i + 5).toDerivative(date));
}
}
}
}