public static ZonedDateTime[] getAdjustedMaturityDateSchedule( final ZonedDateTime effectiveDate, final ZonedDateTime[] dates, final BusinessDayConvention convention, final Calendar calendar, final Frequency frequency) { ArgumentChecker.notEmpty(dates, "dates"); ArgumentChecker.notNull(convention, "convention"); ArgumentChecker.notNull(calendar, "calendar"); ArgumentChecker.notNull(frequency, "frequency"); PeriodFrequency periodFrequency; if (frequency instanceof PeriodFrequency) { periodFrequency = (PeriodFrequency) frequency; } else if (frequency instanceof SimpleFrequency) { periodFrequency = ((SimpleFrequency) frequency).toPeriodFrequency(); } else { throw new IllegalArgumentException( "For the moment can only deal with PeriodFrequency and SimpleFrequency"); } final Period period = periodFrequency.getPeriod(); final int n = dates.length; final ZonedDateTime[] results = new ZonedDateTime[n]; results[0] = effectiveDate.plus(period); for (int i = 1; i < n; i++) { results[i] = convention.adjustDate( calendar, dates[i - 1].plus(period)); // TODO need to further shift these dates by a convention } return results; }
/** * Counts back from maturityDate, filling to equally spaced dates frequency times a year until the * last date <b>after</b> effective date. * * @param effectiveDate the date that terminates to back counting (i.e. the first date is after * this date), not null * @param maturityDate the date to count back from, not null * @param frequency how many times a year dates occur, not null * @return the first date after effectiveDate (i.e. effectiveDate is <b>not</b> included to the * maturityDate (included) */ public static ZonedDateTime[] getBackwardsUnadjustedDateSchedule( final ZonedDateTime effectiveDate, final ZonedDateTime maturityDate, final Frequency frequency) { ArgumentChecker.notNull(effectiveDate, "effective date"); ArgumentChecker.notNull(maturityDate, "maturity date"); ArgumentChecker.notNull(frequency, "frequency"); if (effectiveDate.isAfter(maturityDate)) { throw new IllegalArgumentException("Effective date was after maturity"); } PeriodFrequency periodFrequency; if (frequency instanceof PeriodFrequency) { periodFrequency = (PeriodFrequency) frequency; } else if (frequency instanceof SimpleFrequency) { periodFrequency = ((SimpleFrequency) frequency).toPeriodFrequency(); } else { throw new IllegalArgumentException( "For the moment can only deal with PeriodFrequency and SimpleFrequency"); } final Period period = periodFrequency.getPeriod(); final List<ZonedDateTime> dates = new ArrayList<>(); ZonedDateTime date = maturityDate; // TODO review the tolerance given while (date.isAfter(effectiveDate) && DateUtils.getExactDaysBetween(effectiveDate, date) > 4.0) { dates.add(date); date = date.minus(period); } Collections.sort(dates); return dates.toArray(EMPTY_ARRAY); }
/** * Convert a Frequency to a Period when possible. * * @param frequency The frequency. * @return The converted period. */ private static Period periodFromFrequency(final Frequency frequency) { PeriodFrequency periodFrequency; if (frequency instanceof PeriodFrequency) { periodFrequency = (PeriodFrequency) frequency; } else if (frequency instanceof SimpleFrequency) { periodFrequency = ((SimpleFrequency) frequency).toPeriodFrequency(); } else { throw new IllegalArgumentException( "For the moment can only deal with PeriodFrequency and SimpleFrequency"); } return periodFrequency.getPeriod(); }
public static ZonedDateTime[] getAdjustedDateSchedule( final ZonedDateTime startDate, final ZonedDateTime endDate, final Frequency frequency, final BusinessDayConvention businessDayConvention, final Calendar calendar, final boolean isEOM) { PeriodFrequency periodFrequency; if (frequency instanceof PeriodFrequency) { periodFrequency = (PeriodFrequency) frequency; } else if (frequency instanceof SimpleFrequency) { periodFrequency = ((SimpleFrequency) frequency).toPeriodFrequency(); } else { throw new IllegalArgumentException( "For the moment can only deal with PeriodFrequency and SimpleFrequency"); } final Period period = periodFrequency.getPeriod(); return getAdjustedDateSchedule( startDate, endDate, period, businessDayConvention, calendar, isEOM, true); }
/** * Calculates the unadjusted date schedule. * * @param effectiveDate the effective date, not null * @param accrualDate the accrual date, not null * @param maturityDate the maturity date, not null * @param frequency how many times a year dates occur, not null * @return the schedule, not null */ public static ZonedDateTime[] getUnadjustedDateSchedule( final ZonedDateTime effectiveDate, final ZonedDateTime accrualDate, final ZonedDateTime maturityDate, final Frequency frequency) { ArgumentChecker.notNull(effectiveDate, "effective date"); ArgumentChecker.notNull(accrualDate, "accrual date"); ArgumentChecker.notNull(maturityDate, "maturity date"); ArgumentChecker.notNull(frequency, "frequency"); if (effectiveDate.isAfter(maturityDate)) { throw new IllegalArgumentException("Effective date was after maturity"); } if (accrualDate.isAfter(maturityDate)) { throw new IllegalArgumentException("Accrual date was after maturity"); } // TODO what if there's no valid date between accrual date and maturity date? PeriodFrequency periodFrequency; if (frequency instanceof PeriodFrequency) { periodFrequency = (PeriodFrequency) frequency; } else if (frequency instanceof SimpleFrequency) { periodFrequency = ((SimpleFrequency) frequency).toPeriodFrequency(); } else { throw new IllegalArgumentException( "For the moment can only deal with PeriodFrequency and SimpleFrequency"); } final Period period = periodFrequency.getPeriod(); final List<ZonedDateTime> dates = new ArrayList<>(); ZonedDateTime date = effectiveDate; // TODO this is only correct if effective date = accrual date date = date.plus(period); while (isWithinSwapLifetime( date, maturityDate)) { // REVIEW: could speed this up by working out how many periods between // start and end date? dates.add(date); date = date.plus(period); } return dates.toArray(EMPTY_ARRAY); }