1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2004 FIMAT Group
5 Copyright (C) 2007, 2009, 2010, 2011 StatPro Italia srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include <ql/time/calendars/china.hpp>
22#include <ql/errors.hpp>
23#include <set>
24
25namespace QuantLib {
26
27 China::China(Market m) {
28 // all calendar instances share the same implementation instance
29 static ext::shared_ptr<Calendar::Impl> sseImpl(new China::SseImpl);
30 static ext::shared_ptr<Calendar::Impl> IBImpl(new China::IbImpl);
31 switch (m) {
32 case SSE:
33 impl_ = sseImpl;
34 break;
35 case IB:
36 impl_ = IBImpl;
37 break;
38 default:
39 QL_FAIL("unknown market");
40 }
41 }
42
43 bool China::SseImpl::isWeekend(Weekday w) const {
44 return w == Saturday || w == Sunday;
45 }
46
47 bool China::SseImpl::isBusinessDay(const Date& date) const {
48 Weekday w = date.weekday();
49 Day d = date.dayOfMonth();
50 Month m = date.month();
51 Year y = date.year();
52
53 if (isWeekend(w)
54 // New Year's Day
55 || (d == 1 && m == January)
56 || (y == 2005 && d == 3 && m == January)
57 || (y == 2006 && (d == 2 || d == 3) && m == January)
58 || (y == 2007 && d <= 3 && m == January)
59 || (y == 2007 && d == 31 && m == December)
60 || (y == 2009 && d == 2 && m == January)
61 || (y == 2011 && d == 3 && m == January)
62 || (y == 2012 && (d == 2 || d == 3) && m == January)
63 || (y == 2013 && d <= 3 && m == January)
64 || (y == 2014 && d == 1 && m == January)
65 || (y == 2015 && d <= 3 && m == January)
66 || (y == 2017 && d == 2 && m == January)
67 || (y == 2018 && d == 1 && m == January)
68 || (y == 2018 && d == 31 && m == December)
69 || (y == 2019 && d == 1 && m == January)
70 || (y == 2020 && d == 1 && m == January)
71 || (y == 2021 && d == 1 && m == January)
72 || (y == 2022 && d == 3 && m == January)
73 || (y == 2023 && d == 2 && m == January)
74 // Chinese New Year
75 || (y == 2004 && d >= 19 && d <= 28 && m == January)
76 || (y == 2005 && d >= 7 && d <= 15 && m == February)
77 || (y == 2006 && ((d >= 26 && m == January) ||
78 (d <= 3 && m == February)))
79 || (y == 2007 && d >= 17 && d <= 25 && m == February)
80 || (y == 2008 && d >= 6 && d <= 12 && m == February)
81 || (y == 2009 && d >= 26 && d <= 30 && m == January)
82 || (y == 2010 && d >= 15 && d <= 19 && m == February)
83 || (y == 2011 && d >= 2 && d <= 8 && m == February)
84 || (y == 2012 && d >= 23 && d <= 28 && m == January)
85 || (y == 2013 && d >= 11 && d <= 15 && m == February)
86 || (y == 2014 && d >= 31 && m == January)
87 || (y == 2014 && d <= 6 && m == February)
88 || (y == 2015 && d >= 18 && d <= 24 && m == February)
89 || (y == 2016 && d >= 8 && d <= 12 && m == February)
90 || (y == 2017 && ((d >= 27 && m == January) ||
91 (d <= 2 && m == February)))
92 || (y == 2018 && (d >= 15 && d <= 21 && m == February))
93 || (y == 2019 && d >= 4 && d <= 8 && m == February)
94 || (y == 2020 && (d == 24 || (d >= 27 && d <= 31)) && m == January)
95 || (y == 2021 && (d == 11 || d == 12 || d == 15 || d == 16 || d == 17) && m == February)
96 || (y == 2022 && ((d == 31 && m == January) || (d <= 4 && m == February)))
97 || (y == 2023 && d >= 23 && d <= 27 && m == January)
98 // Ching Ming Festival
99 || (y <= 2008 && d == 4 && m == April)
100 || (y == 2009 && d == 6 && m == April)
101 || (y == 2010 && d == 5 && m == April)
102 || (y == 2011 && d >=3 && d <= 5 && m == April)
103 || (y == 2012 && d >= 2 && d <= 4 && m == April)
104 || (y == 2013 && d >= 4 && d <= 5 && m == April)
105 || (y == 2014 && d == 7 && m == April)
106 || (y == 2015 && d >= 5 && d <= 6 && m == April)
107 || (y == 2016 && d == 4 && m == April)
108 || (y == 2017 && d >= 3 && d <= 4 && m == April)
109 || (y == 2018 && d >= 5 && d <= 6 && m == April)
110 || (y == 2019 && d == 5 && m == April)
111 || (y == 2020 && d == 6 && m == April)
112 || (y == 2021 && d == 5 && m == April)
113 || (y == 2022 && d >= 4 && d <= 5 && m == April)
114 || (y == 2023 && d == 5 && m == April)
115 // Labor Day
116 || (y <= 2007 && d >= 1 && d <= 7 && m == May)
117 || (y == 2008 && d >= 1 && d <= 2 && m == May)
118 || (y == 2009 && d == 1 && m == May)
119 || (y == 2010 && d == 3 && m == May)
120 || (y == 2011 && d == 2 && m == May)
121 || (y == 2012 && ((d == 30 && m == April) ||
122 (d == 1 && m == May)))
123 || (y == 2013 && ((d >= 29 && m == April) ||
124 (d == 1 && m == May)))
125 || (y == 2014 && d >= 1 && d <=3 && m == May)
126 || (y == 2015 && d == 1 && m == May)
127 || (y == 2016 && d >= 1 && d <=2 && m == May)
128 || (y == 2017 && d == 1 && m == May)
129 || (y == 2018 && ((d == 30 && m == April) || (d == 1 && m == May)))
130 || (y == 2019 && d >= 1 && d <=3 && m == May)
131 || (y == 2020 && (d == 1 || d == 4 || d == 5) && m == May)
132 || (y == 2021 && (d == 3 || d == 4 || d == 5) && m == May)
133 || (y == 2022 && d >= 2 && d <= 4 && m == May)
134 || (y == 2023 && d >= 1 && d <= 3 && m == May)
135 // Tuen Ng Festival
136 || (y <= 2008 && d == 9 && m == June)
137 || (y == 2009 && (d == 28 || d == 29) && m == May)
138 || (y == 2010 && d >= 14 && d <= 16 && m == June)
139 || (y == 2011 && d >= 4 && d <= 6 && m == June)
140 || (y == 2012 && d >= 22 && d <= 24 && m == June)
141 || (y == 2013 && d >= 10 && d <= 12 && m == June)
142 || (y == 2014 && d == 2 && m == June)
143 || (y == 2015 && d == 22 && m == June)
144 || (y == 2016 && d >= 9 && d <= 10 && m == June)
145 || (y == 2017 && d >= 29 && d <= 30 && m == May)
146 || (y == 2018 && d == 18 && m == June)
147 || (y == 2019 && d == 7 && m == June)
148 || (y == 2020 && d >= 25 && d <= 26 && m == June)
149 || (y == 2021 && d == 14 && m == June)
150 || (y == 2022 && d == 3 && m == June)
151 || (y == 2023 && d >= 22 && d <= 23 && m == June)
152 // Mid-Autumn Festival
153 || (y <= 2008 && d == 15 && m == September)
154 || (y == 2010 && d >= 22 && d <= 24 && m == September)
155 || (y == 2011 && d >= 10 && d <= 12 && m == September)
156 || (y == 2012 && d == 30 && m == September)
157 || (y == 2013 && d >= 19 && d <= 20 && m == September)
158 || (y == 2014 && d == 8 && m == September)
159 || (y == 2015 && d == 27 && m == September)
160 || (y == 2016 && d >= 15 && d <= 16 && m == September)
161 || (y == 2018 && d == 24 && m == September)
162 || (y == 2019 && d == 13 && m == September)
163 || (y == 2021 && (d == 20 || d == 21) && m == September)
164 || (y == 2022 && d == 12 && m == September)
165 || (y == 2023 && d == 29 && m == September)
166 // National Day
167 || (y <= 2007 && d >= 1 && d <= 7 && m == October)
168 || (y == 2008 && ((d >= 29 && m == September) ||
169 (d <= 3 && m == October)))
170 || (y == 2009 && d >= 1 && d <= 8 && m == October)
171 || (y == 2010 && d >= 1 && d <= 7 && m == October)
172 || (y == 2011 && d >= 1 && d <= 7 && m == October)
173 || (y == 2012 && d >= 1 && d <= 7 && m == October)
174 || (y == 2013 && d >= 1 && d <= 7 && m == October)
175 || (y == 2014 && d >= 1 && d <= 7 && m == October)
176 || (y == 2015 && d >= 1 && d <= 7 && m == October)
177 || (y == 2016 && d >= 3 && d <= 7 && m == October)
178 || (y == 2017 && d >= 2 && d <= 6 && m == October)
179 || (y == 2018 && d >= 1 && d <= 5 && m == October)
180 || (y == 2019 && d >= 1 && d <= 7 && m == October)
181 || (y == 2020 && d >= 1 && d <= 2 && m == October)
182 || (y == 2020 && d >= 5 && d <= 8 && m == October)
183 || (y == 2021 && (d == 1 || d == 4 || d == 5 || d == 6 || d == 7) && m == October)
184 || (y == 2022 && d >= 3 && d <= 7 && m == October)
185 || (y == 2023 && d >= 2 && d <= 6 && m == October)
186 // 70th anniversary of the victory of anti-Japaneses war
187 || (y == 2015 && d >= 3 && d <= 4 && m == September)
188 )
189 return false; // NOLINT(readability-simplify-boolean-expr)
190 return true;
191 }
192
193 bool China::IbImpl::isWeekend(Weekday w) const {
194 return w == Saturday || w == Sunday;
195 }
196
197 bool China::IbImpl::isBusinessDay(const Date& date) const {
198 static const Date working_weekends[] = {
199 // 2005
200 Date(5, February, 2005),
201 Date(6, February, 2005),
202 Date(30, April, 2005),
203 Date(8, May, 2005),
204 Date(8, October, 2005),
205 Date(9, October, 2005),
206 Date(31, December, 2005),
207 //2006
208 Date(28, January, 2006),
209 Date(29, April, 2006),
210 Date(30, April, 2006),
211 Date(30, September, 2006),
212 Date(30, December, 2006),
213 Date(31, December, 2006),
214 // 2007
215 Date(17, February, 2007),
216 Date(25, February, 2007),
217 Date(28, April, 2007),
218 Date(29, April, 2007),
219 Date(29, September, 2007),
220 Date(30, September, 2007),
221 Date(29, December, 2007),
222 // 2008
223 Date(2, February, 2008),
224 Date(3, February, 2008),
225 Date(4, May, 2008),
226 Date(27, September, 2008),
227 Date(28, September, 2008),
228 // 2009
229 Date(4, January, 2009),
230 Date(24, January, 2009),
231 Date(1, February, 2009),
232 Date(31, May, 2009),
233 Date(27, September, 2009),
234 Date(10, October, 2009),
235 // 2010
236 Date(20, February, 2010),
237 Date(21, February, 2010),
238 Date(12, June, 2010),
239 Date(13, June, 2010),
240 Date(19, September, 2010),
241 Date(25, September, 2010),
242 Date(26, September, 2010),
243 Date(9, October, 2010),
244 // 2011
245 Date(30, January, 2011),
246 Date(12, February, 2011),
247 Date(2, April, 2011),
248 Date(8, October, 2011),
249 Date(9, October, 2011),
250 Date(31, December, 2011),
251 // 2012
252 Date(21, January, 2012),
253 Date(29, January, 2012),
254 Date(31, March, 2012),
255 Date(1, April, 2012),
256 Date(28, April, 2012),
257 Date(29, September, 2012),
258 // 2013
259 Date(5,January,2013),
260 Date(6,January,2013),
261 Date(16,February,2013),
262 Date(17,February,2013),
263 Date(7,April,2013),
264 Date(27,April,2013),
265 Date(28,April,2013),
266 Date(8,June,2013),
267 Date(9,June,2013),
268 Date(22,September,2013),
269 Date(29,September,2013),
270 Date(12,October,2013),
271 // 2014
272 Date(26,January,2014),
273 Date(8,February,2014),
274 Date(4,May,2014),
275 Date(28,September,2014),
276 Date(11,October,2014),
277 // 2015
278 Date(4,January,2015),
279 Date(15,February,2015),
280 Date(28,February,2015),
281 Date(6,September,2015),
282 Date(10,October,2015),
283 // 2016
284 Date(6,February,2016),
285 Date(14,February,2016),
286 Date(12,June,2016),
287 Date(18,September,2016),
288 Date(8,October,2016),
289 Date(9,October,2016),
290 // 2017
291 Date(22,January,2017),
292 Date(4,February,2017),
293 Date(1,April,2017),
294 Date(27,May,2017),
295 Date(30,September,2017),
296 // 2018
297 Date(11, February, 2018),
298 Date(24, February, 2018),
299 Date(8, April, 2018),
300 Date(28, April, 2018),
301 Date(29, September, 2018),
302 Date(30, September, 2018),
303 Date(29, December, 2018),
304 // 2019
305 Date(2, February, 2019),
306 Date(3, February, 2019),
307 Date(28, April, 2019),
308 Date(5, May, 2019),
309 Date(29, September, 2019),
310 Date(12, October, 2019),
311 // 2020
312 Date(19, January, 2020),
313 Date(26, April, 2020),
314 Date(9, May, 2020),
315 Date(28, June, 2020),
316 Date(27, September, 2020),
317 Date(10, October, 2020),
318 // 2021
319 Date(7, February, 2021),
320 Date(20, February, 2021),
321 Date(25, April, 2021),
322 Date(8, May, 2021),
323 Date(18, September, 2021),
324 Date(26, September, 2021),
325 Date(9, October, 2021),
326 // 2022
327 Date(29, January, 2022),
328 Date(30, January, 2022),
329 Date(2, April, 2022),
330 Date(24, April, 2022),
331 Date(7, May, 2022),
332 Date(8, October, 2022),
333 Date(9, October, 2022),
334 // 2023
335 Date(28, January, 2023),
336 Date(29, January, 2023),
337 Date(23, April, 2023),
338 Date(6, May, 2023),
339 Date(25, June, 2023),
340 Date(7, October, 2023),
341 Date(8, October, 2023)
342 };
343 static const Size n =
344 sizeof(working_weekends)/sizeof(working_weekends[0]);
345 static const std::set<Date> workingWeekends(working_weekends+0,
346 working_weekends+n);
347
348 // If it is already a SSE business day, it must be a IB business day
349 return sseImpl->isBusinessDay(date) ||
350 (workingWeekends.find(x: date) != workingWeekends.end());
351 }
352
353}
354
355

source code of quantlib/ql/time/calendars/china.cpp