pandas-market-calendars 5.1.0__py3-none-any.whl → 5.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. pandas_market_calendars/__init__.py +39 -39
  2. pandas_market_calendars/calendar_registry.py +58 -57
  3. pandas_market_calendars/calendar_utils.py +1151 -1151
  4. pandas_market_calendars/calendars/asx.py +100 -70
  5. pandas_market_calendars/calendars/bmf.py +225 -219
  6. pandas_market_calendars/calendars/bse.py +433 -425
  7. pandas_market_calendars/calendars/cboe.py +153 -149
  8. pandas_market_calendars/calendars/cme.py +417 -405
  9. pandas_market_calendars/calendars/cme_globex_agriculture.py +172 -172
  10. pandas_market_calendars/calendars/cme_globex_base.py +127 -119
  11. pandas_market_calendars/calendars/cme_globex_crypto.py +166 -158
  12. pandas_market_calendars/calendars/cme_globex_energy_and_metals.py +224 -216
  13. pandas_market_calendars/calendars/cme_globex_equities.py +131 -123
  14. pandas_market_calendars/calendars/cme_globex_fixed_income.py +136 -136
  15. pandas_market_calendars/calendars/cme_globex_fx.py +101 -101
  16. pandas_market_calendars/calendars/eurex.py +139 -131
  17. pandas_market_calendars/calendars/eurex_fixed_income.py +106 -98
  18. pandas_market_calendars/calendars/hkex.py +437 -431
  19. pandas_market_calendars/calendars/ice.py +89 -81
  20. pandas_market_calendars/calendars/iex.py +163 -155
  21. pandas_market_calendars/calendars/jpx.py +125 -117
  22. pandas_market_calendars/calendars/lse.py +126 -118
  23. pandas_market_calendars/calendars/mirror.py +144 -144
  24. pandas_market_calendars/calendars/nyse.py +1462 -1466
  25. pandas_market_calendars/calendars/ose.py +124 -118
  26. pandas_market_calendars/calendars/sifma.py +391 -383
  27. pandas_market_calendars/calendars/six.py +144 -136
  28. pandas_market_calendars/calendars/sse.py +305 -315
  29. pandas_market_calendars/calendars/tase.py +232 -224
  30. pandas_market_calendars/calendars/tsx.py +193 -185
  31. pandas_market_calendars/class_registry.py +115 -115
  32. pandas_market_calendars/holidays/cme.py +385 -385
  33. pandas_market_calendars/holidays/cme_globex.py +214 -214
  34. pandas_market_calendars/holidays/cn.py +1476 -1476
  35. pandas_market_calendars/holidays/jp.py +401 -401
  36. pandas_market_calendars/holidays/jpx_equinox.py +506 -506
  37. pandas_market_calendars/holidays/nyse.py +1536 -1536
  38. pandas_market_calendars/holidays/oz.py +82 -63
  39. pandas_market_calendars/holidays/sifma.py +350 -350
  40. pandas_market_calendars/holidays/uk.py +186 -186
  41. pandas_market_calendars/holidays/us.py +376 -376
  42. pandas_market_calendars/market_calendar.py +1006 -1008
  43. {pandas_market_calendars-5.1.0.dist-info → pandas_market_calendars-5.1.3.dist-info}/METADATA +5 -4
  44. pandas_market_calendars-5.1.3.dist-info/RECORD +50 -0
  45. {pandas_market_calendars-5.1.0.dist-info → pandas_market_calendars-5.1.3.dist-info}/WHEEL +1 -1
  46. pandas_market_calendars-5.1.0.dist-info/RECORD +0 -50
  47. {pandas_market_calendars-5.1.0.dist-info → pandas_market_calendars-5.1.3.dist-info}/licenses/LICENSE +0 -0
  48. {pandas_market_calendars-5.1.0.dist-info → pandas_market_calendars-5.1.3.dist-info}/licenses/NOTICE +0 -0
  49. {pandas_market_calendars-5.1.0.dist-info → pandas_market_calendars-5.1.3.dist-info}/top_level.txt +0 -0
@@ -1,185 +1,193 @@
1
- from datetime import time
2
- from itertools import chain
3
-
4
- import pandas as pd
5
- from pandas.tseries.holiday import (
6
- AbstractHolidayCalendar,
7
- DateOffset,
8
- GoodFriday,
9
- Holiday,
10
- MO,
11
- weekend_to_monday,
12
- )
13
- from zoneinfo import ZoneInfo
14
-
15
- from pandas_market_calendars.holidays.uk import (
16
- BoxingDay,
17
- WeekendBoxingDay,
18
- WeekendChristmas,
19
- )
20
- from pandas_market_calendars.market_calendar import (
21
- MarketCalendar,
22
- MONDAY,
23
- TUESDAY,
24
- WEDNESDAY,
25
- THURSDAY,
26
- FRIDAY,
27
- )
28
-
29
- # New Year's Day
30
- TSXNewYearsDay = Holiday(
31
- "New Year's Day",
32
- month=1,
33
- day=1,
34
- observance=weekend_to_monday,
35
- )
36
- # Ontario Family Day
37
- FamilyDay = Holiday(
38
- "Family Day",
39
- month=2,
40
- day=1,
41
- offset=DateOffset(weekday=MO(3)),
42
- start_date="2008-01-01",
43
- )
44
- # Victoria Day
45
- # https://www.timeanddate.com/holidays/canada/victoria-day
46
- VictoriaDay = Holiday(
47
- "Victoria Day",
48
- month=5,
49
- day=24,
50
- offset=DateOffset(weekday=MO(-1)),
51
- )
52
- # Canada Day
53
- CanadaDay = Holiday(
54
- "Canada Day",
55
- month=7,
56
- day=1,
57
- observance=weekend_to_monday,
58
- )
59
- # Civic Holiday
60
- CivicHoliday = Holiday(
61
- "Civic Holiday",
62
- month=8,
63
- day=1,
64
- offset=DateOffset(weekday=MO(1)),
65
- )
66
- # Labor Day
67
- LaborDay = Holiday(
68
- "Labor Day",
69
- month=9,
70
- day=1,
71
- offset=DateOffset(weekday=MO(1)),
72
- )
73
- # Thanksgiving
74
- Thanksgiving = Holiday(
75
- "Thanksgiving",
76
- month=10,
77
- day=1,
78
- offset=DateOffset(weekday=MO(2)),
79
- )
80
-
81
- Christmas = Holiday(
82
- "Christmas",
83
- month=12,
84
- day=25,
85
- )
86
-
87
- ChristmasEveEarlyClose2010Onwards = Holiday(
88
- "Christmas Eve Early Close",
89
- month=12,
90
- day=24,
91
- days_of_week=(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY),
92
- start_date=pd.Timestamp("2010-01-01"),
93
- )
94
-
95
- September11Closings2001 = [
96
- pd.Timestamp("2001-09-11", tz="UTC"),
97
- pd.Timestamp("2001-09-12", tz="UTC"),
98
- ]
99
-
100
-
101
- class TSXExchangeCalendar(MarketCalendar):
102
- """
103
- Exchange calendar for the Toronto Stock Exchange
104
-
105
- Open Time: 9:30 AM, EST
106
- Close Time: 4:00 PM, EST
107
-
108
- Regularly-Observed Holidays:
109
- - New Years Day (observed on first business day on/after)
110
- - Family Day (Third Monday in February, starting in 2008)
111
- - Good Friday
112
- - Victoria Day (Monday before May 25th)
113
- - Canada Day (July 1st, observed first business day after)
114
- - Civic Holiday (First Monday in August)
115
- - Labor Day (First Monday in September)
116
- - Thanksgiving (Second Monday in October)
117
- - Christmas Day
118
- - Dec. 26th if Christmas is on a Sunday
119
- - Dec. 27th if Christmas is on a weekend
120
- - Boxing Day
121
- - Dec. 27th if Christmas is on a Sunday
122
- - Dec. 28th if Boxing Day is on a weekend
123
-
124
- Early closes:
125
- - Starting in 2010, if Christmas Eve falls on a weekday, the market
126
- closes at 1:00 pm that day. If it falls on a weekend, there is no
127
- early close.
128
- """
129
-
130
- aliases = ["TSX", "TSXV"]
131
-
132
- regular_market_times = {
133
- "market_open": ((None, time(9, 30)),),
134
- "market_close": ((None, time(16)),),
135
- }
136
-
137
- @property
138
- def name(self):
139
- return "TSX"
140
-
141
- @property
142
- def full_name(self):
143
- return "Toronto Stock Exchange"
144
-
145
- @property
146
- def tz(self):
147
- return ZoneInfo("Canada/Eastern")
148
-
149
- regular_early_close = time(13)
150
-
151
- @property
152
- def regular_holidays(self):
153
- return AbstractHolidayCalendar(
154
- rules=[
155
- TSXNewYearsDay,
156
- FamilyDay,
157
- GoodFriday,
158
- VictoriaDay,
159
- CanadaDay,
160
- CivicHoliday,
161
- LaborDay,
162
- Thanksgiving,
163
- Christmas,
164
- WeekendChristmas,
165
- BoxingDay,
166
- WeekendBoxingDay,
167
- ]
168
- )
169
-
170
- @property
171
- def adhoc_holidays(self):
172
- return list(
173
- chain(
174
- September11Closings2001,
175
- )
176
- )
177
-
178
- @property
179
- def special_closes(self):
180
- return [
181
- (
182
- self.regular_early_close,
183
- AbstractHolidayCalendar([ChristmasEveEarlyClose2010Onwards]),
184
- )
185
- ]
1
+ from datetime import time
2
+ from itertools import chain
3
+
4
+ import pandas as pd
5
+ from pandas.tseries.holiday import (
6
+ AbstractHolidayCalendar,
7
+ DateOffset,
8
+ GoodFriday,
9
+ Holiday,
10
+ MO,
11
+ weekend_to_monday,
12
+ )
13
+ import sys
14
+
15
+ # check python versiOn aNd import accordingly
16
+ if sys.version_info >= (3, 9):
17
+ # For Python 3.9 and later, import directly
18
+ from zoneinfo import ZoneInfo
19
+ else:
20
+ # For Python 3.8 and earlier, import from backports
21
+ from backports.zoneinfo import ZoneInfo
22
+
23
+ from pandas_market_calendars.holidays.uk import (
24
+ BoxingDay,
25
+ WeekendBoxingDay,
26
+ WeekendChristmas,
27
+ )
28
+ from pandas_market_calendars.market_calendar import (
29
+ MarketCalendar,
30
+ MONDAY,
31
+ TUESDAY,
32
+ WEDNESDAY,
33
+ THURSDAY,
34
+ FRIDAY,
35
+ )
36
+
37
+ # New Year's Day
38
+ TSXNewYearsDay = Holiday(
39
+ "New Year's Day",
40
+ month=1,
41
+ day=1,
42
+ observance=weekend_to_monday,
43
+ )
44
+ # Ontario Family Day
45
+ FamilyDay = Holiday(
46
+ "Family Day",
47
+ month=2,
48
+ day=1,
49
+ offset=DateOffset(weekday=MO(3)),
50
+ start_date="2008-01-01",
51
+ )
52
+ # Victoria Day
53
+ # https://www.timeanddate.com/holidays/canada/victoria-day
54
+ VictoriaDay = Holiday(
55
+ "Victoria Day",
56
+ month=5,
57
+ day=24,
58
+ offset=DateOffset(weekday=MO(-1)),
59
+ )
60
+ # Canada Day
61
+ CanadaDay = Holiday(
62
+ "Canada Day",
63
+ month=7,
64
+ day=1,
65
+ observance=weekend_to_monday,
66
+ )
67
+ # Civic Holiday
68
+ CivicHoliday = Holiday(
69
+ "Civic Holiday",
70
+ month=8,
71
+ day=1,
72
+ offset=DateOffset(weekday=MO(1)),
73
+ )
74
+ # Labor Day
75
+ LaborDay = Holiday(
76
+ "Labor Day",
77
+ month=9,
78
+ day=1,
79
+ offset=DateOffset(weekday=MO(1)),
80
+ )
81
+ # Thanksgiving
82
+ Thanksgiving = Holiday(
83
+ "Thanksgiving",
84
+ month=10,
85
+ day=1,
86
+ offset=DateOffset(weekday=MO(2)),
87
+ )
88
+
89
+ Christmas = Holiday(
90
+ "Christmas",
91
+ month=12,
92
+ day=25,
93
+ )
94
+
95
+ ChristmasEveEarlyClose2010Onwards = Holiday(
96
+ "Christmas Eve Early Close",
97
+ month=12,
98
+ day=24,
99
+ days_of_week=(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY),
100
+ start_date=pd.Timestamp("2010-01-01"),
101
+ )
102
+
103
+ September11Closings2001 = [
104
+ pd.Timestamp("2001-09-11", tz="UTC"),
105
+ pd.Timestamp("2001-09-12", tz="UTC"),
106
+ ]
107
+
108
+
109
+ class TSXExchangeCalendar(MarketCalendar):
110
+ """
111
+ Exchange calendar for the Toronto Stock Exchange
112
+
113
+ Open Time: 9:30 AM, EST
114
+ Close Time: 4:00 PM, EST
115
+
116
+ Regularly-Observed Holidays:
117
+ - New Years Day (observed on first business day on/after)
118
+ - Family Day (Third Monday in February, starting in 2008)
119
+ - Good Friday
120
+ - Victoria Day (Monday before May 25th)
121
+ - Canada Day (July 1st, observed first business day after)
122
+ - Civic Holiday (First Monday in August)
123
+ - Labor Day (First Monday in September)
124
+ - Thanksgiving (Second Monday in October)
125
+ - Christmas Day
126
+ - Dec. 26th if Christmas is on a Sunday
127
+ - Dec. 27th if Christmas is on a weekend
128
+ - Boxing Day
129
+ - Dec. 27th if Christmas is on a Sunday
130
+ - Dec. 28th if Boxing Day is on a weekend
131
+
132
+ Early closes:
133
+ - Starting in 2010, if Christmas Eve falls on a weekday, the market
134
+ closes at 1:00 pm that day. If it falls on a weekend, there is no
135
+ early close.
136
+ """
137
+
138
+ aliases = ["TSX", "TSXV"]
139
+
140
+ regular_market_times = {
141
+ "market_open": ((None, time(9, 30)),),
142
+ "market_close": ((None, time(16)),),
143
+ }
144
+
145
+ @property
146
+ def name(self):
147
+ return "TSX"
148
+
149
+ @property
150
+ def full_name(self):
151
+ return "Toronto Stock Exchange"
152
+
153
+ @property
154
+ def tz(self):
155
+ return ZoneInfo("Canada/Eastern")
156
+
157
+ regular_early_close = time(13)
158
+
159
+ @property
160
+ def regular_holidays(self):
161
+ return AbstractHolidayCalendar(
162
+ rules=[
163
+ TSXNewYearsDay,
164
+ FamilyDay,
165
+ GoodFriday,
166
+ VictoriaDay,
167
+ CanadaDay,
168
+ CivicHoliday,
169
+ LaborDay,
170
+ Thanksgiving,
171
+ Christmas,
172
+ WeekendChristmas,
173
+ BoxingDay,
174
+ WeekendBoxingDay,
175
+ ]
176
+ )
177
+
178
+ @property
179
+ def adhoc_holidays(self):
180
+ return list(
181
+ chain(
182
+ September11Closings2001,
183
+ )
184
+ )
185
+
186
+ @property
187
+ def special_closes(self):
188
+ return [
189
+ (
190
+ self.regular_early_close,
191
+ AbstractHolidayCalendar([ChristmasEveEarlyClose2010Onwards]),
192
+ )
193
+ ]
@@ -1,115 +1,115 @@
1
- import inspect
2
- from pprint import pformat
3
-
4
-
5
- def _regmeta_instance_factory(cls, name, *args, **kwargs):
6
- """
7
- :param cls(RegisteryMeta): registration meta class
8
- :param name(str): name of class that needs to be instantiated
9
- :param args(Optional(tuple)): instance positional arguments
10
- :param kwargs(Optional(dict)): instance named arguments
11
- :return: class instance
12
- """
13
- try:
14
- class_ = cls._regmeta_class_registry[name]
15
- except KeyError:
16
- raise RuntimeError(
17
- "Class {} is not one of the registered classes: {}".format(
18
- name, cls._regmeta_class_registry.keys()
19
- )
20
- )
21
- return class_(*args, **kwargs)
22
-
23
-
24
- def _regmeta_register_class(cls, regcls, name):
25
- """
26
- :param cls(RegisteryMeta): registration base class
27
- :param regcls(class): class to be registered
28
- :param name(str): name of the class to be registered
29
- """
30
- if hasattr(regcls, "aliases"):
31
- if regcls.aliases:
32
- for alias in regcls.aliases:
33
- cls._regmeta_class_registry[alias] = regcls
34
- else:
35
- cls._regmeta_class_registry[name] = regcls
36
- else:
37
- cls._regmeta_class_registry[name] = regcls
38
-
39
-
40
- class RegisteryMeta(type):
41
- """
42
- Metaclass used to register all classes inheriting from RegisteryMeta
43
- """
44
-
45
- def __new__(mcs, name, bases, attr):
46
- cls = super(RegisteryMeta, mcs).__new__(mcs, name, bases, attr)
47
- if not hasattr(cls, "_regmeta_class_registry"):
48
- cls._regmeta_class_registry = {}
49
- cls.factory = classmethod(_regmeta_instance_factory)
50
-
51
- return cls
52
-
53
- def __init__(cls, name, bases, attr):
54
- if not inspect.isabstract(cls):
55
- _regmeta_register_class(cls, cls, name)
56
- for b in bases:
57
- if hasattr(b, "_regmeta_class_registry"):
58
- _regmeta_register_class(b, cls, name)
59
-
60
- super(RegisteryMeta, cls).__init__(name, bases, attr)
61
-
62
- cls.regular_market_times = ProtectedDict(cls.regular_market_times)
63
- cls.open_close_map = ProtectedDict(cls.open_close_map)
64
-
65
- cls.special_market_open = cls.special_opens
66
- cls.special_market_open_adhoc = cls.special_opens_adhoc
67
-
68
- cls.special_market_close = cls.special_closes
69
- cls.special_market_close_adhoc = cls.special_closes_adhoc
70
-
71
-
72
- class ProtectedDict(dict):
73
- def __init__(self, *args, **kwargs):
74
- super().__init__(*args, **kwargs)
75
- # __init__ is bypassed when unpickling, which causes __setitem__ to fail
76
- # without the _INIT_RAN_NORMALLY flag
77
- self._INIT_RAN_NORMALLY = True
78
-
79
- def _set(self, key, value):
80
- return super().__setitem__(key, value)
81
-
82
- def _del(self, key):
83
- return super().__delitem__(key)
84
-
85
- def __setitem__(self, key, value):
86
- if not hasattr(self, "_INIT_RAN_NORMALLY"):
87
- return self._set(key, value)
88
-
89
- raise TypeError(
90
- "You cannot set a value directly, you can change regular_market_times "
91
- "using .change_time, .add_time or .remove_time."
92
- )
93
-
94
- def __delitem__(self, key):
95
- if not hasattr(self, "_INIT_RAN_NORMALLY"):
96
- return self._del(key)
97
-
98
- raise TypeError(
99
- "You cannot delete an item directly. You can change regular_market_times "
100
- "using .change_time, .add_time or .remove_time"
101
- )
102
-
103
- def __repr__(self):
104
- return self.__class__.__name__ + "(" + super().__repr__() + ")"
105
-
106
- def __str__(self):
107
- try:
108
- formatted = pformat(dict(self), sort_dicts=False) # sort_dicts apparently not available < python3.8
109
- except TypeError:
110
- formatted = pformat(dict(self))
111
-
112
- return self.__class__.__name__ + "(\n" + formatted + "\n)"
113
-
114
- def copy(self):
115
- return self.__class__(super().copy())
1
+ import inspect
2
+ from pprint import pformat
3
+
4
+
5
+ def _regmeta_instance_factory(cls, name, *args, **kwargs):
6
+ """
7
+ :param cls(RegisteryMeta): registration meta class
8
+ :param name(str): name of class that needs to be instantiated
9
+ :param args(Optional(tuple)): instance positional arguments
10
+ :param kwargs(Optional(dict)): instance named arguments
11
+ :return: class instance
12
+ """
13
+ try:
14
+ class_ = cls._regmeta_class_registry[name]
15
+ except KeyError:
16
+ raise RuntimeError(
17
+ "Class {} is not one of the registered classes: {}".format(
18
+ name, cls._regmeta_class_registry.keys()
19
+ )
20
+ )
21
+ return class_(*args, **kwargs)
22
+
23
+
24
+ def _regmeta_register_class(cls, regcls, name):
25
+ """
26
+ :param cls(RegisteryMeta): registration base class
27
+ :param regcls(class): class to be registered
28
+ :param name(str): name of the class to be registered
29
+ """
30
+ if hasattr(regcls, "aliases"):
31
+ if regcls.aliases:
32
+ for alias in regcls.aliases:
33
+ cls._regmeta_class_registry[alias] = regcls
34
+ else:
35
+ cls._regmeta_class_registry[name] = regcls
36
+ else:
37
+ cls._regmeta_class_registry[name] = regcls
38
+
39
+
40
+ class RegisteryMeta(type):
41
+ """
42
+ Metaclass used to register all classes inheriting from RegisteryMeta
43
+ """
44
+
45
+ def __new__(mcs, name, bases, attr):
46
+ cls = super(RegisteryMeta, mcs).__new__(mcs, name, bases, attr)
47
+ if not hasattr(cls, "_regmeta_class_registry"):
48
+ cls._regmeta_class_registry = {}
49
+ cls.factory = classmethod(_regmeta_instance_factory)
50
+
51
+ return cls
52
+
53
+ def __init__(cls, name, bases, attr):
54
+ if not inspect.isabstract(cls):
55
+ _regmeta_register_class(cls, cls, name)
56
+ for b in bases:
57
+ if hasattr(b, "_regmeta_class_registry"):
58
+ _regmeta_register_class(b, cls, name)
59
+
60
+ super(RegisteryMeta, cls).__init__(name, bases, attr)
61
+
62
+ cls.regular_market_times = ProtectedDict(cls.regular_market_times)
63
+ cls.open_close_map = ProtectedDict(cls.open_close_map)
64
+
65
+ cls.special_market_open = cls.special_opens
66
+ cls.special_market_open_adhoc = cls.special_opens_adhoc
67
+
68
+ cls.special_market_close = cls.special_closes
69
+ cls.special_market_close_adhoc = cls.special_closes_adhoc
70
+
71
+
72
+ class ProtectedDict(dict):
73
+ def __init__(self, *args, **kwargs):
74
+ super().__init__(*args, **kwargs)
75
+ # __init__ is bypassed when unpickling, which causes __setitem__ to fail
76
+ # without the _INIT_RAN_NORMALLY flag
77
+ self._INIT_RAN_NORMALLY = True
78
+
79
+ def _set(self, key, value):
80
+ return super().__setitem__(key, value)
81
+
82
+ def _del(self, key):
83
+ return super().__delitem__(key)
84
+
85
+ def __setitem__(self, key, value):
86
+ if not hasattr(self, "_INIT_RAN_NORMALLY"):
87
+ return self._set(key, value)
88
+
89
+ raise TypeError(
90
+ "You cannot set a value directly, you can change regular_market_times "
91
+ "using .change_time, .add_time or .remove_time."
92
+ )
93
+
94
+ def __delitem__(self, key):
95
+ if not hasattr(self, "_INIT_RAN_NORMALLY"):
96
+ return self._del(key)
97
+
98
+ raise TypeError(
99
+ "You cannot delete an item directly. You can change regular_market_times "
100
+ "using .change_time, .add_time or .remove_time"
101
+ )
102
+
103
+ def __repr__(self):
104
+ return self.__class__.__name__ + "(" + super().__repr__() + ")"
105
+
106
+ def __str__(self):
107
+ try:
108
+ formatted = pformat(dict(self), sort_dicts=False) # sort_dicts apparently not available < python3.8
109
+ except TypeError:
110
+ formatted = pformat(dict(self))
111
+
112
+ return self.__class__.__name__ + "(\n" + formatted + "\n)"
113
+
114
+ def copy(self):
115
+ return self.__class__(super().copy())