BondFutureOptionExpiryCalculator implements ExchangeTradedInstrumentExpiryCalculator { @Override public LocalDate getExpiryDate(final int n, final LocalDate today, final Calendar holidayCalendar) { ArgumentChecker.isTrue(n > 0, "n must be greater than zero; have {}", n); ArgumentChecker.notNull(today, "today"); ArgumentChecker.notNull(holidayCalendar, "holiday calendar"); final LocalDate lastFridayOfThisMonth = today.with(LAST_DAY_ADJUSTER).with(PREVIOUS_OR_CURRENT_FRIDAY_ADJUSTER); LocalDate lastDayOfMonth; LocalDate lastFridayOfMonth; if (today.isAfter(lastFridayOfThisMonth)) { lastDayOfMonth = today.plusMonths(n).with(LAST_DAY_ADJUSTER); lastFridayOfMonth = lastDayOfMonth.with(PREVIOUS_OR_CURRENT_FRIDAY_ADJUSTER); } else { lastDayOfMonth = today.plusMonths(n - 1).with(LAST_DAY_ADJUSTER); lastFridayOfMonth = lastDayOfMonth.with(PREVIOUS_OR_CURRENT_FRIDAY_ADJUSTER); } int nBusinessDays = 0; LocalDate date = lastFridayOfMonth.plusDays(1); while (!date.isAfter(lastDayOfMonth)) { if (holidayCalendar.isWorkingDay(date)) { nBusinessDays++; } if (nBusinessDays >= 2) { while (!holidayCalendar.isWorkingDay(lastFridayOfMonth)) { lastFridayOfMonth = lastFridayOfMonth.minusDays(1); } return lastFridayOfMonth; } date = date.plusDays(1); } LocalDate result = lastFridayOfMonth.with(PREVIOUS_FRIDAY_ADJUSTER); while (!holidayCalendar.isWorkingDay(result)) { result = result.minusDays(1); } return result; } private  BondFutureOptionExpiryCalculator(); static BondFutureOptionExpiryCalculator getInstance(); @Override LocalDate getExpiryDate(final int n, final LocalDate today, final Calendar holidayCalendar); @Override LocalDate getExpiryMonth(final int n, final LocalDate today); @Override String getName(); static final String NAME; }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNegativeN() { CALCULATOR.getExpiryDate(-1, AUGUST, CALENDAR); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testZeroN() { CALCULATOR.getExpiryDate(0, AUGUST, CALENDAR); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullDate() { CALCULATOR.getExpiryDate(1, null, CALENDAR); }
@Test(expectedExceptions = IllegalArgumentException.class) public void testNullCalendar() { CALCULATOR.getExpiryDate(2, AUGUST, null); }
@Test public void testExpiryMonthAfterExpiry() { assertEquals(LocalDate.of(2012, 10, 26), CALCULATOR.getExpiryDate(1, SEPTEMBER_END, WEEKEND_CALENDAR)); assertEquals(LocalDate.of(2012, 10, 26), CALCULATOR.getExpiryDate(1, SEPTEMBER_END, CALENDAR)); assertEquals(LocalDate.of(2012, 11, 23), CALCULATOR.getExpiryDate(2, SEPTEMBER_END, WEEKEND_CALENDAR)); assertEquals(LocalDate.of(2012, 11, 22), CALCULATOR.getExpiryDate(2, SEPTEMBER_END, CALENDAR)); assertEquals(LocalDate.of(2012, 12, 21), CALCULATOR.getExpiryDate(3, SEPTEMBER_END, WEEKEND_CALENDAR)); assertEquals(LocalDate.of(2012, 12, 21), CALCULATOR.getExpiryDate(3, SEPTEMBER_END, CALENDAR)); assertEquals(LocalDate.of(2013, 1, 25), CALCULATOR.getExpiryDate(4, SEPTEMBER_END, WEEKEND_CALENDAR)); assertEquals(LocalDate.of(2013, 1, 25), CALCULATOR.getExpiryDate(4, SEPTEMBER_END, CALENDAR)); assertEquals(LocalDate.of(2013, 2, 22), CALCULATOR.getExpiryDate(5, SEPTEMBER_END, WEEKEND_CALENDAR)); assertEquals(LocalDate.of(2013, 2, 22), CALCULATOR.getExpiryDate(5, SEPTEMBER_END, CALENDAR)); assertEquals(LocalDate.of(2013, 3, 22), CALCULATOR.getExpiryDate(6, SEPTEMBER_END, WEEKEND_CALENDAR)); assertEquals(LocalDate.of(2013, 3, 22), CALCULATOR.getExpiryDate(6, SEPTEMBER_END, CALENDAR)); assertEquals(LocalDate.of(2013, 4, 26), CALCULATOR.getExpiryDate(7, SEPTEMBER_END, WEEKEND_CALENDAR)); assertEquals(LocalDate.of(2013, 4, 19), CALCULATOR.getExpiryDate(7, SEPTEMBER_END, CALENDAR)); }