/**
  * 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);
 }