QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
unitedstates.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2004, 2005 Ferdinando Ametrano
5 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
6 Copyright (C) 2003, 2004, 2005, 2006 StatPro Italia srl
7 Copyright (C) 2017 Peter Caspers
8 Copyright (C) 2017 Oleg Kulkov
9
10 This file is part of QuantLib, a free-software/open-source library
11 for financial quantitative analysts and developers - http://quantlib.org/
12
13 QuantLib is free software: you can redistribute it and/or modify it
14 under the terms of the QuantLib license. You should have received a
15 copy of the license along with this program; if not, please email
16 <quantlib-dev@lists.sf.net>. The license is also available online at
17 <http://quantlib.org/license.shtml>.
18
19 This program is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 FOR A PARTICULAR PURPOSE. See the license for more details.
22*/
23
24#include <ql/time/calendars/unitedstates.hpp>
25#include <ql/errors.hpp>
26
27namespace QuantLib {
28
29 namespace {
30
31 // a few rules used by multiple calendars
32
33 bool isWashingtonBirthday(Day d, Month m, Year y, Weekday w) {
34 if (y >= 1971) {
35 // third Monday in February
36 return (d >= 15 && d <= 21) && w == Monday && m == February;
37 } else {
38 // February 22nd, possily adjusted
39 return (d == 22 || (d == 23 && w == Monday)
40 || (d == 21 && w == Friday)) && m == February;
41 }
42 }
43
44 bool isMemorialDay(Day d, Month m, Year y, Weekday w) {
45 if (y >= 1971) {
46 // last Monday in May
47 return d >= 25 && w == Monday && m == May;
48 } else {
49 // May 30th, possibly adjusted
50 return (d == 30 || (d == 31 && w == Monday)
51 || (d == 29 && w == Friday)) && m == May;
52 }
53 }
54
55 bool isLaborDay(Day d, Month m, Year y, Weekday w) {
56 // first Monday in September
57 return d <= 7 && w == Monday && m == September;
58 }
59
60 bool isColumbusDay(Day d, Month m, Year y, Weekday w) {
61 // second Monday in October
62 return (d >= 8 && d <= 14) && w == Monday && m == October
63 && y >= 1971;
64 }
65
66 bool isVeteransDay(Day d, Month m, Year y, Weekday w) {
67 if (y <= 1970 || y >= 1978) {
68 // November 11th, adjusted
69 return (d == 11 || (d == 12 && w == Monday) ||
70 (d == 10 && w == Friday)) && m == November;
71 } else {
72 // fourth Monday in October
73 return (d >= 22 && d <= 28) && w == Monday && m == October;
74 }
75 }
76
77 bool isVeteransDayNoSaturday(Day d, Month m, Year y, Weekday w) {
78 if (y <= 1970 || y >= 1978) {
79 // November 11th, adjusted, but no Saturday to Friday
80 return (d == 11 || (d == 12 && w == Monday)) && m == November;
81 } else {
82 // fourth Monday in October
83 return (d >= 22 && d <= 28) && w == Monday && m == October;
84 }
85 }
86
87 bool isJuneteenth(Day d, Month m, Year y, Weekday w) {
88 // declared in 2021, but only observed by exchanges since 2022
89 return (d == 19 || (d == 20 && w == Monday) || (d == 18 && w == Friday))
90 && m == June && y >= 2022;
91 }
92 }
93
95 // all calendar instances on the same market share the same implementation instance
96 static auto settlementImpl = ext::make_shared<UnitedStates::SettlementImpl>();
97 static auto liborImpactImpl = ext::make_shared<UnitedStates::LiborImpactImpl>();
98 static auto nyseImpl = ext::make_shared<UnitedStates::NyseImpl>();
99 static auto governmentImpl = ext::make_shared<UnitedStates::GovernmentBondImpl>();
100 static auto nercImpl = ext::make_shared<UnitedStates::NercImpl>();
101 static auto federalReserveImpl = ext::make_shared<UnitedStates::FederalReserveImpl>();
102 static auto sofrImpl = ext::make_shared<UnitedStates::SofrImpl>();
103
104 switch (market) {
105 case Settlement:
106 impl_ = settlementImpl;
107 break;
108 case LiborImpact:
109 impl_ = liborImpactImpl;
110 break;
111 case NYSE:
112 impl_ = nyseImpl;
113 break;
114 case GovernmentBond:
115 impl_ = governmentImpl;
116 break;
117 case SOFR:
118 impl_ = sofrImpl;
119 break;
120 case NERC:
121 impl_ = nercImpl;
122 break;
123 case FederalReserve:
124 impl_ = federalReserveImpl;
125 break;
126 default:
127 QL_FAIL("unknown market");
128 }
129 }
130
131
133 Weekday w = date.weekday();
134 Day d = date.dayOfMonth();
135 Month m = date.month();
136 Year y = date.year();
137 if (isWeekend(w)
138 // New Year's Day (possibly moved to Monday if on Sunday)
139 || ((d == 1 || (d == 2 && w == Monday)) && m == January)
140 // (or to Friday if on Saturday)
141 || (d == 31 && w == Friday && m == December)
142 // Martin Luther King's birthday (third Monday in January)
143 || ((d >= 15 && d <= 21) && w == Monday && m == January
144 && y >= 1983)
145 // Washington's birthday (third Monday in February)
146 || isWashingtonBirthday(d, m, y, w)
147 // Memorial Day (last Monday in May)
148 || isMemorialDay(d, m, y, w)
149 // Juneteenth (Monday if Sunday or Friday if Saturday)
150 || isJuneteenth(d, m, y, w)
151 // Independence Day (Monday if Sunday or Friday if Saturday)
152 || ((d == 4 || (d == 5 && w == Monday) ||
153 (d == 3 && w == Friday)) && m == July)
154 // Labor Day (first Monday in September)
155 || isLaborDay(d, m, y, w)
156 // Columbus Day (second Monday in October)
157 || isColumbusDay(d, m, y, w)
158 // Veteran's Day (Monday if Sunday or Friday if Saturday)
159 || isVeteransDay(d, m, y, w)
160 // Thanksgiving Day (fourth Thursday in November)
161 || ((d >= 22 && d <= 28) && w == Thursday && m == November)
162 // Christmas (Monday if Sunday or Friday if Saturday)
163 || ((d == 25 || (d == 26 && w == Monday) ||
164 (d == 24 && w == Friday)) && m == December))
165 return false; // NOLINT(readability-simplify-boolean-expr)
166 return true;
167 }
168
170 // Since 2015 Independence Day only impacts Libor if it falls
171 // on a weekday
172 Weekday w = date.weekday();
173 Day d = date.dayOfMonth();
174 Month m = date.month();
175 Year y = date.year();
176 if (((d == 5 && w == Monday) ||
177 (d == 3 && w == Friday)) && m == July && y >= 2015)
178 return true;
180 }
181
183 Weekday w = date.weekday();
184 Day d = date.dayOfMonth(), dd = date.dayOfYear();
185 Month m = date.month();
186 Year y = date.year();
187 Day em = easterMonday(y);
188 if (isWeekend(w)
189 // New Year's Day (possibly moved to Monday if on Sunday)
190 || ((d == 1 || (d == 2 && w == Monday)) && m == January)
191 // Washington's birthday (third Monday in February)
192 || isWashingtonBirthday(d, m, y, w)
193 // Good Friday
194 || (dd == em-3)
195 // Memorial Day (last Monday in May)
196 || isMemorialDay(d, m, y, w)
197 // Juneteenth (Monday if Sunday or Friday if Saturday)
198 || isJuneteenth(d, m, y, w)
199 // Independence Day (Monday if Sunday or Friday if Saturday)
200 || ((d == 4 || (d == 5 && w == Monday) ||
201 (d == 3 && w == Friday)) && m == July)
202 // Labor Day (first Monday in September)
203 || isLaborDay(d, m, y, w)
204 // Thanksgiving Day (fourth Thursday in November)
205 || ((d >= 22 && d <= 28) && w == Thursday && m == November)
206 // Christmas (Monday if Sunday or Friday if Saturday)
207 || ((d == 25 || (d == 26 && w == Monday) ||
208 (d == 24 && w == Friday)) && m == December)
209 ) return false;
210
211 if (y >= 1998 && (d >= 15 && d <= 21) && w == Monday && m == January)
212 // Martin Luther King's birthday (third Monday in January)
213 return false;
214
215 if ((y <= 1968 || (y <= 1980 && y % 4 == 0)) && m == November
216 && d <= 7 && w == Tuesday)
217 // Presidential election days
218 return false;
219
220 // Special closings
221 if (// President Bush's Funeral
222 (y == 2018 && m == December && d == 5)
223 // Hurricane Sandy
224 || (y == 2012 && m == October && (d == 29 || d == 30))
225 // President Ford's funeral
226 || (y == 2007 && m == January && d == 2)
227 // President Reagan's funeral
228 || (y == 2004 && m == June && d == 11)
229 // September 11-14, 2001
230 || (y == 2001 && m == September && (11 <= d && d <= 14))
231 // President Nixon's funeral
232 || (y == 1994 && m == April && d == 27)
233 // Hurricane Gloria
234 || (y == 1985 && m == September && d == 27)
235 // 1977 Blackout
236 || (y == 1977 && m == July && d == 14)
237 // Funeral of former President Lyndon B. Johnson.
238 || (y == 1973 && m == January && d == 25)
239 // Funeral of former President Harry S. Truman
240 || (y == 1972 && m == December && d == 28)
241 // National Day of Participation for the lunar exploration.
242 || (y == 1969 && m == July && d == 21)
243 // Funeral of former President Eisenhower.
244 || (y == 1969 && m == March && d == 31)
245 // Closed all day - heavy snow.
246 || (y == 1969 && m == February && d == 10)
247 // Day after Independence Day.
248 || (y == 1968 && m == July && d == 5)
249 // June 12-Dec. 31, 1968
250 // Four day week (closed on Wednesdays) - Paperwork Crisis
251 || (y == 1968 && dd >= 163 && w == Wednesday)
252 // Day of mourning for Martin Luther King Jr.
253 || (y == 1968 && m == April && d == 9)
254 // Funeral of President Kennedy
255 || (y == 1963 && m == November && d == 25)
256 // Day before Decoration Day
257 || (y == 1961 && m == May && d == 29)
258 // Day after Christmas
259 || (y == 1958 && m == December && d == 26)
260 // Christmas Eve
261 || ((y == 1954 || y == 1956 || y == 1965)
262 && m == December && d == 24)
263 ) return false;
264
265 return true;
266 }
267
268
270 Weekday w = date.weekday();
271 Day d = date.dayOfMonth(), dd = date.dayOfYear();
272 Month m = date.month();
273 Year y = date.year();
274 Day em = easterMonday(y);
275 if (isWeekend(w)
276 // New Year's Day (possibly moved to Monday if on Sunday)
277 || ((d == 1 || (d == 2 && w == Monday)) && m == January)
278 // Martin Luther King's birthday (third Monday in January)
279 || ((d >= 15 && d <= 21) && w == Monday && m == January
280 && y >= 1983)
281 // Washington's birthday (third Monday in February)
282 || isWashingtonBirthday(d, m, y, w)
283 // Good Friday (2015, 2021, 2023 are half day due to NFP/SIFMA;
284 // see <https://www.sifma.org/resources/general/holiday-schedule/>)
285 || (dd == em-3 && y != 2015 && y != 2021 && y != 2023)
286 // Memorial Day (last Monday in May)
287 || isMemorialDay(d, m, y, w)
288 // Juneteenth (Monday if Sunday or Friday if Saturday)
289 || isJuneteenth(d, m, y, w)
290 // Independence Day (Monday if Sunday or Friday if Saturday)
291 || ((d == 4 || (d == 5 && w == Monday) ||
292 (d == 3 && w == Friday)) && m == July)
293 // Labor Day (first Monday in September)
294 || isLaborDay(d, m, y, w)
295 // Columbus Day (second Monday in October)
296 || isColumbusDay(d, m, y, w)
297 // Veteran's Day (Monday if Sunday)
298 || isVeteransDayNoSaturday(d, m, y, w)
299 // Thanksgiving Day (fourth Thursday in November)
300 || ((d >= 22 && d <= 28) && w == Thursday && m == November)
301 // Christmas (Monday if Sunday or Friday if Saturday)
302 || ((d == 25 || (d == 26 && w == Monday) ||
303 (d == 24 && w == Friday)) && m == December))
304 return false;
305
306 // Special closings
307 if (// President Bush's Funeral
308 (y == 2018 && m == December && d == 5)
309 // Hurricane Sandy
310 || (y == 2012 && m == October && (d == 30))
311 // President Reagan's funeral
312 || (y == 2004 && m == June && d == 11)
313 ) return false;
314
315 return true;
316 }
317
318
320 // Good Friday 2023 was only a half close for SIFMA but SOFR didn't fix
321 if (date == Date(7, April, 2023))
322 return false;
324 }
325
326
328 Weekday w = date.weekday();
329 Day d = date.dayOfMonth();
330 Month m = date.month();
331 Year y = date.year();
332 if (isWeekend(w)
333 // New Year's Day (possibly moved to Monday if on Sunday)
334 || ((d == 1 || (d == 2 && w == Monday)) && m == January)
335 // Memorial Day (last Monday in May)
336 || isMemorialDay(d, m, y, w)
337 // Independence Day (Monday if Sunday)
338 || ((d == 4 || (d == 5 && w == Monday)) && m == July)
339 // Labor Day (first Monday in September)
340 || isLaborDay(d, m, y, w)
341 // Thanksgiving Day (fourth Thursday in November)
342 || ((d >= 22 && d <= 28) && w == Thursday && m == November)
343 // Christmas (Monday if Sunday)
344 || ((d == 25 || (d == 26 && w == Monday)) && m == December))
345 return false; // NOLINT(readability-simplify-boolean-expr)
346 return true;
347 }
348
349
351 // see https://www.frbservices.org/about/holiday-schedules for details
352 Weekday w = date.weekday();
353 Day d = date.dayOfMonth();
354 Month m = date.month();
355 Year y = date.year();
356 if (isWeekend(w)
357 // New Year's Day (possibly moved to Monday if on Sunday)
358 || ((d == 1 || (d == 2 && w == Monday)) && m == January)
359 // Martin Luther King's birthday (third Monday in January)
360 || ((d >= 15 && d <= 21) && w == Monday && m == January
361 && y >= 1983)
362 // Washington's birthday (third Monday in February)
363 || isWashingtonBirthday(d, m, y, w)
364 // Memorial Day (last Monday in May)
365 || isMemorialDay(d, m, y, w)
366 // Juneteenth (Monday if Sunday or Friday if Saturday)
367 || isJuneteenth(d, m, y, w)
368 // Independence Day (Monday if Sunday)
369 || ((d == 4 || (d == 5 && w == Monday)) && m == July)
370 // Labor Day (first Monday in September)
371 || isLaborDay(d, m, y, w)
372 // Columbus Day (second Monday in October)
373 || isColumbusDay(d, m, y, w)
374 // Veteran's Day (Monday if Sunday)
375 || isVeteransDayNoSaturday(d, m, y, w)
376 // Thanksgiving Day (fourth Thursday in November)
377 || ((d >= 22 && d <= 28) && w == Thursday && m == November)
378 // Christmas (Monday if Sunday)
379 || ((d == 25 || (d == 26 && w == Monday)) && m == December))
380 return false; // NOLINT(readability-simplify-boolean-expr)
381 return true;
382 }
383
384}
bool isWeekend(Weekday) const override
Definition: calendar.cpp:189
bool isWeekend(Weekday w) const
Definition: calendar.hpp:255
ext::shared_ptr< Impl > impl_
Definition: calendar.hpp:72
Concrete date class.
Definition: date.hpp:125
Month month() const
Definition: date.cpp:82
Year year() const
Definition: date.cpp:93
Day dayOfMonth() const
Definition: date.hpp:400
Weekday weekday() const
Definition: date.hpp:395
Day dayOfYear() const
One-based (Jan 1st = 1)
Definition: date.hpp:404
bool isBusinessDay(const Date &) const override
bool isBusinessDay(const Date &) const override
bool isBusinessDay(const Date &) const override
bool isBusinessDay(const Date &) const override
bool isBusinessDay(const Date &) const override
bool isBusinessDay(const Date &) const override
bool isBusinessDay(const Date &) const override
@ FederalReserve
Federal Reserve Bankwire System.
@ NYSE
New York stock exchange calendar.
@ LiborImpact
Libor impact calendar.
@ GovernmentBond
government-bond calendar
@ NERC
off-peak days for NERC
@ Settlement
generic settlement calendar
@ SOFR
SOFR fixing calendar.
UnitedStates(Market market)
Integer Year
Year number.
Definition: date.hpp:87
Integer Day
Day number.
Definition: date.hpp:53
Month
Month names.
Definition: date.hpp:57
@ December
Definition: date.hpp:68
@ January
Definition: date.hpp:57
@ July
Definition: date.hpp:63
@ May
Definition: date.hpp:61
@ March
Definition: date.hpp:59
@ February
Definition: date.hpp:58
@ April
Definition: date.hpp:60
@ November
Definition: date.hpp:67
@ October
Definition: date.hpp:66
@ June
Definition: date.hpp:62
@ September
Definition: date.hpp:65
@ Wednesday
Definition: weekday.hpp:44
@ Monday
Definition: weekday.hpp:42
@ Tuesday
Definition: weekday.hpp:43
@ Thursday
Definition: weekday.hpp:45
@ Friday
Definition: weekday.hpp:46
Definition: any.hpp:35