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