/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.basics.schedule;
import static com.opengamma.strata.basics.schedule.Frequency.P1M;
import static com.opengamma.strata.basics.schedule.Frequency.P2M;
import static com.opengamma.strata.basics.schedule.Frequency.P3M;
import static com.opengamma.strata.basics.schedule.Frequency.TERM;
import static com.opengamma.strata.basics.schedule.RollConventions.DAY_17;
import static com.opengamma.strata.collect.TestHelper.assertSerialization;
import static com.opengamma.strata.collect.TestHelper.assertThrows;
import static com.opengamma.strata.collect.TestHelper.assertThrowsIllegalArg;
import static com.opengamma.strata.collect.TestHelper.coverImmutableBean;
import static com.opengamma.strata.collect.TestHelper.date;
import static java.time.Month.AUGUST;
import static java.time.Month.DECEMBER;
import static java.time.Month.JULY;
import static java.time.Month.JUNE;
import static java.time.Month.NOVEMBER;
import static java.time.Month.OCTOBER;
import static java.time.Month.SEPTEMBER;
import static org.testng.Assert.assertEquals;
import java.time.LocalDate;
import java.util.Optional;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Test {@link Schedule}.
*/
@Test
public class ScheduleTest {
private static final LocalDate JUN_15 = date(2014, JUNE, 15);
private static final LocalDate JUN_16 = date(2014, JUNE, 16);
private static final LocalDate JUL_04 = date(2014, JULY, 4);
private static final LocalDate JUL_16 = date(2014, JULY, 16);
private static final LocalDate JUL_17 = date(2014, JULY, 17);
private static final LocalDate AUG_17 = date(2014, AUGUST, 17);
private static final LocalDate SEP_17 = date(2014, SEPTEMBER, 17);
private static final LocalDate SEP_30 = date(2014, SEPTEMBER, 30);
private static final LocalDate OCT_15 = date(2014, OCTOBER, 15);
private static final LocalDate OCT_17 = date(2014, OCTOBER, 17);
private static final LocalDate NOV_17 = date(2014, NOVEMBER, 17);
private static final LocalDate DEC_17 = date(2014, DECEMBER, 17);
private static final SchedulePeriod P1_STUB = SchedulePeriod.of(JUL_04, JUL_17);
private static final SchedulePeriod P2_NORMAL = SchedulePeriod.of(JUL_17, AUG_17);
private static final SchedulePeriod P3_NORMAL = SchedulePeriod.of(AUG_17, SEP_17);
private static final SchedulePeriod P4_STUB = SchedulePeriod.of(SEP_17, SEP_30);
private static final SchedulePeriod P4_NORMAL = SchedulePeriod.of(SEP_17, OCT_17);
private static final SchedulePeriod P5_NORMAL = SchedulePeriod.of(OCT_17, NOV_17);
private static final SchedulePeriod P6_NORMAL = SchedulePeriod.of(NOV_17, DEC_17);
private static final SchedulePeriod P1_3 = SchedulePeriod.of(JUL_04, SEP_17);
private static final SchedulePeriod P2_3 = SchedulePeriod.of(JUL_17, SEP_17);
private static final SchedulePeriod P3_4 = SchedulePeriod.of(AUG_17, OCT_17);
private static final SchedulePeriod P4_5 = SchedulePeriod.of(SEP_17, NOV_17);
private static final SchedulePeriod P5_6 = SchedulePeriod.of(OCT_17, DEC_17);
private static final SchedulePeriod P2_4 = SchedulePeriod.of(JUL_17, OCT_17);
private static final SchedulePeriod P4_6 = SchedulePeriod.of(SEP_17, DEC_17);
//-------------------------------------------------------------------------
public void test_of_size0() {
assertThrowsIllegalArg(() -> Schedule.builder().periods(ImmutableList.of()));
}
public void test_ofTerm() {
Schedule test = Schedule.ofTerm(P1_STUB);
assertEquals(test.size(), 1);
assertEquals(test.isTerm(), true);
assertEquals(test.getFrequency(), TERM);
assertEquals(test.getRollConvention(), RollConventions.NONE);
assertEquals(test.isEndOfMonthConvention(), false);
assertEquals(test.getPeriods(), ImmutableList.of(P1_STUB));
assertEquals(test.getPeriod(0), P1_STUB);
assertEquals(test.getStartDate(), P1_STUB.getStartDate());
assertEquals(test.getEndDate(), P1_STUB.getEndDate());
assertEquals(test.getFirstPeriod(), P1_STUB);
assertEquals(test.getLastPeriod(), P1_STUB);
assertEquals(test.getInitialStub(), Optional.empty());
assertEquals(test.getFinalStub(), Optional.empty());
assertEquals(test.getRegularPeriods(), ImmutableList.of(P1_STUB));
assertThrows(() -> test.getPeriod(1), IndexOutOfBoundsException.class);
}
public void test_of_size2_initialStub() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test.size(), 2);
assertEquals(test.isTerm(), false);
assertEquals(test.getFrequency(), P1M);
assertEquals(test.getRollConvention(), DAY_17);
assertEquals(test.isEndOfMonthConvention(), false);
assertEquals(test.getPeriods(), ImmutableList.of(P1_STUB, P2_NORMAL));
assertEquals(test.getPeriod(0), P1_STUB);
assertEquals(test.getPeriod(1), P2_NORMAL);
assertEquals(test.getStartDate(), P1_STUB.getStartDate());
assertEquals(test.getEndDate(), P2_NORMAL.getEndDate());
assertEquals(test.getFirstPeriod(), P1_STUB);
assertEquals(test.getLastPeriod(), P2_NORMAL);
assertEquals(test.getInitialStub(), Optional.of(P1_STUB));
assertEquals(test.getFinalStub(), Optional.empty());
assertEquals(test.getRegularPeriods(), ImmutableList.of(P2_NORMAL));
assertThrows(() -> test.getPeriod(2), IndexOutOfBoundsException.class);
}
public void test_of_size2_noStub() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test.size(), 2);
assertEquals(test.isTerm(), false);
assertEquals(test.getFrequency(), P1M);
assertEquals(test.getRollConvention(), DAY_17);
assertEquals(test.isEndOfMonthConvention(), false);
assertEquals(test.getPeriods(), ImmutableList.of(P2_NORMAL, P3_NORMAL));
assertEquals(test.getPeriod(0), P2_NORMAL);
assertEquals(test.getPeriod(1), P3_NORMAL);
assertEquals(test.getStartDate(), P2_NORMAL.getStartDate());
assertEquals(test.getEndDate(), P3_NORMAL.getEndDate());
assertEquals(test.getFirstPeriod(), P2_NORMAL);
assertEquals(test.getLastPeriod(), P3_NORMAL);
assertEquals(test.getInitialStub(), Optional.empty());
assertEquals(test.getFinalStub(), Optional.empty());
assertEquals(test.getRegularPeriods(), ImmutableList.of(P2_NORMAL, P3_NORMAL));
assertThrows(() -> test.getPeriod(2), IndexOutOfBoundsException.class);
}
public void test_of_size2_finalStub() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P3_NORMAL, P4_STUB))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test.size(), 2);
assertEquals(test.isTerm(), false);
assertEquals(test.getFrequency(), P1M);
assertEquals(test.getRollConvention(), DAY_17);
assertEquals(test.isEndOfMonthConvention(), false);
assertEquals(test.getPeriods(), ImmutableList.of(P3_NORMAL, P4_STUB));
assertEquals(test.getPeriod(0), P3_NORMAL);
assertEquals(test.getPeriod(1), P4_STUB);
assertEquals(test.getStartDate(), P3_NORMAL.getStartDate());
assertEquals(test.getEndDate(), P4_STUB.getEndDate());
assertEquals(test.getFirstPeriod(), P3_NORMAL);
assertEquals(test.getLastPeriod(), P4_STUB);
assertEquals(test.getInitialStub(), Optional.empty());
assertEquals(test.getFinalStub(), Optional.of(P4_STUB));
assertEquals(test.getRegularPeriods(), ImmutableList.of(P3_NORMAL));
assertThrows(() -> test.getPeriod(2), IndexOutOfBoundsException.class);
}
public void test_of_size3_initialStub() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test.size(), 3);
assertEquals(test.isTerm(), false);
assertEquals(test.getFrequency(), P1M);
assertEquals(test.getRollConvention(), DAY_17);
assertEquals(test.isEndOfMonthConvention(), false);
assertEquals(test.getPeriods(), ImmutableList.of(P1_STUB, P2_NORMAL, P3_NORMAL));
assertEquals(test.getPeriod(0), P1_STUB);
assertEquals(test.getPeriod(1), P2_NORMAL);
assertEquals(test.getPeriod(2), P3_NORMAL);
assertEquals(test.getStartDate(), P1_STUB.getStartDate());
assertEquals(test.getEndDate(), P3_NORMAL.getEndDate());
assertEquals(test.getFirstPeriod(), P1_STUB);
assertEquals(test.getLastPeriod(), P3_NORMAL);
assertEquals(test.getInitialStub(), Optional.of(P1_STUB));
assertEquals(test.getFinalStub(), Optional.empty());
assertEquals(test.getRegularPeriods(), ImmutableList.of(P2_NORMAL, P3_NORMAL));
assertThrows(() -> test.getPeriod(3), IndexOutOfBoundsException.class);
}
public void test_of_size4_bothStubs() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_NORMAL, P3_NORMAL, P4_STUB))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test.size(), 4);
assertEquals(test.isTerm(), false);
assertEquals(test.getFrequency(), P1M);
assertEquals(test.getRollConvention(), DAY_17);
assertEquals(test.isEndOfMonthConvention(), false);
assertEquals(test.getPeriods(), ImmutableList.of(P1_STUB, P2_NORMAL, P3_NORMAL, P4_STUB));
assertEquals(test.getPeriod(0), P1_STUB);
assertEquals(test.getPeriod(1), P2_NORMAL);
assertEquals(test.getPeriod(2), P3_NORMAL);
assertEquals(test.getPeriod(3), P4_STUB);
assertEquals(test.getStartDate(), P1_STUB.getStartDate());
assertEquals(test.getEndDate(), P4_STUB.getEndDate());
assertEquals(test.getFirstPeriod(), P1_STUB);
assertEquals(test.getLastPeriod(), P4_STUB);
assertEquals(test.getInitialStub(), Optional.of(P1_STUB));
assertEquals(test.getFinalStub(), Optional.of(P4_STUB));
assertEquals(test.getRegularPeriods(), ImmutableList.of(P2_NORMAL, P3_NORMAL));
assertThrows(() -> test.getPeriod(4), IndexOutOfBoundsException.class);
}
//-------------------------------------------------------------------------
public void test_isEndOfMonthConvention_eom() {
// schedule doesn't make sense, but test only requires roll convention of EOM
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(RollConventions.EOM)
.build();
assertEquals(test.isEndOfMonthConvention(), true);
}
//-------------------------------------------------------------------------
public void test_getPeriodEndDate() {
// schedule doesn't make sense, but test only requires roll convention of EOM
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test.getPeriodEndDate(P2_NORMAL.getStartDate()), P2_NORMAL.getEndDate());
assertEquals(test.getPeriodEndDate(P2_NORMAL.getStartDate().plusDays(1)), P2_NORMAL.getEndDate());
assertEquals(test.getPeriodEndDate(P3_NORMAL.getStartDate()), P3_NORMAL.getEndDate());
assertEquals(test.getPeriodEndDate(P3_NORMAL.getStartDate().plusDays(1)), P3_NORMAL.getEndDate());
assertThrowsIllegalArg(() -> test.getPeriodEndDate(P2_NORMAL.getStartDate().minusDays(1)));
}
//-------------------------------------------------------------------------
public void test_mergeToTerm() {
Schedule testNormal = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(testNormal.mergeToTerm(), Schedule.ofTerm(P1_3));
assertEquals(testNormal.mergeToTerm().mergeToTerm(), Schedule.ofTerm(P1_3));
}
//-------------------------------------------------------------------------
public void test_mergeRegular_group2_within2_initialStub() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_3))
.frequency(P2M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(2, true), expected);
assertEquals(test.mergeRegular(2, false), expected);
}
public void test_mergeRegular_group2_within2_noStub() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_3))
.frequency(P2M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(2, true), expected);
assertEquals(test.mergeRegular(2, false), expected);
}
public void test_mergeRegular_group2_within2_finalStub() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_STUB))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_3, P4_STUB))
.frequency(P2M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(2, true), expected);
assertEquals(test.mergeRegular(2, false), expected);
}
public void test_mergeRegular_group2_within3_forwards() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_3, P4_NORMAL))
.frequency(P2M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(2, true), expected);
}
public void test_mergeRegular_group2_within3_backwards() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_4))
.frequency(P2M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(2, false), expected);
}
public void test_mergeRegular_group2_within5_forwards() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_3, P4_5, P6_NORMAL))
.frequency(P2M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(2, true), expected);
}
public void test_mergeRegular_group2_within5_backwards() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_4, P5_6))
.frequency(P2M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(2, false), expected);
}
public void test_mergeRegular_group3_within5_forwards() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_4, P5_6))
.frequency(P3M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(3, true), expected);
}
public void test_mergeRegular_group3_within5_backwards() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(P2_3, P4_6))
.frequency(P3M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(3, false), expected);
}
public void test_mergeRegular_termNoChange() {
Schedule test = Schedule.ofTerm(P1_STUB);
assertEquals(test.mergeRegular(2, true), test);
assertEquals(test.mergeRegular(2, false), test);
}
public void test_mergeRegular_groupSizeOneNoChange() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test.mergeRegular(1, true), test);
assertEquals(test.mergeRegular(1, false), test);
}
public void test_mergeRegular_groupSizeInvalid() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertThrowsIllegalArg(() -> test.mergeRegular(0, true));
assertThrowsIllegalArg(() -> test.mergeRegular(0, false));
assertThrowsIllegalArg(() -> test.mergeRegular(-1, true));
assertThrowsIllegalArg(() -> test.mergeRegular(-1, false));
}
//-------------------------------------------------------------------------
public void test_toAdjusted() {
SchedulePeriod period1 = SchedulePeriod.of(JUN_15, SEP_17);
SchedulePeriod period2 = SchedulePeriod.of(SEP_17, SEP_30);
Schedule test = Schedule.builder()
.periods(period1, period2)
.frequency(P3M)
.rollConvention(DAY_17)
.build();
assertEquals(test.toAdjusted(date -> date), test);
assertEquals(test.toAdjusted(date -> date.equals(JUN_15) ? JUN_16 : date), Schedule.builder()
.periods(SchedulePeriod.of(JUN_16, SEP_17, JUN_15, SEP_17), period2)
.frequency(P3M)
.rollConvention(DAY_17)
.build());
}
public void test_toUnadjusted() {
SchedulePeriod a = SchedulePeriod.of(JUL_17, OCT_17, JUL_16, OCT_15);
SchedulePeriod b = SchedulePeriod.of(JUL_16, OCT_15, JUL_16, OCT_15);
Schedule test = Schedule.builder()
.periods(ImmutableList.of(a))
.frequency(P1M)
.rollConvention(DAY_17)
.build()
.toUnadjusted();
Schedule expected = Schedule.builder()
.periods(ImmutableList.of(b))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertEquals(test, expected);
}
//-------------------------------------------------------------------------
public void coverage_equals() {
Schedule a = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule b = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
Schedule c = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P3M)
.rollConvention(DAY_17)
.build();
Schedule d = Schedule.builder()
.periods(ImmutableList.of(P2_NORMAL, P3_NORMAL, P4_NORMAL, P5_NORMAL, P6_NORMAL))
.frequency(P1M)
.rollConvention(RollConventions.DAY_1)
.build();
assertEquals(a.equals(a), true);
assertEquals(a.equals(b), false);
assertEquals(a.equals(c), false);
assertEquals(a.equals(d), false);
}
//-------------------------------------------------------------------------
public void coverage_builder() {
Schedule.Builder builder = Schedule.builder();
builder
.periods(P1_STUB)
.frequency(P1M)
.rollConvention(DAY_17)
.build();
}
//-------------------------------------------------------------------------
public void coverage() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
coverImmutableBean(test);
}
public void test_serialization() {
Schedule test = Schedule.builder()
.periods(ImmutableList.of(P1_STUB, P2_NORMAL))
.frequency(P1M)
.rollConvention(DAY_17)
.build();
assertSerialization(test);
}
}