/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.basics.date;
import static com.opengamma.strata.basics.date.DayCounts.ACT_360;
import static com.opengamma.strata.basics.date.DayCounts.ACT_364;
import static com.opengamma.strata.basics.date.DayCounts.ACT_365F;
import static com.opengamma.strata.basics.date.DayCounts.ACT_365L;
import static com.opengamma.strata.basics.date.DayCounts.ACT_365_25;
import static com.opengamma.strata.basics.date.DayCounts.ACT_365_ACTUAL;
import static com.opengamma.strata.basics.date.DayCounts.ACT_ACT_AFB;
import static com.opengamma.strata.basics.date.DayCounts.ACT_ACT_ICMA;
import static com.opengamma.strata.basics.date.DayCounts.ACT_ACT_ISDA;
import static com.opengamma.strata.basics.date.DayCounts.ACT_ACT_YEAR;
import static com.opengamma.strata.basics.date.DayCounts.NL_365;
import static com.opengamma.strata.basics.date.DayCounts.ONE_ONE;
import static com.opengamma.strata.basics.date.DayCounts.THIRTY_360_ISDA;
import static com.opengamma.strata.basics.date.DayCounts.THIRTY_360_PSA;
import static com.opengamma.strata.basics.date.DayCounts.THIRTY_EPLUS_360;
import static com.opengamma.strata.basics.date.DayCounts.THIRTY_E_360;
import static com.opengamma.strata.basics.date.DayCounts.THIRTY_E_360_ISDA;
import static com.opengamma.strata.basics.date.DayCounts.THIRTY_U_360;
import static com.opengamma.strata.basics.date.DayCounts.THIRTY_U_360_EOM;
import static com.opengamma.strata.basics.schedule.Frequency.P12M;
import static com.opengamma.strata.basics.schedule.Frequency.P3M;
import static com.opengamma.strata.basics.schedule.Frequency.P6M;
import static com.opengamma.strata.collect.TestHelper.assertJodaConvert;
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.assertThrowsRuntime;
import static com.opengamma.strata.collect.TestHelper.coverEnum;
import static com.opengamma.strata.collect.TestHelper.coverPrivateConstructor;
import static com.opengamma.strata.collect.TestHelper.date;
import static org.testng.Assert.assertEquals;
import java.time.LocalDate;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.opengamma.strata.basics.date.DayCount.ScheduleInfo;
import com.opengamma.strata.basics.schedule.Frequency;
/**
* Test {@link DayCount}.
*/
@Test
public class DayCountTest {
private static final LocalDate JAN_01 = LocalDate.of(2010, 1, 1);
private static final LocalDate JAN_02 = LocalDate.of(2010, 1, 2);
private static final LocalDate JUL_01 = LocalDate.of(2010, 7, 1);
private static final LocalDate JAN_01_NEXT = LocalDate.of(2011, 1, 1);
private static final double TOLERANCE_ZERO = 0d;
//-------------------------------------------------------------------------
@DataProvider(name = "types")
static Object[][] data_types() {
StandardDayCounts[] conv = StandardDayCounts.values();
Object[][] result = new Object[conv.length][];
for (int i = 0; i < conv.length; i++) {
result[i] = new Object[] {conv[i]};
}
return result;
}
@Test(dataProvider = "types")
public void test_null(DayCount type) {
assertThrowsRuntime(() -> type.yearFraction(null, JAN_01));
assertThrowsRuntime(() -> type.yearFraction(JAN_01, null));
assertThrowsRuntime(() -> type.yearFraction(null, null));
assertThrowsRuntime(() -> type.days(null, JAN_01));
assertThrowsRuntime(() -> type.days(JAN_01, null));
assertThrowsRuntime(() -> type.days(null, null));
}
@Test(dataProvider = "types")
public void test_wrongOrder(DayCount type) {
assertThrowsIllegalArg(() -> type.yearFraction(JAN_02, JAN_01));
assertThrowsIllegalArg(() -> type.days(JAN_02, JAN_01));
}
@Test(dataProvider = "types")
public void test_same(DayCount type) {
if (type != ONE_ONE) {
assertEquals(type.yearFraction(JAN_02, JAN_02), 0d, TOLERANCE_ZERO);
assertEquals(type.days(JAN_02, JAN_02), 0);
}
}
@Test(dataProvider = "types")
public void test_halfYear(DayCount type) {
// sanity check to ensure that half year has fraction close to half
if (type != ONE_ONE) {
ScheduleInfo info = new Info(JAN_01, JAN_01_NEXT, JAN_01_NEXT, false, P12M);
assertEquals(type.yearFraction(JAN_01, JUL_01, info), 0.5d, 0.01d);
assertEquals(type.days(JAN_01, JUL_01), 182, 2);
}
}
@Test(dataProvider = "types")
public void test_wholeYear(DayCount type) {
// sanity check to ensure that one year has fraction close to one
if (type != ONE_ONE) {
ScheduleInfo info = new Info(JAN_01, JAN_01_NEXT, JAN_01_NEXT, false, P12M);
assertEquals(type.yearFraction(JAN_01, JAN_01_NEXT, info), 1d, 0.02d);
assertEquals(type.days(JAN_01, JAN_01_NEXT), 365, 5);
}
}
//-------------------------------------------------------------------------
// use flag to make it clearer when an adjustment is happening
private static Double SIMPLE_30_360 = new Double(Double.NaN);
private static int SIMPLE_30_360Days = 0;
@DataProvider(name = "yearFraction")
static Object[][] data_yearFraction() {
return new Object[][] {
{ONE_ONE, 2011, 12, 28, 2012, 2, 28, 1d},
{ONE_ONE, 2011, 12, 28, 2012, 2, 29, 1d},
{ONE_ONE, 2011, 12, 28, 2012, 3, 1, 1d},
{ONE_ONE, 2011, 12, 28, 2016, 2, 28, 1d},
{ONE_ONE, 2011, 12, 28, 2016, 2, 29, 1d},
{ONE_ONE, 2011, 12, 28, 2016, 3, 1, 1d},
{ONE_ONE, 2012, 2, 29, 2012, 3, 29, 1d},
{ONE_ONE, 2012, 2, 29, 2012, 3, 28, 1d},
{ONE_ONE, 2012, 3, 1, 2012, 3, 28, 1d},
//-------------------------------------------------------
{ACT_ACT_ISDA, 2011, 12, 28, 2012, 2, 28, (4d / 365d + 58d / 366d)},
{ACT_ACT_ISDA, 2011, 12, 28, 2012, 2, 29, (4d / 365d + 59d / 366d)},
{ACT_ACT_ISDA, 2011, 12, 28, 2012, 3, 1, (4d / 365d + 60d / 366d)},
{ACT_ACT_ISDA, 2011, 12, 28, 2016, 2, 28, (4d / 365d + 58d / 366d + 4)},
{ACT_ACT_ISDA, 2011, 12, 28, 2016, 2, 29, (4d / 365d + 59d / 366d + 4)},
{ACT_ACT_ISDA, 2011, 12, 28, 2016, 3, 1, (4d / 365d + 60d / 366d + 4)},
{ACT_ACT_ISDA, 2012, 2, 29, 2012, 3, 29, 29d / 366d},
{ACT_ACT_ISDA, 2012, 2, 29, 2012, 3, 28, 28d / 366d},
{ACT_ACT_ISDA, 2012, 3, 1, 2012, 3, 28, 27d / 366d},
//-------------------------------------------------------
{ACT_ACT_AFB, 2011, 12, 28, 2012, 2, 28, (62d / 365d)},
{ACT_ACT_AFB, 2011, 12, 28, 2012, 2, 29, (63d / 365d)},
{ACT_ACT_AFB, 2011, 12, 28, 2012, 3, 1, (64d / 366d)},
{ACT_ACT_AFB, 2011, 12, 28, 2016, 2, 28, (62d / 365d) + 4},
{ACT_ACT_AFB, 2011, 12, 28, 2016, 2, 29, (63d / 365d) + 4},
{ACT_ACT_AFB, 2011, 12, 28, 2016, 3, 1, (64d / 366d) + 4},
{ACT_ACT_AFB, 2012, 2, 28, 2012, 3, 28, 29d / 366d},
{ACT_ACT_AFB, 2012, 2, 29, 2012, 3, 28, 28d / 366d},
{ACT_ACT_AFB, 2012, 3, 1, 2012, 3, 28, 27d / 365d},
//-------------------------------------------------------
{ACT_ACT_YEAR, 2011, 12, 28, 2012, 2, 28, (62d / 366d)},
{ACT_ACT_YEAR, 2011, 12, 28, 2012, 2, 29, (63d / 366d)},
{ACT_ACT_YEAR, 2011, 12, 28, 2012, 3, 1, (64d / 366d)},
{ACT_ACT_YEAR, 2011, 12, 28, 2016, 2, 28, (62d / 366d) + 4},
{ACT_ACT_YEAR, 2011, 12, 28, 2016, 2, 29, (63d / 366d) + 4},
{ACT_ACT_YEAR, 2011, 12, 28, 2016, 3, 1, (64d / 366d) + 4},
{ACT_ACT_YEAR, 2012, 2, 28, 2012, 3, 28, 29d / 366d},
{ACT_ACT_YEAR, 2012, 2, 29, 2012, 3, 28, 28d / 365d},
{ACT_ACT_YEAR, 2012, 3, 1, 2012, 3, 28, 27d / 365d},
{ACT_ACT_YEAR, 2011, 2, 28, 2011, 3, 2, (2d / 365d)},
{ACT_ACT_YEAR, 2011, 3, 1, 2011, 3, 2, (1d / 366d)},
{ACT_ACT_YEAR, 2012, 2, 28, 2016, 3, 2, (3d / 366d) + 4},
{ACT_ACT_YEAR, 2012, 2, 29, 2016, 3, 2, (2d / 365d) + 4},
//-------------------------------------------------------
{ACT_365_ACTUAL, 2011, 12, 28, 2012, 2, 28, (62d / 365d)},
{ACT_365_ACTUAL, 2011, 12, 28, 2012, 2, 29, (63d / 366d)},
{ACT_365_ACTUAL, 2011, 12, 28, 2012, 3, 1, (64d / 366d)},
{ACT_365_ACTUAL, 2011, 12, 28, 2016, 2, 28, ((62d + 366d + 365d + 365d + 365d) / 366d)},
{ACT_365_ACTUAL, 2011, 12, 28, 2016, 2, 29, ((63d + 366d + 365d + 365d + 365d) / 366d)},
{ACT_365_ACTUAL, 2011, 12, 28, 2016, 3, 1, ((64d + 366d + 365d + 365d + 365d) / 366d)},
{ACT_365_ACTUAL, 2012, 2, 28, 2012, 3, 28, 29d / 366d},
{ACT_365_ACTUAL, 2012, 2, 29, 2012, 3, 28, 28d / 365d},
{ACT_365_ACTUAL, 2012, 3, 1, 2012, 3, 28, 27d / 365d},
//-------------------------------------------------------
{ACT_360, 2011, 12, 28, 2012, 2, 28, (62d / 360d)},
{ACT_360, 2011, 12, 28, 2012, 2, 29, (63d / 360d)},
{ACT_360, 2011, 12, 28, 2012, 3, 1, (64d / 360d)},
{ACT_360, 2011, 12, 28, 2016, 2, 28, ((62d + 366d + 365d + 365d + 365d) / 360d)},
{ACT_360, 2011, 12, 28, 2016, 2, 29, ((63d + 366d + 365d + 365d + 365d) / 360d)},
{ACT_360, 2011, 12, 28, 2016, 3, 1, ((64d + 366d + 365d + 365d + 365d) / 360d)},
{ACT_360, 2012, 2, 28, 2012, 3, 28, 29d / 360d},
{ACT_360, 2012, 2, 29, 2012, 3, 28, 28d / 360d},
{ACT_360, 2012, 3, 1, 2012, 3, 28, 27d / 360d},
//-------------------------------------------------------
{ACT_364, 2011, 12, 28, 2012, 2, 28, (62d / 364d)},
{ACT_364, 2011, 12, 28, 2012, 2, 29, (63d / 364d)},
{ACT_364, 2011, 12, 28, 2012, 3, 1, (64d / 364d)},
{ACT_364, 2011, 12, 28, 2016, 2, 28, ((62d + 366d + 365d + 365d + 365d) / 364d)},
{ACT_364, 2011, 12, 28, 2016, 2, 29, ((63d + 366d + 365d + 365d + 365d) / 364d)},
{ACT_364, 2011, 12, 28, 2016, 3, 1, ((64d + 366d + 365d + 365d + 365d) / 364d)},
{ACT_364, 2012, 2, 28, 2012, 3, 28, 29d / 364d},
{ACT_364, 2012, 2, 29, 2012, 3, 28, 28d / 364d},
{ACT_364, 2012, 3, 1, 2012, 3, 28, 27d / 364d},
//-------------------------------------------------------
{ACT_365F, 2011, 12, 28, 2012, 2, 28, (62d / 365d)},
{ACT_365F, 2011, 12, 28, 2012, 2, 29, (63d / 365d)},
{ACT_365F, 2011, 12, 28, 2012, 3, 1, (64d / 365d)},
{ACT_365F, 2011, 12, 28, 2016, 2, 28, ((62d + 366d + 365d + 365d + 365d) / 365d)},
{ACT_365F, 2011, 12, 28, 2016, 2, 29, ((63d + 366d + 365d + 365d + 365d) / 365d)},
{ACT_365F, 2011, 12, 28, 2016, 3, 1, ((64d + 366d + 365d + 365d + 365d) / 365d)},
{ACT_365F, 2012, 2, 28, 2012, 3, 28, 29d / 365d},
{ACT_365F, 2012, 2, 29, 2012, 3, 28, 28d / 365d},
{ACT_365F, 2012, 3, 1, 2012, 3, 28, 27d / 365d},
//-------------------------------------------------------
{ACT_365_25, 2011, 12, 28, 2012, 2, 28, (62d / 365.25d)},
{ACT_365_25, 2011, 12, 28, 2012, 2, 29, (63d / 365.25d)},
{ACT_365_25, 2011, 12, 28, 2012, 3, 1, (64d / 365.25d)},
{ACT_365_25, 2011, 12, 28, 2016, 2, 28, ((62d + 366d + 365d + 365d + 365d) / 365.25d)},
{ACT_365_25, 2011, 12, 28, 2016, 2, 29, ((63d + 366d + 365d + 365d + 365d) / 365.25d)},
{ACT_365_25, 2011, 12, 28, 2016, 3, 1, ((64d + 366d + 365d + 365d + 365d) / 365.25d)},
{ACT_365_25, 2012, 2, 28, 2012, 3, 28, 29d / 365.25d},
{ACT_365_25, 2012, 2, 29, 2012, 3, 28, 28d / 365.25d},
{ACT_365_25, 2012, 3, 1, 2012, 3, 28, 27d / 365.25d},
//-------------------------------------------------------
{NL_365, 2011, 12, 28, 2012, 2, 28, (62d / 365d)},
{NL_365, 2011, 12, 28, 2012, 2, 29, (62d / 365d)},
{NL_365, 2011, 12, 28, 2012, 3, 1, (63d / 365d)},
{NL_365, 2011, 12, 28, 2016, 2, 28, ((62d + 365d + 365d + 365d + 365d) / 365d)},
{NL_365, 2011, 12, 28, 2016, 2, 29, ((62d + 365d + 365d + 365d + 365d) / 365d)},
{NL_365, 2011, 12, 28, 2016, 3, 1, ((63d + 365d + 365d + 365d + 365d) / 365d)},
{NL_365, 2012, 2, 28, 2012, 3, 28, 28d / 365d},
{NL_365, 2012, 2, 29, 2012, 3, 28, 28d / 365d},
{NL_365, 2012, 3, 1, 2012, 3, 28, 27d / 365d},
{NL_365, 2011, 12, 1, 2012, 12, 1, 365d / 365d},
//-------------------------------------------------------
{THIRTY_360_ISDA, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360},
{THIRTY_360_ISDA, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360},
{THIRTY_360_ISDA, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360},
{THIRTY_360_ISDA, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360},
{THIRTY_360_ISDA, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360},
{THIRTY_360_ISDA, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 2, 29, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_360_ISDA, 2011, 2, 28, 2012, 2, 28, SIMPLE_30_360},
{THIRTY_360_ISDA, 2011, 2, 28, 2012, 2, 29, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 2, 29, 2016, 2, 29, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 5, 29, 2013, 8, 31, SIMPLE_30_360},
{THIRTY_360_ISDA, 2012, 5, 30, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_ISDA, 2012, 5, 31, 2013, 8, 30, calc360(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_ISDA, 2012, 5, 31, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30)},
//-------------------------------------------------------
{THIRTY_360_PSA, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360},
{THIRTY_360_PSA, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360},
{THIRTY_360_PSA, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360},
{THIRTY_360_PSA, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360},
{THIRTY_360_PSA, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360},
{THIRTY_360_PSA, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360},
{THIRTY_360_PSA, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_360_PSA, 2012, 2, 29, 2012, 3, 28, calc360(2012, 2, 30, 2012, 3, 28)},
{THIRTY_360_PSA, 2011, 2, 28, 2012, 2, 28, calc360(2011, 2, 30, 2012, 2, 28)},
{THIRTY_360_PSA, 2011, 2, 28, 2012, 2, 29, calc360(2011, 2, 30, 2012, 2, 29)},
{THIRTY_360_PSA, 2012, 2, 29, 2016, 2, 29, calc360(2012, 2, 30, 2016, 2, 29)},
{THIRTY_360_PSA, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_360_PSA, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360},
{THIRTY_360_PSA, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_360_PSA, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_360_PSA, 2012, 5, 29, 2013, 8, 31, SIMPLE_30_360},
{THIRTY_360_PSA, 2012, 5, 30, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_PSA, 2012, 5, 31, 2013, 8, 30, calc360(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_PSA, 2012, 5, 31, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30)},
//-------------------------------------------------------
{THIRTY_E_360, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360},
{THIRTY_E_360, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360},
{THIRTY_E_360, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360},
{THIRTY_E_360, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360},
{THIRTY_E_360, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360},
{THIRTY_E_360, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360},
{THIRTY_E_360, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_E_360, 2012, 2, 29, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_E_360, 2011, 2, 28, 2012, 2, 28, SIMPLE_30_360},
{THIRTY_E_360, 2011, 2, 28, 2012, 2, 29, SIMPLE_30_360},
{THIRTY_E_360, 2012, 2, 29, 2016, 2, 29, SIMPLE_30_360},
{THIRTY_E_360, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_E_360, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360},
{THIRTY_E_360, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_E_360, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_E_360, 2012, 5, 29, 2013, 8, 31, calc360(2012, 5, 29, 2013, 8, 30)},
{THIRTY_E_360, 2012, 5, 30, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30)},
{THIRTY_E_360, 2012, 5, 31, 2013, 8, 30, calc360(2012, 5, 30, 2013, 8, 30)},
{THIRTY_E_360, 2012, 5, 31, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30)},
//-------------------------------------------------------
{THIRTY_EPLUS_360, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 2, 29, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2011, 2, 28, 2012, 2, 28, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2011, 2, 28, 2012, 2, 29, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 2, 29, 2016, 2, 29, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360},
{THIRTY_EPLUS_360, 2012, 5, 29, 2013, 8, 31, calc360(2012, 5, 29, 2013, 9, 1)},
{THIRTY_EPLUS_360, 2012, 5, 30, 2013, 8, 31, calc360(2012, 5, 30, 2013, 9, 1)},
{THIRTY_EPLUS_360, 2012, 5, 31, 2013, 8, 30, calc360(2012, 5, 30, 2013, 8, 30)},
{THIRTY_EPLUS_360, 2012, 5, 31, 2013, 8, 31, calc360(2012, 5, 30, 2013, 9, 1)},
};
}
private static double calc360(int y1, int m1, int d1, int y2, int m2, int d2) {
return ((y2 - y1) * 360 + (m2 - m1) * 30 + (d2 - d1)) / 360d;
}
private static int calc360Days(int y1, int m1, int d1, int y2, int m2, int d2) {
return (y2 - y1) * 360 + (m2 - m1) * 30 + (d2 - d1);
}
@Test(dataProvider = "yearFraction")
public void test_yearFraction(DayCount dayCount, int y1, int m1, int d1, int y2, int m2, int d2, Double value) {
double expected = (value == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : value);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
assertEquals(dayCount.yearFraction(date1, date2), expected, TOLERANCE_ZERO);
}
@Test(dataProvider = "yearFraction")
public void test_relativeYearFraction(
DayCount dayCount, int y1, int m1, int d1, int y2, int m2, int d2, Double value) {
double expected = (value == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : value);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
assertEquals(dayCount.relativeYearFraction(date1, date2), expected, TOLERANCE_ZERO);
}
@Test(dataProvider = "yearFraction")
public void test_relativeYearFraction_reverse(
DayCount dayCount, int y1, int m1, int d1, int y2, int m2, int d2, Double value) {
double expected = (value == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : value);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
assertEquals(dayCount.relativeYearFraction(date2, date1), -expected, TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
@DataProvider(name = "days")
static Object[][] data_days() {
return new Object[][] {
{ONE_ONE, 2011, 12, 28, 2012, 2, 28, 1},
{ONE_ONE, 2011, 12, 28, 2012, 2, 29, 1},
{ONE_ONE, 2011, 12, 28, 2012, 3, 1, 1},
{ONE_ONE, 2011, 12, 28, 2016, 2, 28, 1},
{ONE_ONE, 2011, 12, 28, 2016, 2, 29, 1},
{ONE_ONE, 2011, 12, 28, 2016, 3, 1, 1},
{ONE_ONE, 2012, 2, 29, 2012, 3, 29, 1},
{ONE_ONE, 2012, 2, 29, 2012, 3, 28, 1},
{ONE_ONE, 2012, 3, 1, 2012, 3, 28, 1},
//-------------------------------------------------------
{ACT_ACT_ISDA, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_ACT_ISDA, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_ACT_ISDA, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_ACT_ISDA, 2011, 12, 28, 2016, 2, 28, 1523},
{ACT_ACT_ISDA, 2011, 12, 28, 2016, 2, 29, 1524},
{ACT_ACT_ISDA, 2011, 12, 28, 2016, 3, 1, 1525},
//-------------------------------------------------------
{ACT_ACT_AFB, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_ACT_AFB, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_ACT_AFB, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_ACT_AFB, 2011, 12, 28, 2016, 2, 28, 1523},
{ACT_ACT_AFB, 2011, 12, 28, 2016, 2, 29, 1524},
{ACT_ACT_AFB, 2011, 12, 28, 2016, 3, 1, 1525},
//-------------------------------------------------------
{ACT_ACT_YEAR, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_ACT_YEAR, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_ACT_YEAR, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_ACT_YEAR, 2011, 12, 28, 2016, 2, 28, 1523},
{ACT_ACT_YEAR, 2011, 12, 28, 2016, 2, 29, 1524},
{ACT_ACT_YEAR, 2011, 12, 28, 2016, 3, 1, 1525},
//-------------------------------------------------------
{ACT_365_ACTUAL, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_365_ACTUAL, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_365_ACTUAL, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_365_ACTUAL, 2011, 12, 28, 2016, 2, 28, 62 + 366 + 365 + 365 + 365},
{ACT_365_ACTUAL, 2011, 12, 28, 2016, 2, 29, 63 + 366 + 365 + 365 + 365},
{ACT_365_ACTUAL, 2011, 12, 28, 2016, 3, 1, 64 + 366 + 365 + 365 + 365},
{ACT_365_ACTUAL, 2012, 2, 28, 2012, 3, 28, 29},
{ACT_365_ACTUAL, 2012, 2, 29, 2012, 3, 28, 28},
{ACT_365_ACTUAL, 2012, 3, 1, 2012, 3, 28, 27},
//-------------------------------------------------------
{ACT_360, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_360, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_360, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_360, 2011, 12, 28, 2016, 2, 28, 62 + 366 + 365 + 365 + 365},
{ACT_360, 2011, 12, 28, 2016, 2, 29, 63 + 366 + 365 + 365 + 365},
{ACT_360, 2011, 12, 28, 2016, 3, 1, 64 + 366 + 365 + 365 + 365},
//-------------------------------------------------------
{ACT_364, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_364, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_364, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_364, 2011, 12, 28, 2016, 2, 28, 62 + 366 + 365 + 365 + 365},
{ACT_364, 2011, 12, 28, 2016, 2, 29, 63 + 366 + 365 + 365 + 365},
{ACT_364, 2011, 12, 28, 2016, 3, 1, 64 + 366 + 365 + 365 + 365},
{ACT_364, 2012, 2, 28, 2012, 3, 28, 29},
{ACT_364, 2012, 2, 29, 2012, 3, 28, 28},
{ACT_364, 2012, 3, 1, 2012, 3, 28, 27},
//-------------------------------------------------------
{ACT_365F, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_365F, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_365F, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_365F, 2011, 12, 28, 2016, 2, 28, 62 + 366 + 365 + 365 + 365},
{ACT_365F, 2011, 12, 28, 2016, 2, 29, 63 + 366 + 365 + 365 + 365},
{ACT_365F, 2011, 12, 28, 2016, 3, 1, 64 + 366 + 365 + 365 + 365},
{ACT_365F, 2012, 2, 28, 2012, 3, 28, 29},
{ACT_365F, 2012, 2, 29, 2012, 3, 28, 28},
{ACT_365F, 2012, 3, 1, 2012, 3, 28, 27},
//-------------------------------------------------------
{ACT_365_25, 2011, 12, 28, 2012, 2, 28, 62},
{ACT_365_25, 2011, 12, 28, 2012, 2, 29, 63},
{ACT_365_25, 2011, 12, 28, 2012, 3, 1, 64},
{ACT_365_25, 2011, 12, 28, 2016, 2, 28, 62 + 366 + 365 + 365 + 365},
{ACT_365_25, 2011, 12, 28, 2016, 2, 29, 63 + 366 + 365 + 365 + 365},
{ACT_365_25, 2011, 12, 28, 2016, 3, 1, 64 + 366 + 365 + 365 + 365},
{ACT_365_25, 2012, 2, 28, 2012, 3, 28, 29},
{ACT_365_25, 2012, 2, 29, 2012, 3, 28, 28},
{ACT_365_25, 2012, 3, 1, 2012, 3, 28, 27},
//-------------------------------------------------------
{NL_365, 2011, 12, 28, 2012, 2, 28, 62},
{NL_365, 2011, 12, 28, 2012, 2, 29, 62},
{NL_365, 2011, 12, 28, 2012, 3, 1, 63},
{NL_365, 2011, 12, 28, 2016, 2, 28, 62 + 365 + 365 + 365 + 365},
{NL_365, 2011, 12, 28, 2016, 2, 29, 62 + 365 + 365 + 365 + 365},
{NL_365, 2011, 12, 28, 2016, 3, 1, 63 + 365 + 365 + 365 + 365},
{NL_365, 2012, 2, 28, 2012, 3, 28, 28},
{NL_365, 2012, 2, 29, 2012, 3, 28, 28},
{NL_365, 2012, 3, 1, 2012, 3, 28, 27},
{NL_365, 2011, 12, 1, 2012, 12, 1, 365},
//-------------------------------------------------------
{THIRTY_360_ISDA, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 2, 29, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2011, 2, 28, 2012, 2, 28, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2011, 2, 28, 2012, 2, 29, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 2, 29, 2016, 2, 29, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 5, 29, 2013, 8, 31, SIMPLE_30_360Days},
{THIRTY_360_ISDA, 2012, 5, 30, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_ISDA, 2012, 5, 31, 2013, 8, 30, calc360Days(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_ISDA, 2012, 5, 31, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 8, 30)},
//-------------------------------------------------------
{THIRTY_360_PSA, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2012, 2, 29, 2012, 3, 28, calc360Days(2012, 2, 30, 2012, 3, 28)},
{THIRTY_360_PSA, 2011, 2, 28, 2012, 2, 28, calc360Days(2011, 2, 30, 2012, 2, 28)},
{THIRTY_360_PSA, 2011, 2, 28, 2012, 2, 29, calc360Days(2011, 2, 30, 2012, 2, 29)},
{THIRTY_360_PSA, 2012, 2, 29, 2016, 2, 29, calc360Days(2012, 2, 30, 2016, 2, 29)},
{THIRTY_360_PSA, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2012, 5, 29, 2013, 8, 31, SIMPLE_30_360Days},
{THIRTY_360_PSA, 2012, 5, 30, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_PSA, 2012, 5, 31, 2013, 8, 30, calc360Days(2012, 5, 30, 2013, 8, 30)},
{THIRTY_360_PSA, 2012, 5, 31, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 8, 30)},
//-------------------------------------------------------
{THIRTY_E_360, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360Days},
{THIRTY_E_360, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360Days},
{THIRTY_E_360, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360Days},
{THIRTY_E_360, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360Days},
{THIRTY_E_360, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360Days},
{THIRTY_E_360, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 2, 29, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_E_360, 2011, 2, 28, 2012, 2, 28, SIMPLE_30_360Days},
{THIRTY_E_360, 2011, 2, 28, 2012, 2, 29, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 2, 29, 2016, 2, 29, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_E_360, 2012, 5, 29, 2013, 8, 31, calc360Days(2012, 5, 29, 2013, 8, 30)},
{THIRTY_E_360, 2012, 5, 30, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 8, 30)},
{THIRTY_E_360, 2012, 5, 31, 2013, 8, 30, calc360Days(2012, 5, 30, 2013, 8, 30)},
{THIRTY_E_360, 2012, 5, 31, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 8, 30)},
//-------------------------------------------------------
{THIRTY_EPLUS_360, 2011, 12, 28, 2012, 2, 28, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2011, 12, 28, 2012, 2, 29, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2011, 12, 28, 2012, 3, 1, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2011, 12, 28, 2016, 2, 28, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2011, 12, 28, 2016, 2, 29, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2011, 12, 28, 2016, 3, 1, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 2, 28, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 2, 29, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2011, 2, 28, 2012, 2, 28, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2011, 2, 28, 2012, 2, 29, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 2, 29, 2016, 2, 29, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 3, 1, 2012, 3, 28, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 5, 30, 2013, 8, 29, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 5, 29, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 5, 30, 2013, 8, 30, SIMPLE_30_360Days},
{THIRTY_EPLUS_360, 2012, 5, 29, 2013, 8, 31, calc360Days(2012, 5, 29, 2013, 9, 1)},
{THIRTY_EPLUS_360, 2012, 5, 30, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 9, 1)},
{THIRTY_EPLUS_360, 2012, 5, 31, 2013, 8, 30, calc360Days(2012, 5, 30, 2013, 8, 30)},
{THIRTY_EPLUS_360, 2012, 5, 31, 2013, 8, 31, calc360Days(2012, 5, 30, 2013, 9, 1)},
};
}
@Test(dataProvider = "days")
public void test_days(DayCount dayCount, int y1, int m1, int d1, int y2, int m2, int d2, int value) {
int expected = (value == SIMPLE_30_360Days ? calc360Days(y1, m1, d1, y2, m2, d2) : value);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
assertEquals(dayCount.days(date1, date2), expected, TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
@DataProvider(name = "30U360")
static Object[][] data_30U360() {
return new Object[][] {
{2011, 12, 28, 2012, 2, 28, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2012, 2, 29, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2012, 3, 1, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2016, 2, 28, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2016, 2, 29, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2016, 3, 1, SIMPLE_30_360, SIMPLE_30_360},
{2012, 2, 28, 2012, 3, 28, SIMPLE_30_360, SIMPLE_30_360},
{2012, 2, 29, 2012, 3, 28, SIMPLE_30_360, calc360(2012, 2, 30, 2012, 3, 28)},
{2012, 2, 29, 2012, 3, 30, SIMPLE_30_360, calc360(2012, 2, 30, 2012, 3, 30)},
{2012, 2, 29, 2012, 3, 31, SIMPLE_30_360, calc360(2012, 2, 30, 2012, 3, 30)},
{2012, 2, 29, 2013, 2, 28, SIMPLE_30_360, calc360(2012, 2, 30, 2013, 2, 30)},
{2011, 2, 28, 2012, 2, 28, SIMPLE_30_360, calc360(2011, 2, 30, 2012, 2, 28)},
{2011, 2, 28, 2012, 2, 29, SIMPLE_30_360, calc360(2011, 2, 30, 2012, 2, 30)},
{2012, 2, 29, 2016, 2, 29, SIMPLE_30_360, calc360(2012, 2, 30, 2016, 2, 30)},
{2012, 3, 1, 2012, 3, 28, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 30, 2013, 8, 29, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 29, 2013, 8, 30, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 30, 2013, 8, 30, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 29, 2013, 8, 31, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 30, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30), calc360(2012, 5, 30, 2013, 8, 30)},
{2012, 5, 31, 2013, 8, 30, calc360(2012, 5, 30, 2013, 8, 30), calc360(2012, 5, 30, 2013, 8, 30)},
{2012, 5, 31, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30), calc360(2012, 5, 30, 2013, 8, 30)},
};
}
@Test(dataProvider = "30U360")
public void test_yearFraction_30U360_notEom(
int y1, int m1, int d1, int y2, int m2, int d2, Double valueNotEOM, Double valueEOM) {
double expected = (valueNotEOM == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : valueNotEOM);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
ScheduleInfo info = new Info(false);
assertEquals(THIRTY_U_360.yearFraction(date1, date2, info), expected, TOLERANCE_ZERO);
}
@Test(dataProvider = "30U360")
public void test_yearFraction_30U360_eom(
int y1, int m1, int d1, int y2, int m2, int d2, Double valueNotEOM, Double valueEOM) {
double expected = (valueEOM == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : valueEOM);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
ScheduleInfo info = new Info(true);
assertEquals(THIRTY_U_360.yearFraction(date1, date2, info), expected, TOLERANCE_ZERO);
}
@Test(dataProvider = "30U360")
public void test_yearFraction_30360ISDA(
int y1, int m1, int d1, int y2, int m2, int d2, Double valueNotEOM, Double valueEOM) {
double expected = (valueNotEOM == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : valueNotEOM);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
ScheduleInfo info = new Info(true);
assertEquals(THIRTY_360_ISDA.yearFraction(date1, date2, info), expected, TOLERANCE_ZERO);
}
@Test(dataProvider = "30U360")
public void test_yearFraction_30U360EOM(
int y1, int m1, int d1, int y2, int m2, int d2, Double valueNotEOM, Double valueEOM) {
double expected = (valueEOM == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : valueEOM);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
ScheduleInfo info = new Info(true);
assertEquals(THIRTY_U_360_EOM.yearFraction(date1, date2, info), expected, TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
@DataProvider(name = "30E360ISDA")
static Object[][] data_30E360ISDA() {
return new Object[][] {
{2011, 12, 28, 2012, 2, 28, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2012, 2, 29, calc360(2011, 12, 28, 2012, 2, 30), SIMPLE_30_360},
{2011, 12, 28, 2012, 3, 1, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2016, 2, 28, SIMPLE_30_360, SIMPLE_30_360},
{2011, 12, 28, 2016, 2, 29, calc360(2011, 12, 28, 2016, 2, 30), SIMPLE_30_360},
{2011, 12, 28, 2016, 3, 1, SIMPLE_30_360, SIMPLE_30_360},
{2012, 2, 28, 2012, 3, 28, SIMPLE_30_360, SIMPLE_30_360},
{2012, 2, 29, 2012, 3, 28, calc360(2012, 2, 30, 2012, 3, 28), calc360(2012, 2, 30, 2012, 3, 28)},
{2011, 2, 28, 2012, 2, 28, calc360(2011, 2, 30, 2012, 2, 28), calc360(2011, 2, 30, 2012, 2, 28)},
{2011, 2, 28, 2012, 2, 29, calc360(2011, 2, 30, 2012, 2, 30), calc360(2011, 2, 30, 2012, 2, 29)},
{2012, 2, 29, 2016, 2, 29, calc360(2012, 2, 30, 2016, 2, 30), calc360(2012, 2, 30, 2016, 2, 29)},
{2012, 3, 1, 2012, 3, 28, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 30, 2013, 8, 29, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 29, 2013, 8, 30, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 30, 2013, 8, 30, SIMPLE_30_360, SIMPLE_30_360},
{2012, 5, 29, 2013, 8, 31, calc360(2012, 5, 29, 2013, 8, 30), calc360(2012, 5, 29, 2013, 8, 30)},
{2012, 5, 30, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30), calc360(2012, 5, 30, 2013, 8, 30)},
{2012, 5, 31, 2013, 8, 30, calc360(2012, 5, 30, 2013, 8, 30), calc360(2012, 5, 30, 2013, 8, 30)},
{2012, 5, 31, 2013, 8, 31, calc360(2012, 5, 30, 2013, 8, 30), calc360(2012, 5, 30, 2013, 8, 30)},
};
}
@Test(dataProvider = "30E360ISDA")
public void test_yearFraction_30E360ISDA_notMaturity(
int y1, int m1, int d1, int y2, int m2, int d2, Double valueNotMaturity, Double valueMaturity) {
double expected = (valueNotMaturity == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : valueNotMaturity);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
ScheduleInfo info = new Info(false);
assertEquals(THIRTY_E_360_ISDA.yearFraction(date1, date2, info), expected, TOLERANCE_ZERO);
}
@Test(dataProvider = "30E360ISDA")
public void test_yearFraction_30E360ISDA_maturity(
int y1, int m1, int d1, int y2, int m2, int d2, Double valueNotMaturity, Double valueMaturity) {
double expected = (valueMaturity == SIMPLE_30_360 ? calc360(y1, m1, d1, y2, m2, d2) : valueMaturity);
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
ScheduleInfo info = new Info(null, date2, null, false, P3M);
assertEquals(THIRTY_E_360_ISDA.yearFraction(date1, date2, info), expected, TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
// AFB day count is poorly defined, so tests were used to identify a sensible interpretation
// 1) The ISDA use of "Calculation Period" is a translation of "Periode d'Application"
// where the original simply meant the period the day count is applied over
// and NOT the regular periodic schedule (ISDA's definition of "Calculation Period").
// 2) The ISDA "clarification" for rolling backward does not appear in the original French.
// The ISDA rule produce strange results (in comments below) which can be avoided.
// OpenGamma interprets that February 29th should only be chosen if the end date of the period
// is February 29th and the rolled back date is a leap year.
// 3) No document indicates precisely when to stop rolling back and treat the remainder as a fraction
// OpenGamma interprets that rolling back in whole years continues until the remainder
// is less than one year, and possibly zero if two dates are an exact number of years apart
// 4) In all cases, the rule has strange effects when interest through a period encounters
// February 29th and the denominator suddenly changes from 365 to 366 for the rest of the year
@DataProvider(name = "ACTACTAFB")
static Object[][] data_ACTACTAFB() {
return new Object[][] {
// example from the original French specification
{1994, 2, 10, 1997, 6, 30, 140d / 365d + 3},
{1994, 2, 10, 1994, 6, 30, 140d / 365d},
// simple examples that are less than one year long
{2004, 2, 10, 2005, 2, 10, 1d},
{2004, 2, 28, 2005, 2, 28, 1d},
{2004, 2, 29, 2005, 2, 28, 365d / 366d},
{2004, 3, 1, 2005, 3, 1, 1d},
// examples over one year, from a fixed start date
// from Feb28 2003
{2003, 2, 28, 2005, 2, 27, 1d + (364d / 365d)},
{2003, 2, 28, 2005, 2, 28, 2d},
{2003, 2, 28, 2005, 3, 1, 2d + (1d / 365d)},
{2003, 2, 28, 2008, 2, 27, 4d + (364d / 365d)},
{2003, 2, 28, 2008, 2, 28, 5d},
{2003, 2, 28, 2008, 2, 29, 5d},
{2003, 2, 28, 2008, 3, 1, 5d + (1d / 365d)},
// from Feb28 2004
{2004, 2, 28, 2005, 2, 27, (365d / 366d)},
{2004, 2, 28, 2005, 2, 28, 1d},
{2004, 2, 28, 2005, 3, 1, 1d + (2d / 366d)},
{2004, 2, 28, 2008, 2, 27, 3d + (365d / 366d)},
{2004, 2, 28, 2008, 2, 28, 4d}, // ISDA end-of-February would give (4d + (1d / 365d))
{2004, 2, 28, 2008, 2, 29, 4d + (1d / 365d)},
{2004, 2, 28, 2008, 3, 1, 4d + (2d / 366d)},
// from Feb29 2004
{2004, 2, 29, 2005, 2, 28, 365d / 366d},
{2004, 2, 29, 2005, 3, 1, 1d + (1d / 366d)},
{2004, 2, 29, 2008, 2, 27, 3d + (364d / 366d)},
{2004, 2, 29, 2008, 2, 28, 3d + (365d / 366d)}, // ISDA end-of-February would give (4d)
{2004, 2, 29, 2008, 2, 29, 4d},
{2004, 2, 29, 2008, 3, 1, 4d + (1d / 366d)},
// from Mar01 2004
{2004, 3, 1, 2005, 2, 28, 364d / 365d},
{2004, 3, 1, 2005, 3, 1, 1d},
{2004, 3, 1, 2008, 2, 27, 3d + (363d / 365d)},
{2004, 3, 1, 2008, 2, 28, 3d + (364d / 365d)},
{2004, 3, 1, 2008, 2, 29, 3d + (364d / 365d)},
{2004, 3, 1, 2008, 3, 1, 4d},
// from Mar01 2003
{2003, 3, 1, 2005, 2, 27, 1d + (363d / 365d)},
{2003, 3, 1, 2005, 2, 28, 1d + (364d / 365d)}, // ISDA end-of-February would give (2d)
{2003, 3, 1, 2005, 3, 1, 2d},
{2003, 3, 1, 2008, 2, 27, 4d + (363d / 365d)}, // ISDA end-of-February would give (5d)
{2003, 3, 1, 2008, 2, 28, 4d + (364d / 365d)},
{2003, 3, 1, 2008, 2, 29, 5d},
{2003, 3, 1, 2008, 3, 1, 5d},
// examples over one year, up to a fixed end date (not relevant in real life)
// up to Mar01 from leap year
{2004, 2, 28, 2006, 3, 1, 2d + (2d / 366d)},
{2004, 2, 29, 2006, 3, 1, 2d + (1d / 366d)},
{2004, 3, 1, 2006, 3, 1, 2d},
// up to Mar01 from non leap year
{2005, 2, 28, 2007, 3, 1, 2d + (1d / 365d)},
{2005, 3, 1, 2007, 3, 1, 2d},
// up to Feb28 in leap year from leap year
{2004, 2, 27, 2008, 2, 28, 4d + (1d / 365d)}, // ISDA end-of-February would give (4d + (2d / 365d))
{2004, 2, 28, 2008, 2, 28, 4d}, // ISDA end-of-February would give (4d + (1d / 365d))
{2004, 2, 29, 2008, 2, 28, 3d + (365d / 366d)}, // ISDA end-of-February would give (4d)
{2004, 3, 1, 2008, 2, 28, 3d + (364d / 365d)},
// up to Feb28 in leap year from non leap year
{2006, 2, 27, 2008, 2, 28, 2d + (1d / 365d)},
{2006, 2, 28, 2008, 2, 28, 2d},
{2006, 3, 1, 2008, 2, 28, 1d + (364d / 365d)},
// up to Feb29 in leap year from leap year
{2004, 2, 28, 2008, 2, 29, 4d + (1d / 365d)},
{2004, 2, 29, 2008, 2, 29, 4d},
{2004, 3, 1, 2008, 2, 29, 3d + (364d / 365d)},
// up to Feb29 in leap year from non leap year
{2006, 2, 27, 2008, 2, 29, 2d + (1d / 365d)},
{2006, 2, 28, 2008, 2, 29, 2d},
{2006, 3, 1, 2008, 2, 29, 1d + (364d / 365d)},
};
}
@Test(dataProvider = "ACTACTAFB")
public void test_yearFraction_ACTACTAFB(
int y1, int m1, int d1, int y2, int m2, int d2, double expected) {
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
assertEquals(ACT_ACT_AFB.yearFraction(date1, date2), expected, TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
@DataProvider(name = "ACT365L")
static Object[][] data_ACT365L() {
return new Object[][] {
{2011, 12, 28, 2012, 2, 28, P12M, 2012, 2, 28, 62d / 365d},
{2011, 12, 28, 2012, 2, 28, P12M, 2012, 2, 29, 62d / 366d},
{2011, 12, 28, 2012, 2, 28, P12M, 2012, 3, 1, 62d / 366d},
{2011, 12, 28, 2012, 2, 29, P12M, 2012, 2, 29, 63d / 366d},
{2011, 12, 28, 2012, 2, 29, P12M, 2012, 3, 1, 63d / 366d},
{2011, 12, 28, 2012, 2, 28, P6M, 2012, 2, 28, 62d / 366d},
{2011, 12, 28, 2012, 2, 28, P6M, 2012, 2, 29, 62d / 366d},
{2011, 12, 28, 2012, 2, 28, P6M, 2012, 3, 1, 62d / 366d},
{2011, 12, 28, 2012, 2, 29, P6M, 2012, 2, 29, 63d / 366d},
{2011, 12, 28, 2012, 2, 29, P6M, 2012, 3, 1, 63d / 366d},
{2010, 12, 28, 2011, 2, 28, P6M, 2011, 2, 28, 62d / 365d},
{2010, 12, 28, 2011, 2, 28, P6M, 2011, 3, 1, 62d / 365d},
};
}
@Test(dataProvider = "ACT365L")
public void test_yearFraction_ACT365L(
int y1, int m1, int d1, int y2, int m2, int d2, Frequency freq, int y3, int m3, int d3, double expected) {
LocalDate date1 = LocalDate.of(y1, m1, d1);
LocalDate date2 = LocalDate.of(y2, m2, d2);
ScheduleInfo info = new Info(null, null, LocalDate.of(y3, m3, d3), false, freq);
assertEquals(ACT_365L.yearFraction(date1, date2, info), expected, TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
public void test_actActIcma_singlePeriod() {
LocalDate start = LocalDate.of(2003, 11, 1);
LocalDate end = LocalDate.of(2004, 5, 1);
ScheduleInfo info = new Info(start, end, end, true, P6M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end.minusDays(1), info), (181d / (182d * 2d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (182d / (182d * 2d)), TOLERANCE_ZERO);
}
public void test_actActIcma_longInitialStub_eomFlagEom_short() {
// nominals, 2011-08-31 (P91D) 2011-11-30 (P91D) 2012-02-29
LocalDate start = LocalDate.of(2011, 10, 1);
LocalDate periodEnd = LocalDate.of(2012, 2, 29);
LocalDate end = LocalDate.of(2011, 11, 12); // before first nominal
ScheduleInfo info = new Info(start, periodEnd.plus(P3M), periodEnd, true, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (42d / (91d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_longInitialStub_eomFlagEom_long() {
// nominals, 2011-08-31 (P91D) 2011-11-30 (P91D) 2012-02-29
LocalDate start = LocalDate.of(2011, 10, 1);
LocalDate periodEnd = LocalDate.of(2012, 2, 29);
LocalDate end = LocalDate.of(2012, 1, 12); // after first nominal
ScheduleInfo info = new Info(start, periodEnd.plus(P3M), periodEnd, true, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (60d / (91d * 4d)) + (43d / (91d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_veryLongInitialStub_eomFlagEom_short() {
// nominals, 2011-05-31 (P92D) 2011-08-31 (P91D) 2011-11-30 (P91D) 2012-02-29
LocalDate start = LocalDate.of(2011, 7, 1);
LocalDate periodEnd = LocalDate.of(2012, 2, 29);
LocalDate end = LocalDate.of(2011, 8, 12); // before first nominal
ScheduleInfo info = new Info(start, periodEnd.plus(P3M), periodEnd, true, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (42d / (92d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_veryLongInitialStub_eomFlagEom_mid() {
// nominals, 2011-05-31 (P92D) 2011-08-31 (P91D) 2011-11-30 (P91D) 2012-02-29
LocalDate start = LocalDate.of(2011, 7, 1);
LocalDate periodEnd = LocalDate.of(2012, 2, 29);
LocalDate end = LocalDate.of(2011, 11, 12);
ScheduleInfo info = new Info(start, periodEnd.plus(P3M), periodEnd, true, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (61d / (92d * 4d)) + (73d / (91d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_longInitialStub_notEomFlagEom_short() {
// nominals, 2011-08-29 (P92D) 2011-11-29 (P92D) 2012-02-29
LocalDate start = LocalDate.of(2011, 10, 1);
LocalDate periodEnd = LocalDate.of(2012, 2, 29);
LocalDate end = LocalDate.of(2011, 11, 12); // before first nominal
ScheduleInfo info = new Info(start, periodEnd.plus(P3M), periodEnd, false, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (42d / (92d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_longInitialStub_notEomFlagEom_long() {
// nominals, 2011-08-29 (P92D) 2011-11-29 (P92D) 2012-02-29
LocalDate start = LocalDate.of(2011, 10, 1);
LocalDate periodEnd = LocalDate.of(2012, 2, 29);
LocalDate end = LocalDate.of(2012, 1, 12); // after first nominal
ScheduleInfo info = new Info(start, periodEnd.plus(P3M), periodEnd, false, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (59d / (92d * 4d)) + (44d / (92d * 4d)), TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
public void test_actActIcma_longFinalStub_eomFlagEom_short() {
// nominals, 2011-08-31 (P91D) 2011-11-30 (P91D) 2012-02-29
LocalDate start = LocalDate.of(2011, 8, 31);
LocalDate periodEnd = LocalDate.of(2012, 1, 31);
LocalDate end = LocalDate.of(2011, 11, 12); // before first nominal
ScheduleInfo info = new Info(start.minus(P3M), periodEnd, periodEnd, true, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (73d / (91d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_longFinalStub_eomFlagEom_long() {
// nominals, 2011-08-31 (P91D) 2011-11-30 (P91D) 2012-02-29
LocalDate start = LocalDate.of(2011, 8, 31);
LocalDate periodEnd = LocalDate.of(2012, 1, 31);
LocalDate end = LocalDate.of(2012, 1, 12); // after first nominal
ScheduleInfo info = new Info(start.minus(P3M), periodEnd, periodEnd, true, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (91d / (91d * 4d)) + (43d / (91d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_longFinalStub_notEomFlagEom_short() {
// nominals, 2012-02-29 (P90D) 2012-05-29 (P92D) 2012-08-29
LocalDate start = LocalDate.of(2012, 2, 29);
LocalDate periodEnd = LocalDate.of(2012, 7, 31);
LocalDate end = LocalDate.of(2012, 4, 1); // before first nominal
ScheduleInfo info = new Info(start.minus(P3M), periodEnd, periodEnd, false, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (32d / (90d * 4d)), TOLERANCE_ZERO);
}
public void test_actActIcma_longFinalStub_notEomFlagEom_long() {
// nominals, 2012-02-29 (P90D) 2012-05-29 (P92D) 2012-08-29
LocalDate start = LocalDate.of(2012, 2, 29);
LocalDate periodEnd = LocalDate.of(2012, 7, 31);
LocalDate end = LocalDate.of(2012, 6, 1); // after first nominal
ScheduleInfo info = new Info(start.minus(P3M), periodEnd, periodEnd, false, P3M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (90d / (90d * 4d)) + (3d / (92d * 4d)), TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
// test against official examples - http://www.isda.org/c_and_a/pdf/ACT-ACT-ISDA-1999.pdf
// this version has an error http://www.isda.org/c_and_a/pdf/mktc1198.pdf
public void test_actAct_isdaTestCase_normal() {
LocalDate start = LocalDate.of(2003, 11, 1);
LocalDate end = LocalDate.of(2004, 5, 1);
ScheduleInfo info = new Info(start, end.plus(P6M), end, true, P6M);
assertEquals(ACT_ACT_ISDA.yearFraction(start, end), (61d / 365d) + (121d / 366d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (182d / (182d * 2d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(start, end), (182d / 366d), TOLERANCE_ZERO);
}
public void test_actAct_isdaTestCase_shortInitialStub() {
LocalDate start = LocalDate.of(1999, 2, 1);
LocalDate firstRegular = LocalDate.of(1999, 7, 1);
LocalDate end = LocalDate.of(2000, 7, 1);
ScheduleInfo info1 = new Info(start, end.plus(P12M), firstRegular, true, P12M); // initial period
ScheduleInfo info2 = new Info(start, end.plus(P12M), end, true, P12M); // regular period
assertEquals(ACT_ACT_ISDA.yearFraction(start, firstRegular), (150d / 365d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(start, firstRegular, info1), (150d / (365d * 1d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(start, firstRegular), (150d / (365d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ISDA.yearFraction(firstRegular, end), (184d / 365d) + (182d / 366d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(firstRegular, end, info2), (366d / (366d * 1d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(firstRegular, end), (366d / 366d), TOLERANCE_ZERO);
}
public void test_actAct_isdaTestCase_longInitialStub() {
LocalDate start = LocalDate.of(2002, 8, 15);
LocalDate firstRegular = LocalDate.of(2003, 7, 15);
LocalDate end = LocalDate.of(2004, 1, 15);
ScheduleInfo info1 = new Info(start, end, firstRegular, true, P6M); // initial period
ScheduleInfo info2 = new Info(start, end, end, true, P6M); // regular period
assertEquals(ACT_ACT_ISDA.yearFraction(start, firstRegular), (334d / 365d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(start, firstRegular, info1),
(181d / (181d * 2d)) + (153d / (184d * 2d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(start, firstRegular), (334d / 365d), TOLERANCE_ZERO);
// example is wrong in 1998 euro swap version
assertEquals(ACT_ACT_ISDA.yearFraction(firstRegular, end), (170d / 365d) + (14d / 366d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(firstRegular, end, info2), (184d / (184d * 2d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(firstRegular, end), (184d / 365d), TOLERANCE_ZERO);
}
public void test_actAct_isdaTestCase_shortFinalStub() {
LocalDate start = LocalDate.of(1999, 7, 30);
LocalDate lastRegular = LocalDate.of(2000, 1, 30);
LocalDate end = LocalDate.of(2000, 6, 30);
ScheduleInfo info1 = new Info(start, end, lastRegular, true, P6M); // regular period
ScheduleInfo info2 = new Info(start, end, end, true, P6M); // final period
assertEquals(ACT_ACT_ISDA.yearFraction(start, lastRegular), (155d / 365d) + (29d / 366d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(start, lastRegular, info1), (184d / (184d * 2d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(start, lastRegular), (184d / 365d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ISDA.yearFraction(lastRegular, end), (152d / 366d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(lastRegular, end, info2), (152d / (182d * 2d)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(lastRegular, end), (152d / 366d), TOLERANCE_ZERO);
}
public void test_actAct_isdaTestCase_longFinalStub() {
LocalDate start = LocalDate.of(1999, 11, 30);
LocalDate end = LocalDate.of(2000, 4, 30);
ScheduleInfo info = new Info(start.minus(P3M), end, end, true, P3M);
assertEquals(ACT_ACT_ISDA.yearFraction(start, end), (32d / 365d) + (120d / 366d), TOLERANCE_ZERO);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), (91d / (91d * 4d)) + (61d / (92d * 4)), TOLERANCE_ZERO);
assertEquals(ACT_ACT_AFB.yearFraction(start, end), (152d / 366d), TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
public void test_actActYearVsIcma() {
LocalDate start = LocalDate.of(2011, 1, 1);
for (int i = 0; i < 400; i++) {
for (int j = 0; j < 365; j++) {
LocalDate end = start.plusDays(j);
ScheduleInfo info = new Info(start, end, start.plusYears(1), false, P12M);
assertEquals(ACT_ACT_ICMA.yearFraction(start, end, info), ACT_ACT_YEAR.yearFraction(start, end), TOLERANCE_ZERO);
}
start = start.plusDays(1);
}
}
//-------------------------------------------------------------------------
@DataProvider(name = "name")
static Object[][] data_name() {
return new Object[][] {
{ONE_ONE, "1/1"},
{ACT_ACT_ISDA, "Act/Act ISDA"},
{ACT_ACT_ICMA, "Act/Act ICMA"},
{ACT_ACT_AFB, "Act/Act AFB"},
{ACT_ACT_YEAR, "Act/Act Year"},
{ACT_365_ACTUAL, "Act/365 Actual"},
{ACT_365L, "Act/365L"},
{ACT_360, "Act/360"},
{ACT_364, "Act/364"},
{ACT_365F, "Act/365F"},
{ACT_365_25, "Act/365.25"},
{NL_365, "NL/365"},
{THIRTY_360_ISDA, "30/360 ISDA"},
{THIRTY_U_360, "30U/360"},
{THIRTY_U_360_EOM, "30U/360 EOM"},
{THIRTY_360_PSA, "30/360 PSA"},
{THIRTY_E_360_ISDA, "30E/360 ISDA"},
{THIRTY_E_360, "30E/360"},
{THIRTY_EPLUS_360, "30E+/360"},
};
}
@Test(dataProvider = "name")
public void test_name(DayCount convention, String name) {
assertEquals(convention.getName(), name);
}
@Test(dataProvider = "name")
public void test_toString(DayCount convention, String name) {
assertEquals(convention.toString(), name);
}
@Test(dataProvider = "name")
public void test_of_lookup(DayCount convention, String name) {
assertEquals(DayCount.of(name), convention);
}
@Test(dataProvider = "name")
public void test_extendedEnum(DayCount convention, String name) {
ImmutableMap<String, DayCount> map = DayCount.extendedEnum().lookupAll();
assertEquals(map.get(name), convention);
}
public void test_of_lookup_notFound() {
assertThrowsIllegalArg(() -> DayCount.of("Rubbish"));
}
public void test_of_lookup_null() {
assertThrowsRuntime(() -> DayCount.of(null));
}
//-------------------------------------------------------------------------
public void test_relativeYearFraction_defaultMethod() {
DayCount dc = new DayCount() {
@Override
public double yearFraction(LocalDate firstDate, LocalDate secondDate, ScheduleInfo scheduleInfo) {
return 1;
}
@Override
public int days(LocalDate firstDate, LocalDate secondDate) {
return 1;
}
@Override
public String getName() {
return "";
}
};
LocalDate date1 = date(2015, 6, 1);
LocalDate date2 = date(2015, 7, 1);
assertEquals(dc.yearFraction(date1, date2), 1, TOLERANCE_ZERO);
assertEquals(dc.relativeYearFraction(date1, date2), 1, TOLERANCE_ZERO);
assertEquals(dc.relativeYearFraction(date2, date1), -1, TOLERANCE_ZERO);
}
//-------------------------------------------------------------------------
public void test_scheduleInfo() {
ScheduleInfo test = new ScheduleInfo() {};
assertEquals(test.isEndOfMonthConvention(), true);
assertThrows(() -> test.getStartDate(), UnsupportedOperationException.class);
assertThrows(() -> test.getEndDate(), UnsupportedOperationException.class);
assertThrows(() -> test.getFrequency(), UnsupportedOperationException.class);
assertThrows(() -> test.getPeriodEndDate(JAN_01), UnsupportedOperationException.class);
}
//-------------------------------------------------------------------------
public void coverage() {
coverPrivateConstructor(DayCounts.class);
coverEnum(StandardDayCounts.class);
}
public void test_serialization() {
assertSerialization(ACT_364);
}
public void test_jodaConvert() {
assertJodaConvert(DayCount.class, THIRTY_360_ISDA);
assertJodaConvert(DayCount.class, ACT_365F);
}
//-------------------------------------------------------------------------
static class Info implements ScheduleInfo {
private final LocalDate start;
private final LocalDate end;
private final LocalDate periodEnd;
private final boolean eom;
private final Frequency frequency;
public Info(boolean eom) {
this(null, null, null, eom, null);
}
public Info(LocalDate start, LocalDate end, LocalDate periodEnd, boolean eom, Frequency frequency) {
this.start = start;
this.end = end;
this.periodEnd = periodEnd;
this.eom = eom;
this.frequency = frequency;
}
@Override
public boolean isEndOfMonthConvention() {
return eom;
}
@Override
public Frequency getFrequency() {
return frequency;
}
@Override
public LocalDate getStartDate() {
return start;
}
@Override
public LocalDate getEndDate() {
return end;
}
@Override
public LocalDate getPeriodEndDate(LocalDate date) {
return periodEnd;
}
};
}