Quantlib: Date Advance Function for TimeUnit "days" - Bug or Feature?

1.1k Views Asked by At

I've got a tiny question regarding the date-advance function in the C++ Quantlib. I wanted to use a payment offset (in days) for a product with payment businessday convention "preceding" , but payment date was always set to the first day after the weekend when payment date fell on the weekend. This is due to the fact, that the "advance" function ignores businessday conventions when "days" are handed over to "advance" function, see here:

 Date Calendar::advance(const Date& d,
                       Integer n, TimeUnit unit,
                       BusinessDayConvention c,
                       bool endOfMonth) const {
    QL_REQUIRE(d!=Date(), "null date");
    if (n == 0) {
        return adjust(d,c);
    } else if (unit == Days) {
        Date d1 = d;
        if (n > 0) {
            while (n > 0) {
                d1++;
                while (isHoliday(d1))
                    d1++;
                n--;
            }
        } else {
            while (n < 0) {
                d1--;
                while(isHoliday(d1))
                    d1--;
                n++;
            }
        }
        return d1;
    } else if (unit == Weeks) {
        Date d1 = d + n*unit;
        return adjust(d1,c);
    } else {
        Date d1 = d + n*unit;

        // we are sure the unit is Months or Years
        if (endOfMonth && isEndOfMonth(d))
            return Calendar::endOfMonth(d1);

        return adjust(d1, c);
    }
}

Is this implemented on purpose? P.s. "adjust"-function uses business day convention correctly!

2

There are 2 best solutions below

0
Luigi Ballabio On

Yes, this is one of the things that I'd fix if it didn't break client code. In the case of days, Calendar::advance means "advance by a number of business days"; the convention doesn't apply, because by advancing this way you never land on a holiday.

If what you mean is "advance a number of calendar days (e.g., 2) and then adjust", you can write exactly that:

Date paymentDate = calendar.adjust(date + 2, convention);
0
Björn1985 On

Yes, the payment offsets are always business days. So the call of the OISRateHelper was a bit misleading, because you can hand over a business day convention for the payment offset.

ql.OISRateHelper(0,
                     ql.Period(swapMaturity),
                     ql.QuoteHandle(rate),
                     eoniaIndex,
                     termStructureHandle,
                     False,
                     paymentOffset,
                     ql.Preceding
                     )