0

I'm using QuantLib 1.7.1 and try running these codes:

Date begin(30, September, 2009), end(15, Jun, 2012);
Calendar myCal = Japan();
BusinessDayConvention bdC = BusinessDayConvention(Following);
Period myTenor(6, Months);
DateGeneration::Rule myRule = DateGeneration::Forward;
Schedule mySched(begin, end, myTenor, myCal, bdC, bdC, myRule, true);
std::vector <Date > finalSched = mySched.dates();
BOOST_FOREACH(Date d, finalSched) std::cout << d << std::endl;

I expected to get a schedule whose lower and upper bounds are 30/9/2009 and 15/6/2012 respectively like this:

September 30th, 2009
March 31st, 2010
September 30th, 2010
March 31st, 2011
September 30th, 2011
March 30th, 2012
June 15th, 2012

But I got the result where final payment date is 29/6/2012, which is after the bound I set:

September 30th, 2009
March 31st, 2010
September 30th, 2010
March 31st, 2011
September 30th, 2011
March 30th, 2012
June 29th, 2012

If I set DateGeneration rule to Backward, it will work as expected (the schedule lower bound is 30/9/2009):

September 30th, 2009
December 15th, 2009
June 15th, 2010
December 15th, 2010
June 15th, 2011
December 15th, 2011
June 15th, 2012

Did QuantLib give the result outside the bound in the first case intentionally or is this a bug?

Truong Ngo
  • 13
  • 1
  • 4
  • Where is the documentation for the Schedule class? I did a quick Google search and all I found was the implementation code. – John Zwinck Apr 28 '16 at 12:31
  • I saw it from this slide (page 36) from quantlib website [link](http://quantlib.org/slides/dima-ql-intro-1.pdf). It is interesting that in the slide, it gave the correct result – Truong Ngo Apr 28 '16 at 12:34
  • What if you use Backward with the lower bound being 20 Sept instead of 30 Sept? – John Zwinck Apr 28 '16 at 13:01
  • @JohnZwinck in that case, it will return 24 September (since 20 was Sunday, and 21-23 September were also holidays in Japan). If I set the lower bound to 10 September then the first payment date is 10/Sep/2009 as expected. P/S: I have checked Japanese holiday calendar and found no holidays in June 2012. – Truong Ngo Apr 28 '16 at 13:42

1 Answers1

1

As far as I can see, the last parameter you're passing (true) is causing all dates to be adjusted to the business end of the month, including the maturity and even if it's far from that date. I'm not sure how this came to be, but I don't think it's expected.

As of now, I'm afraid there's no workaround for this specific case. Passing false as the last parameter yields the correct maturity, but doesn't adjust the dates in between:

September 30th, 2009
March 30th, 2010
September 30th, 2010
March 30th, 2011
September 30th, 2011
March 30th, 2012
June 15th, 2012

so it won't help you if you happen to need this particular bond.

Also, this only happen if the start date is the last business day of the month; if it isn't, the passed endOfMonth parameter is ignored.

So in short, yes: it's probably a bug.

Update: actually, there is a workaround which I had forgotten: you can tell the Schedule constructor explicitly not to adjust the maturity, by passing Unadjusted as the termination-date convention:

Schedule mySched(begin, end, myTenor, myCal, bdC, Unadjusted, myRule, true);

This yields the dates you're expecting:

September 30th, 2009
March 31st, 2010
September 30th, 2010
March 31st, 2011
September 30th, 2011
March 30th, 2012
June 15th, 2012

I'm still inclined to consider the other behavior as some kind of bug, though, since it's so unexpected.

Luigi Ballabio
  • 4,128
  • 21
  • 29
  • Thank you for your support. I'm learning QuantLib and was just curious as to why it didn't behave as in the example I read. P/S: yes. Unadjusted will be a workaround for this case, though only if termination-date is not a non-trading day :) – Truong Ngo Apr 28 '16 at 14:01
  • That's correct. In that case, you'll have to adjust it manually before passing it to the `Schedule` constructor. – Luigi Ballabio Apr 28 '16 at 15:30