Support adjusted start date for StandardRollConventions (e.g. IMM). #1580
Previous code only supported conversion of adjusted to unadjusted dates for numeric or EOD convention.
This code attempts to calculate an unadjusted date from an adjusted date as follows
This relies on the assumption that the adjusted roll date will never be in a different month to the original unadjusted date. This is relatively safe for the existing StandardRollConventions as the rules for choosing a day in the month will never result in a date close to EOM. The latest possible calculated roll day for the existing roll convention is the 21st of the month (for IMM, if the first of the month is a Thursday). This is sufficiently far from EOM that no reasonable adjustment will result in the adjusted date being in the next month. Similarly the earliest possible date is 7th of the month (for IMMNZD).
The existing implementation for numeric roll convention suffers from a similar problem e.g. if unadjusted roll day of 28th is adjusted using FOLLOWING then the resulting adjusted date could be in the following month. This would result in the date not being identified as adjusted.
This logic will not work for weekly roll conventions in most cases. adjust() method for weekly roll conventions calculates the next weekday which matches the convention. If the passed date has been adjusted forward then it will not be identified as a valid adjusted date; the calculated unadjusted date will be the next occurrence of that weekday, rather than the previous e.g.
See comments in code for (even) more detail.
An alternative approach could be to associate the logic for converting to unadjusted with each roll convention by adding a new method to the RollConvention interface; this would however be an intrusive and breaking change.
This is still a bit of a hack, so open to suggestions for alternatives!