/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.schedule;
import org.apache.commons.lang.Validate;
import org.threeten.bp.LocalDate;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.financial.convention.frequency.Frequency;
import com.opengamma.financial.convention.frequency.PeriodFrequency;
import com.opengamma.financial.convention.frequency.SimpleFrequency;
/**
* Factory to create schedules.
*/
public class ScheduleFactory {
public static LocalDate[] getSchedule(final LocalDate startDate, final LocalDate endDate, final Frequency frequency, final boolean endOfMonth, final boolean fromEnd,
final boolean generateRecursive) {
Validate.notNull(startDate, "start date");
Validate.notNull(endDate, "end date");
Validate.notNull(frequency, "frequency");
SimpleFrequency simple;
if (frequency instanceof SimpleFrequency) {
simple = (SimpleFrequency) frequency;
} else if (frequency instanceof PeriodFrequency) {
simple = ((PeriodFrequency) frequency).toSimpleFrequency();
} else {
throw new IllegalArgumentException("Can only handle SimpleFrequency and PeriodFrequency");
}
final int periodsPerYear = (int) simple.getPeriodsPerYear();
return getSchedule(startDate, endDate, periodsPerYear, endOfMonth, fromEnd, generateRecursive);
}
public static LocalDate[] getSchedule(final LocalDate startDate, final LocalDate endDate, final int periodsPerYear, final boolean endOfMonth, final boolean fromEnd,
final boolean generateRecursive) {
Validate.notNull(startDate, "start date");
Validate.notNull(endDate, "end date");
Validate.isTrue(periodsPerYear > 0);
LocalDate[] result = null;
if (periodsPerYear == 1) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 2) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 4) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.QUARTERLY_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.QUARTERLY_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.QUARTERLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.QUARTERLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 12) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.END_OF_MONTH_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.lengthOfMonth()) {
result = ScheduleCalculatorFactory.END_OF_MONTH_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.MONTHLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.MONTHLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 52) {
if (endOfMonth) {
throw new IllegalArgumentException("Cannot get EOM series for weekly frequency");
}
result = ScheduleCalculatorFactory.WEEKLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (periodsPerYear == 365 || periodsPerYear == 366) {
if (endOfMonth) {
throw new IllegalArgumentException("Cannot get EOM series for daily frequency");
}
result = ScheduleCalculatorFactory.DAILY_CALCULATOR.getSchedule(startDate, endDate);
}
Validate.notNull(result, "result");
return result;
}
public static ZonedDateTime[] getSchedule(final ZonedDateTime startDate, final ZonedDateTime endDate, final Frequency frequency, final boolean endOfMonth, final boolean fromEnd,
final boolean generateRecursive) {
Validate.notNull(startDate, "start date");
Validate.notNull(endDate, "end date");
Validate.notNull(frequency, "frequency");
SimpleFrequency simple;
if (frequency instanceof SimpleFrequency) {
simple = (SimpleFrequency) frequency;
} else if (frequency instanceof PeriodFrequency) {
simple = ((PeriodFrequency) frequency).toSimpleFrequency();
} else {
throw new IllegalArgumentException("Can only handle SimpleFrequency and PeriodFrequency");
}
final int periodsPerYear = (int) simple.getPeriodsPerYear();
return getSchedule(startDate, endDate, periodsPerYear, endOfMonth, fromEnd, generateRecursive);
}
public static ZonedDateTime[] getSchedule(final ZonedDateTime startDate, final ZonedDateTime endDate, final int periodsPerYear, final boolean endOfMonth, final boolean fromEnd,
final boolean generateRecursive) {
Validate.notNull(startDate, "start date");
Validate.notNull(endDate, "end date");
Validate.isTrue(periodsPerYear > 0);
ZonedDateTime[] result = null;
if (periodsPerYear == 1) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 2) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.SEMI_ANNUAL_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 4) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.QUARTERLY_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.QUARTERLY_EOM_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.QUARTERLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.QUARTERLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 12) {
if (endOfMonth) {
if (fromEnd && endDate.getDayOfMonth() == endDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.END_OF_MONTH_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (startDate.getDayOfMonth() == startDate.toLocalDate().lengthOfMonth()) {
result = ScheduleCalculatorFactory.END_OF_MONTH_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else {
result = ScheduleCalculatorFactory.MONTHLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else {
result = ScheduleCalculatorFactory.MONTHLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
}
} else if (periodsPerYear == 52) {
if (endOfMonth) {
throw new IllegalArgumentException("Cannot get EOM series for weekly frequency");
}
result = ScheduleCalculatorFactory.WEEKLY_CALCULATOR.getSchedule(startDate, endDate, fromEnd, generateRecursive);
} else if (periodsPerYear == 365 || periodsPerYear == 366) {
if (endOfMonth) {
throw new IllegalArgumentException("Cannot get EOM series for daily frequency");
}
result = ScheduleCalculatorFactory.DAILY_CALCULATOR.getSchedule(startDate, endDate);
}
Validate.notNull(result, "result");
return result;
}
}