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 | |
25 | namespace 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 | |