From 8cd9096a80eecf9752d548da184ab0494fd5d007 Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Mon, 13 Jan 2025 12:13:07 -0600 Subject: [PATCH] Sync from QuantLib 1.37 (rc) --- ChangeLog | 5 +++ src/ql/time/calendars/newzealand.cpp | 61 +++++++++++++++++++++----- src/ql/time/calendars/newzealand.hpp | 44 +++++++++++++------ src/ql/time/calendars/unitedstates.cpp | 7 ++- 4 files changed, 90 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6ccd40d..58c6202 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-01-13 Dirk Eddelbuettel + + * src/ql/time/calendars/newzealand.?pp: Updated from QuantLib 1.37 (rc) + * src/ql/time/calendars/unitedstates.cpp: Idem + 2024-10-15 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.0.13 diff --git a/src/ql/time/calendars/newzealand.cpp b/src/ql/time/calendars/newzealand.cpp index 497abd8..5ac0037 100644 --- a/src/ql/time/calendars/newzealand.cpp +++ b/src/ql/time/calendars/newzealand.cpp @@ -21,13 +21,7 @@ namespace QuantLib { - NewZealand::NewZealand() { - // all calendar instances share the same implementation instance - static ext::shared_ptr impl(new NewZealand::Impl); - impl_ = impl; - } - - bool NewZealand::Impl::isBusinessDay(const Date& date) const { + bool NewZealand::CommonImpl::isBusinessDay(const Date& date) const { Weekday w = date.weekday(); Day d = date.dayOfMonth(), dd = date.dayOfYear(); Month m = date.month(); @@ -40,16 +34,14 @@ namespace QuantLib { // Day after New Year's Day (possibly moved to Mon or Tuesday) || ((d == 2 || (d == 4 && (w == Monday || w == Tuesday))) && m == January) - // Anniversary Day, Monday nearest January 22nd - || ((d >= 19 && d <= 25) && w == Monday && m == January) - // Waitangi Day. February 6th ("Mondayised" since 2013) + // Waitangi Day. February 6th (possibly moved to Monday since 2013) || (d == 6 && m == February) || ((d == 7 || d == 8) && w == Monday && m == February && y > 2013) // Good Friday || (dd == em-3) // Easter Monday || (dd == em) - // ANZAC Day. April 25th ("Mondayised" since 2013) + // ANZAC Day. April 25th (possibly moved to Monday since 2013) || (d == 25 && m == April) || ((d == 26 || d == 27) && w == Monday && m == April && y > 2013) // Queen's Birthday, first Monday in June @@ -81,9 +73,54 @@ namespace QuantLib { || (d == 14 && m == July && (y == 2023 || y == 2028)) || (d == 15 && m == July && (y == 2039 || y == 2050)) || (d == 18 && m == July && y == 2036) - || (d == 19 && m == July && (y == 2041 || y == 2047))) + || (d == 19 && m == July && (y == 2041 || y == 2047)) + // Queen Elizabeth's funeral + || (d == 26 && m == September && y == 2022)) return false; // NOLINT(readability-simplify-boolean-expr) return true; } + bool NewZealand::WellingtonImpl::isBusinessDay(const Date& date) const { + if (!NewZealand::CommonImpl::isBusinessDay(date)) + return false; + Weekday w = date.weekday(); + Day d = date.dayOfMonth(); + Month m = date.month(); + // Anniversary Day, Monday nearest January 22nd + if ((d >= 19 && d <= 25) && w == Monday && m == January) + return false; // NOLINT(readability-simplify-boolean-expr) + return true; + } + + bool NewZealand::AucklandImpl::isBusinessDay(const Date& date) const { + if (!NewZealand::CommonImpl::isBusinessDay(date)) + return false; + Weekday w = date.weekday(); + Day d = date.dayOfMonth(); + Month m = date.month(); + // Anniversary Day, Monday nearest January 29nd + if ((d >= 26 && w == Monday && m == January) + || (d == 1 && w == Monday && m == February)) + return false; // NOLINT(readability-simplify-boolean-expr) + return true; + } + + + NewZealand::NewZealand(Market market) { + // all calendar instances for a given market share the same implementation instance + static auto wellingtonImpl = ext::make_shared(); + static auto aucklandImpl = ext::make_shared(); + + switch (market) { + case Wellington: + impl_ = wellingtonImpl; + break; + case Auckland: + impl_ = aucklandImpl; + break; + default: + QL_FAIL("unknown market"); + } + } + } diff --git a/src/ql/time/calendars/newzealand.hpp b/src/ql/time/calendars/newzealand.hpp index 29abd65..d5a074d 100644 --- a/src/ql/time/calendars/newzealand.hpp +++ b/src/ql/time/calendars/newzealand.hpp @@ -29,26 +29,33 @@ namespace QuantLib { //! New Zealand calendar - /*! Holidays: + /*! Common holidays:
  • Saturdays
  • Sundays
  • -
  • New Year's Day, January 1st (possibly moved to Monday or - Tuesday)
  • -
  • Day after New Year's Day, January 2st (possibly moved to - Monday or Tuesday)
  • -
  • Anniversary Day, Monday nearest January 22nd
  • -
  • Waitangi Day. February 6th
  • +
  • New Year's Day, January 1st (possibly moved to Monday or Tuesday)
  • +
  • Day after New Year's Day, January 2st (possibly moved to Monday or Tuesday)
  • +
  • Waitangi Day. February 6th (possibly moved to Monday since 2013)
  • Good Friday
  • Easter Monday
  • -
  • ANZAC Day. April 25th
  • +
  • ANZAC Day. April 25th (possibly moved to Monday since 2013)
  • Queen's Birthday, first Monday in June
  • Labour Day, fourth Monday in October
  • Christmas, December 25th (possibly moved to Monday or Tuesday)
  • -
  • Boxing Day, December 26th (possibly moved to Monday or - Tuesday)
  • +
  • Boxing Day, December 26th (possibly moved to Monday or Tuesday)
  • Matariki, in June or July, official calendar released for years 2022-2052
+ + Additional holidays for Wellington: +
    +
  • Anniversary Day, Monday nearest January 22nd
  • +
+ + Additional holidays for Auckland: +
    +
  • Anniversary Day, Monday nearest January 29nd
  • +
+ \note The holiday rules for New Zealand were documented by David Gilbert for IDB (http://www.jrefinery.com/ibd/) The Matariki holiday calendar has been released by the NZ Government @@ -58,13 +65,24 @@ namespace QuantLib { */ class NewZealand : public Calendar { private: - class Impl final : public Calendar::WesternImpl { + class CommonImpl : public Calendar::WesternImpl { + public: + bool isBusinessDay(const Date&) const override; + }; + class WellingtonImpl final : public CommonImpl { + public: + std::string name() const override { return "New Zealand (Wellington)"; } + bool isBusinessDay(const Date&) const override; + }; + class AucklandImpl final : public CommonImpl { public: - std::string name() const override { return "New Zealand"; } + std::string name() const override { return "New Zealand (Auckland)"; } bool isBusinessDay(const Date&) const override; }; public: - NewZealand(); + //! NZ calendars + enum Market { Wellington, Auckland }; + explicit NewZealand(Market market = Wellington); }; } diff --git a/src/ql/time/calendars/unitedstates.cpp b/src/ql/time/calendars/unitedstates.cpp index 198ff9a..39fa31f 100644 --- a/src/ql/time/calendars/unitedstates.cpp +++ b/src/ql/time/calendars/unitedstates.cpp @@ -7,6 +7,7 @@ Copyright (C) 2017 Peter Caspers Copyright (C) 2017 Oleg Kulkov Copyright (C) 2023 Skandinaviska Enskilda Banken AB (publ) + Copyright (C) 2024 Dirk Eddelbuettel This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ @@ -219,8 +220,10 @@ namespace QuantLib { return false; // Special closings - if (// President Bush's Funeral - (y == 2018 && m == December && d == 5) + if (// President Carter's Funeral + (y == 2025 && m == January && d == 9) + // President Bush's Funeral + || (y == 2018 && m == December && d == 5) // Hurricane Sandy || (y == 2012 && m == October && (d == 29 || d == 30)) // President Ford's funeral