From df7ad02a47141a6f8b94b61dc922d388f1700876 Mon Sep 17 00:00:00 2001 From: wilsonfreitas Date: Sun, 29 Oct 2023 18:41:23 -0300 Subject: [PATCH] Added support to python_market_calendars --- bizdays.py | 20 +++++++++++++++++--- pyproject.toml | 7 +++++-- test_calendar.py | 6 ++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/bizdays.py b/bizdays.py index dc2969e..2cde0c7 100644 --- a/bizdays.py +++ b/bizdays.py @@ -3,6 +3,7 @@ import re from datetime import datetime, date, timedelta from itertools import cycle +from typing import TextIO PANDAS_INSTALLED = False @@ -972,9 +973,22 @@ def load(cls, name=None, filename=None): """ if filename: res = _checkfile(filename) + return cls._load_calendar_from_file(res) elif name: - res = _checklocalfile(name) + if name.startswith("PMC/"): + try: + import pandas_market_calendars as mcal + except ImportError: + raise Exception("pandas_market_calendars must be installed to use PMC calendars") + cal = mcal.get_calendar(name[4:]) + hol = cal.holidays() + return Calendar((d.item() for d in hol.holidays), weekdays=("Saturday", "Sunday"), name=name) + else: + res = _checklocalfile(name) + return cls._load_calendar_from_file(res) + @classmethod + def _load_calendar_from_file(cls, res: dict[str, TextIO]) -> "Calendar": w = "|".join(w.lower() for w in cls._weekdays) wre = "^%s$" % w _holidays = [] @@ -1008,7 +1022,7 @@ def __str__(self): __repr__ = __str__ -def _checkfile(fname): +def _checkfile(fname: str) -> dict[str, TextIO]: if not os.path.exists(fname): raise Exception(f"Invalid calendar: {fname}") name = os.path.split(fname)[-1] @@ -1019,7 +1033,7 @@ def _checkfile(fname): return {"name": name, "iter": open(fname)} -def _checklocalfile(name): +def _checklocalfile(name: str) -> dict[str, TextIO]: dir = os.path.dirname(__file__) fname = f"{dir}/{name}.cal" if not os.path.exists(fname): diff --git a/pyproject.toml b/pyproject.toml index 0bb30cf..8838671 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,10 +7,13 @@ readme = "README.md" include = ["ANBIMA.cal", "B3.cal"] [tool.poetry.dependencies] -python = "^3.7" +python = "^3.8" [tool.poetry.group.dev.dependencies] pytest = "^7.1.3" +pycodestyle = "^2.11.1" +pandas-market-calendars = "4.3.1" +ipykernel = "^6.26.0" [tool.poetry.group.docs.dependencies] Sphinx = "^5.1.1" @@ -18,7 +21,7 @@ nbsphinx = "^0.8.9" matplotlib = "^3.5.3" numpy = "^1.23.2" lxml = "^4.9.1" -pandas = "^1.4.4" +pandas = "^1.5.3" alabaster = "^0.7.12" ipywidgets = "^8.0.2" diff --git a/test_calendar.py b/test_calendar.py index f36ecce..7029614 100644 --- a/test_calendar.py +++ b/test_calendar.py @@ -12,3 +12,9 @@ def test_calendar_load(): def test_calendar_load_invalid(): with pytest.raises(Exception): cal = Calendar.load("B1") + + +def test_calendar_load_pmc(): + cal = Calendar.load("PMC/B3") + assert cal.name == "PMC/B3" + assert len(cal.holidays) > 4000