/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.interestrate.payments.derivative;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.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.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.util.money.Currency;
import com.opengamma.util.time.DateUtils;
/**
*
*/
public class CouponIborAverageFixingDatesTest {
private static final Period TENOR = Period.ofMonths(1);
private static final int SETTLEMENT_DAYS = 2;
private static final Calendar CALENDAR = new MondayToFridayCalendar("A");
private static final DayCount DAY_COUNT_INDEX = DayCounts.ACT_360;
private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventions.MODIFIED_FOLLOWING;
private static final boolean IS_EOM = true;
private static final Currency CUR = Currency.EUR;
private static final IborIndex INDEX = new IborIndex(CUR, TENOR, SETTLEMENT_DAYS, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM, "Index");
private static final int NUM_OBS = 6;
private static final ZonedDateTime ACCRUAL_START_DATE = DateUtils.getUTCDate(2011, 1, 6);
private static final ZonedDateTime ACCRUAL_END_DATE = DateUtils.getUTCDate(2011, 7, 4);
private static final ZonedDateTime PAYMENT_DATE = DateUtils.getUTCDate(2011, 7, 6);
// The above dates are not standard but selected for insure correct testing.
private static final ZonedDateTime[] FIXING_DATES = new ZonedDateTime[NUM_OBS];
private static final double[] WEIGHTS = new double[NUM_OBS];
static {
for (int i = 0; i < NUM_OBS; ++i) {
FIXING_DATES[i] = DateUtils.getUTCDate(2011, i + 1, 3);
WEIGHTS[i] = 2. * (NUM_OBS - i) / NUM_OBS / (NUM_OBS + 1.);
}
}
private static final DayCount DAY_COUNT_PAYMENT = DayCounts.ACT_365;
private static final double ACCRUAL_FACTOR = DAY_COUNT_PAYMENT.getDayCountFraction(ACCRUAL_START_DATE, ACCRUAL_END_DATE);
private static final double NOTIONAL = 1000000;
private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2010, 12, 27);
private static ZonedDateTime[] EXP_START_DATES = new ZonedDateTime[NUM_OBS];
private static ZonedDateTime[] EXP_END_DATES = new ZonedDateTime[NUM_OBS];
static {
for (int i = 0; i < NUM_OBS; ++i) {
EXP_START_DATES[i] = ScheduleCalculator.getAdjustedDate(FIXING_DATES[i], INDEX.getSpotLag(), CALENDAR);
EXP_END_DATES[i] = ScheduleCalculator.getAdjustedDate(EXP_START_DATES[i], INDEX.getTenor(), INDEX.getBusinessDayConvention(), CALENDAR, INDEX.isEndOfMonth());
}
}
private static final double PAYMENT_TIME = TimeCalculator.getTimeBetween(REFERENCE_DATE, PAYMENT_DATE);
private static final double[] FIXING_TIMES = TimeCalculator.getTimeBetween(REFERENCE_DATE, FIXING_DATES);
private static final double[] FIXING_PERIOD_START_TIMES = TimeCalculator.getTimeBetween(REFERENCE_DATE, EXP_START_DATES);
private static final double[] FIXING_PERIOD_END_TIMES = TimeCalculator.getTimeBetween(REFERENCE_DATE, EXP_END_DATES);
private static final double[] FIX_ACC_FACTORS = new double[NUM_OBS];
static {
for (int i = 0; i < NUM_OBS; ++i) {
FIX_ACC_FACTORS[i] = INDEX.getDayCount().getDayCountFraction(EXP_START_DATES[i], EXP_END_DATES[i]);
}
}
private static final CouponIborAverageFixingDates DFN1 = new CouponIborAverageFixingDates(CUR, PAYMENT_TIME, ACCRUAL_FACTOR, NOTIONAL, INDEX,
FIXING_TIMES, WEIGHTS, FIXING_PERIOD_START_TIMES, FIXING_PERIOD_END_TIMES, FIX_ACC_FACTORS, 0);
private static final CouponIborAverageFixingDates DFN2 = DFN1.withNotional(NOTIONAL);
/**
*
*/
@SuppressWarnings("unused")
@Test
public void exceptionTest() {
try {
new CouponIborAverageFixingDates(Currency.GBP, PAYMENT_TIME, ACCRUAL_FACTOR, NOTIONAL, INDEX, FIXING_TIMES, WEIGHTS, FIXING_PERIOD_START_TIMES,
FIXING_PERIOD_END_TIMES, FIX_ACC_FACTORS, 0);
throw new RuntimeException();
} catch (final Exception e) {
assertEquals("index currency different from payment currency", e.getMessage());
}
final double[] shortWeight = Arrays.copyOf(WEIGHTS, NUM_OBS - 1);
try {
new CouponIborAverageFixingDates(CUR, PAYMENT_TIME, ACCRUAL_FACTOR, NOTIONAL, INDEX, FIXING_TIMES, shortWeight, FIXING_PERIOD_START_TIMES,
FIXING_PERIOD_END_TIMES, FIX_ACC_FACTORS, 0);
throw new RuntimeException();
} catch (final Exception e) {
assertEquals("weight length different from fixingTime length", e.getMessage());
}
final double[] shortStartTimes = Arrays.copyOf(FIXING_PERIOD_START_TIMES, NUM_OBS - 1);
try {
new CouponIborAverageFixingDates(CUR, PAYMENT_TIME, ACCRUAL_FACTOR, NOTIONAL, INDEX, FIXING_TIMES, WEIGHTS, shortStartTimes,
FIXING_PERIOD_END_TIMES, FIX_ACC_FACTORS, 0);
throw new RuntimeException();
} catch (final Exception e) {
assertEquals("fixingPeriodStartTime length different from fixingTime length", e.getMessage());
}
final double[] shortEndTimes = Arrays.copyOf(FIXING_PERIOD_END_TIMES, NUM_OBS - 1);
try {
new CouponIborAverageFixingDates(CUR, PAYMENT_TIME, ACCRUAL_FACTOR, NOTIONAL, INDEX, FIXING_TIMES, WEIGHTS, FIXING_PERIOD_START_TIMES,
shortEndTimes, FIX_ACC_FACTORS, 0);
throw new RuntimeException();
} catch (final Exception e) {
assertEquals("fixingPeriodEndTime length different from fixingTime length", e.getMessage());
}
final double[] shortfcc = Arrays.copyOf(FIX_ACC_FACTORS, NUM_OBS - 1);
try {
new CouponIborAverageFixingDates(CUR, PAYMENT_TIME, ACCRUAL_FACTOR, NOTIONAL, INDEX, FIXING_TIMES, WEIGHTS, FIXING_PERIOD_START_TIMES,
FIXING_PERIOD_END_TIMES, shortfcc, 0);
throw new RuntimeException();
} catch (final Exception e) {
assertEquals("getFixingPeriodAccrualFactor length different from fixingTime length", e.getMessage());
}
}
/**
*
*/
@Test
public void consistencyTest() {
final CouponIborAverageFixingDates dfn1WithDouble = DFN1.withNotional(NOTIONAL * 2);
assertEquals(DFN1.getIndex(), DFN2.getIndex());
assertEquals(DFN1.getIndex(), dfn1WithDouble.getIndex());
for (int i = 0; i < NUM_OBS; ++i) {
assertEquals(DFN1.getWeight()[i], DFN2.getWeight()[i]);
assertEquals(DFN1.getFixingTime()[i], DFN2.getFixingTime()[i]);
assertEquals(DFN1.getFixingPeriodStartTime()[i], DFN2.getFixingPeriodStartTime()[i]);
assertEquals(DFN1.getFixingPeriodEndTime()[i], DFN2.getFixingPeriodEndTime()[i]);
assertEquals(DFN1.getFixingPeriodAccrualFactor()[i], DFN2.getFixingPeriodAccrualFactor()[i]);
assertEquals(DFN1.getWeight()[i], dfn1WithDouble.getWeight()[i]);
assertEquals(DFN1.getFixingTime()[i], dfn1WithDouble.getFixingTime()[i]);
assertEquals(DFN1.getFixingPeriodStartTime()[i], dfn1WithDouble.getFixingPeriodStartTime()[i]);
assertEquals(DFN1.getFixingPeriodEndTime()[i], dfn1WithDouble.getFixingPeriodEndTime()[i]);
assertEquals(DFN1.getFixingPeriodAccrualFactor()[i], dfn1WithDouble.getFixingPeriodAccrualFactor()[i]);
}
assertTrue(DFN1.equals(DFN2));
assertTrue(DFN1.hashCode() == DFN2.hashCode());
assertFalse(DFN1.hashCode() == dfn1WithDouble.hashCode());
assertFalse(DFN1.equals(dfn1WithDouble));
}
}