/** * Gets trading months (not static as depends on current date). * * @param now the date today, not null * @return the valid trading months, not null */ private Month[] getTradingMonths(final LocalDate now) { // this may need improvements as the year end approaches Set<Month> ret = new TreeSet<>(); ret.add(now.getMonth()); // this month ret.add(now.getMonth().plus(1)); // next month ret.add(now.getMonth().plus(2)); // next 2 months // February, April, August, and October in next 23 months ret.add(Month.FEBRUARY); ret.add(Month.APRIL); ret.add(Month.AUGUST); ret.add(Month.OCTOBER); // June and December falling in next 72 month period ret.add(Month.JUNE); ret.add(Month.DECEMBER); // assuming this gives enough valid dates so dont go round to next 12 month period return ret.toArray(new Month[0]); }
private LocalDate getNextExpiryMonth(final Month[] validMonths, final LocalDate dtCurrent) { Month mthCurrent = dtCurrent.getMonth(); int idx = Arrays.binarySearch(validMonths, mthCurrent); if (Math.abs(idx) >= (validMonths.length - 1)) { return LocalDate.of(dtCurrent.getYear() + 1, validMonths[0], dtCurrent.getDayOfMonth()); } else if (idx >= 0) { return dtCurrent.with(validMonths[idx + 1]); } else { return dtCurrent.with(validMonths[-idx + 1]); } }
@Override /** * Given a LocalDate representing the valuation date and an integer representing the n'th expiry * after that date, returns a date in the expiry month Used in * BloombergFutureUtils.getExpiryCodeForSoybeanFutures() */ public LocalDate getExpiryMonth(final int n, final LocalDate today) { ArgumentChecker.isTrue(n > 0, "n must be greater than zero"); ArgumentChecker.notNull(today, "today"); LocalDate expiryDate = today; for (int m = n; m > 0; m--) { expiryDate = getNextExpiryMonth(expiryDate); } if (expiryDate.getDayOfMonth() > 15) { expiryDate = getNextExpiryMonth(expiryDate); } // set day to first possible - used in getExpiryDate() return LocalDate.of(expiryDate.getYear(), expiryDate.getMonth(), 14); }