Skip to content

Commit

Permalink
Fix a few US holidays before 1971.
Browse files Browse the repository at this point in the history
  • Loading branch information
lballabio committed Aug 30, 2016
1 parent 89b2d8e commit 01cd5bc
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 18 deletions.
83 changes: 66 additions & 17 deletions ql/time/calendars/unitedstates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,56 @@

namespace QuantLib {

namespace {

// a few rules used by multiple calendars

bool isWashingtonBirthday(Day d, Month m, Year y, Weekday w) {
if (y >= 1971) {
// third Monday in February
return (d >= 15 && d <= 21) && w == Monday && m == February;
} else {
// February 22nd, possily adjusted
return (d == 22 || (d == 23 && w == Monday)
|| (d == 21 && w == Friday)) && m == February;
}
}

bool isMemorialDay(Day d, Month m, Year y, Weekday w) {
if (y >= 1971) {
// last Monday in May
return d >= 25 && w == Monday && m == May;
} else {
// May 30th, possibly adjusted
return (d == 30 || (d == 31 && w == Monday)
|| (d == 29 && w == Friday)) && m == May;
}
}

bool isLaborDay(Day d, Month m, Year y, Weekday w) {
// first Monday in September
return d <= 7 && w == Monday && m == September;
}

bool isColumbusDay(Day d, Month m, Year y, Weekday w) {
// second Monday in October
return (d >= 8 && d <= 14) && w == Monday && m == October
&& y >= 1971;
}

bool isVeteransDay(Day d, Month m, Year y, Weekday w) {
if (y <= 1970 || y >= 1978) {
// November 11th, adjusted
return (d == 11 || (d == 12 && w == Monday) ||
(d == 10 && w == Friday)) && m == November;
} else {
// fourth Monday in October
return (d >= 22 && d <= 28) && w == Monday && m == October;
}
}

}

UnitedStates::UnitedStates(UnitedStates::Market market) {
// all calendar instances on the same market share the same
// implementation instance
Expand Down Expand Up @@ -68,19 +118,18 @@ namespace QuantLib {
|| ((d >= 15 && d <= 21) && w == Monday && m == January
&& y >= 1983)
// Washington's birthday (third Monday in February)
|| ((d >= 15 && d <= 21) && w == Monday && m == February)
|| isWashingtonBirthday(d, m, y, w)
// Memorial Day (last Monday in May)
|| (d >= 25 && w == Monday && m == May)
|| isMemorialDay(d, m, y, w)
// Independence Day (Monday if Sunday or Friday if Saturday)
|| ((d == 4 || (d == 5 && w == Monday) ||
(d == 3 && w == Friday)) && m == July)
// Labor Day (first Monday in September)
|| (d <= 7 && w == Monday && m == September)
|| isLaborDay(d, m, y, w)
// Columbus Day (second Monday in October)
|| ((d >= 8 && d <= 14) && w == Monday && m == October)
|| isColumbusDay(d, m, y, w)
// Veteran's Day (Monday if Sunday or Friday if Saturday)
|| ((d == 11 || (d == 12 && w == Monday) ||
(d == 10 && w == Friday)) && m == November)
|| isVeteransDay(d, m, y, w)
// Thanksgiving Day (fourth Thursday in November)
|| ((d >= 22 && d <= 28) && w == Thursday && m == November)
// Christmas (Monday if Sunday or Friday if Saturday)
Expand All @@ -101,16 +150,16 @@ namespace QuantLib {
// New Year's Day (possibly moved to Monday if on Sunday)
|| ((d == 1 || (d == 2 && w == Monday)) && m == January)
// Washington's birthday (third Monday in February)
|| ((d >= 15 && d <= 21) && w == Monday && m == February)
|| isWashingtonBirthday(d, m, y, w)
// Good Friday
|| (dd == em-3)
// Memorial Day (last Monday in May)
|| (d >= 25 && w == Monday && m == May)
|| isMemorialDay(d, m, y, w)
// Independence Day (Monday if Sunday or Friday if Saturday)
|| ((d == 4 || (d == 5 && w == Monday) ||
(d == 3 && w == Friday)) && m == July)
// Labor Day (first Monday in September)
|| (d <= 7 && w == Monday && m == September)
|| isLaborDay(d, m, y, w)
// Thanksgiving Day (fourth Thursday in November)
|| ((d >= 22 && d <= 28) && w == Thursday && m == November)
// Christmas (Monday if Sunday or Friday if Saturday)
Expand Down Expand Up @@ -188,21 +237,20 @@ namespace QuantLib {
|| ((d >= 15 && d <= 21) && w == Monday && m == January
&& y >= 1983)
// Washington's birthday (third Monday in February)
|| ((d >= 15 && d <= 21) && w == Monday && m == February)
|| isWashingtonBirthday(d, m, y, w)
// Good Friday
|| (dd == em-3)
// Memorial Day (last Monday in May)
|| (d >= 25 && w == Monday && m == May)
|| isMemorialDay(d, m, y, w)
// Independence Day (Monday if Sunday or Friday if Saturday)
|| ((d == 4 || (d == 5 && w == Monday) ||
(d == 3 && w == Friday)) && m == July)
// Labor Day (first Monday in September)
|| (d <= 7 && w == Monday && m == September)
|| isLaborDay(d, m, y, w)
// Columbus Day (second Monday in October)
|| ((d >= 8 && d <= 14) && w == Monday && m == October)
|| isColumbusDay(d, m, y, w)
// Veteran's Day (Monday if Sunday or Friday if Saturday)
|| ((d == 11 || (d == 12 && w == Monday) ||
(d == 10 && w == Friday)) && m == November)
|| isVeteransDay(d, m, y, w)
// Thanksgiving Day (fourth Thursday in November)
|| ((d >= 22 && d <= 28) && w == Thursday && m == November)
// Christmas (Monday if Sunday or Friday if Saturday)
Expand All @@ -217,15 +265,16 @@ namespace QuantLib {
Weekday w = date.weekday();
Day d = date.dayOfMonth();
Month m = date.month();
Year y = date.year();
if (isWeekend(w)
// New Year's Day (possibly moved to Monday if on Sunday)
|| ((d == 1 || (d == 2 && w == Monday)) && m == January)
// Memorial Day (last Monday in May)
|| (d >= 25 && w == Monday && m == May)
|| isMemorialDay(d, m, y, w)
// Independence Day (Monday if Sunday)
|| ((d == 4 || (d == 5 && w == Monday)) && m == July)
// Labor Day (first Monday in September)
|| (d <= 7 && w == Monday && m == September)
|| isLaborDay(d, m, y, w)
// Thanksgiving Day (fourth Thursday in November)
|| ((d >= 22 && d <= 28) && w == Thursday && m == November)
// Christmas (Monday if Sunday)
Expand Down
25 changes: 24 additions & 1 deletion test-suite/calendars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,38 @@ void CalendarTest::testUSSettlement() {
Calendar c = UnitedStates(UnitedStates::Settlement);
std::vector<Date> hol = Calendar::holidayList(c, Date( 1, January, 2004),
Date(31,December, 2005));
for (Size i=0; i<std::min<Size>(hol.size(), expectedHol.size()); i++) {
if (hol.size()!=expectedHol.size())
BOOST_FAIL("there were " << expectedHol.size()
<< " expected holidays, while there are " << hol.size()
<< " calculated holidays");
for (Size i=0; i<hol.size(); i++) {
if (hol[i]!=expectedHol[i])
BOOST_FAIL("expected holiday was " << expectedHol[i]
<< " while calculated holiday is " << hol[i]);
}

// before Uniform Monday Holiday Act
expectedHol = std::vector<Date>();
expectedHol.push_back(Date(2,January,1961));
expectedHol.push_back(Date(22,February,1961));
expectedHol.push_back(Date(30,May,1961));
expectedHol.push_back(Date(4,July,1961));
expectedHol.push_back(Date(4,September,1961));
expectedHol.push_back(Date(10,November,1961));
expectedHol.push_back(Date(23,November,1961));
expectedHol.push_back(Date(25,December,1961));

hol = Calendar::holidayList(c, Date( 1, January, 1961),
Date(31,December, 1961));
if (hol.size()!=expectedHol.size())
BOOST_FAIL("there were " << expectedHol.size()
<< " expected holidays, while there are " << hol.size()
<< " calculated holidays");
for (Size i=0; i<hol.size(); i++) {
if (hol[i]!=expectedHol[i])
BOOST_FAIL("expected holiday was " << expectedHol[i]
<< " while calculated holiday is " << hol[i]);
}
}

void CalendarTest::testUSGovernmentBondMarket() {
Expand Down

0 comments on commit 01cd5bc

Please sign in to comment.