pandas-market-calendars 4.6.1__py3-none-any.whl → 5.1.0__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 (35) hide show
  1. pandas_market_calendars/calendar_utils.py +35 -84
  2. pandas_market_calendars/calendars/asx.py +6 -2
  3. pandas_market_calendars/calendars/bmf.py +4 -8
  4. pandas_market_calendars/calendars/bse.py +6 -2
  5. pandas_market_calendars/calendars/cboe.py +6 -2
  6. pandas_market_calendars/calendars/cme.py +4 -4
  7. pandas_market_calendars/calendars/cme_globex_base.py +2 -2
  8. pandas_market_calendars/calendars/cme_globex_crypto.py +12 -14
  9. pandas_market_calendars/calendars/cme_globex_energy_and_metals.py +4 -4
  10. pandas_market_calendars/calendars/cme_globex_equities.py +2 -2
  11. pandas_market_calendars/calendars/eurex.py +2 -2
  12. pandas_market_calendars/calendars/eurex_fixed_income.py +2 -2
  13. pandas_market_calendars/calendars/hkex.py +7 -5
  14. pandas_market_calendars/calendars/ice.py +2 -2
  15. pandas_market_calendars/calendars/iex.py +7 -3
  16. pandas_market_calendars/calendars/jpx.py +6 -2
  17. pandas_market_calendars/calendars/lse.py +6 -2
  18. pandas_market_calendars/calendars/mirror.py +6 -11
  19. pandas_market_calendars/calendars/nyse.py +41 -42
  20. pandas_market_calendars/calendars/ose.py +7 -5
  21. pandas_market_calendars/calendars/sifma.py +51 -22
  22. pandas_market_calendars/calendars/six.py +6 -2
  23. pandas_market_calendars/calendars/sse.py +6 -2
  24. pandas_market_calendars/calendars/tase.py +6 -2
  25. pandas_market_calendars/calendars/tsx.py +6 -2
  26. pandas_market_calendars/class_registry.py +1 -3
  27. pandas_market_calendars/holidays/sifma.py +31 -31
  28. pandas_market_calendars/market_calendar.py +33 -82
  29. {pandas_market_calendars-4.6.1.dist-info → pandas_market_calendars-5.1.0.dist-info}/METADATA +7 -4
  30. pandas_market_calendars-5.1.0.dist-info/RECORD +50 -0
  31. {pandas_market_calendars-4.6.1.dist-info → pandas_market_calendars-5.1.0.dist-info}/WHEEL +1 -1
  32. pandas_market_calendars-4.6.1.dist-info/RECORD +0 -50
  33. {pandas_market_calendars-4.6.1.dist-info → pandas_market_calendars-5.1.0.dist-info/licenses}/LICENSE +0 -0
  34. {pandas_market_calendars-4.6.1.dist-info → pandas_market_calendars-5.1.0.dist-info/licenses}/NOTICE +0 -0
  35. {pandas_market_calendars-4.6.1.dist-info → pandas_market_calendars-5.1.0.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,7 @@ from pandas.tseries.holiday import (
9
9
  USPresidentsDay,
10
10
  USThanksgivingDay,
11
11
  )
12
- from pytz import timezone
12
+ from zoneinfo import ZoneInfo
13
13
 
14
14
  from pandas_market_calendars.holidays.us import (
15
15
  Christmas,
@@ -44,7 +44,7 @@ class ICEExchangeCalendar(MarketCalendar):
44
44
 
45
45
  @property
46
46
  def tz(self):
47
- return timezone("US/Eastern")
47
+ return ZoneInfo("US/Eastern")
48
48
 
49
49
  @property
50
50
  def special_closes(self):
@@ -3,7 +3,7 @@ from itertools import chain
3
3
 
4
4
  from pandas import Timestamp, DatetimeIndex, Timedelta
5
5
  from pandas.tseries.holiday import AbstractHolidayCalendar
6
- from pytz import timezone
6
+ from zoneinfo import ZoneInfo
7
7
 
8
8
  from typing import Literal, Union
9
9
  from pandas_market_calendars import calendar_utils as u
@@ -54,6 +54,10 @@ class IEXExchangeCalendar(NYSEExchangeCalendar):
54
54
  def name(self):
55
55
  return "IEX"
56
56
 
57
+ @property
58
+ def full_name(self):
59
+ return "Investor's Exchange"
60
+
57
61
  @property
58
62
  def weekmask(self):
59
63
  return "Mon Tue Wed Thu Fri"
@@ -85,7 +89,7 @@ class IEXExchangeCalendar(NYSEExchangeCalendar):
85
89
  def special_closes(self):
86
90
  return [
87
91
  (
88
- time(hour=13, tzinfo=timezone("America/New_York")),
92
+ time(hour=13, tzinfo=ZoneInfo("America/New_York")),
89
93
  AbstractHolidayCalendar(
90
94
  rules=[
91
95
  DayAfterThanksgiving1pmEarlyCloseInOrAfter1993,
@@ -100,7 +104,7 @@ class IEXExchangeCalendar(NYSEExchangeCalendar):
100
104
  def special_closes_adhoc(self):
101
105
  return [
102
106
  (
103
- time(13, tzinfo=timezone("America/New_York")),
107
+ time(13, tzinfo=ZoneInfo("America/New_York")),
104
108
  DaysBeforeIndependenceDay1pmEarlyCloseAdhoc,
105
109
  )
106
110
  ]
@@ -2,7 +2,7 @@ from datetime import time
2
2
  from itertools import chain
3
3
 
4
4
  from pandas.tseries.holiday import AbstractHolidayCalendar
5
- from pytz import timezone
5
+ from zoneinfo import ZoneInfo
6
6
 
7
7
  from pandas_market_calendars.holidays.jp import *
8
8
  from pandas_market_calendars.holidays.us import USNewYearsDay
@@ -41,9 +41,13 @@ class JPXExchangeCalendar(MarketCalendar):
41
41
  def name(self):
42
42
  return "JPX"
43
43
 
44
+ @property
45
+ def full_name(self):
46
+ return "Japan Exchange Group"
47
+
44
48
  @property
45
49
  def tz(self):
46
- return timezone("Asia/Tokyo")
50
+ return ZoneInfo("Asia/Tokyo")
47
51
 
48
52
  @property
49
53
  def adhoc_holidays(self):
@@ -16,7 +16,7 @@
16
16
  from datetime import time
17
17
 
18
18
  from pandas.tseries.holiday import AbstractHolidayCalendar, EasterMonday, GoodFriday
19
- from pytz import timezone
19
+ from zoneinfo import ZoneInfo
20
20
 
21
21
  from pandas_market_calendars.holidays.uk import (
22
22
  BoxingDay,
@@ -69,9 +69,13 @@ class LSEExchangeCalendar(MarketCalendar):
69
69
  def name(self):
70
70
  return "LSE"
71
71
 
72
+ @property
73
+ def full_name(self):
74
+ return "London Stock Exchange"
75
+
72
76
  @property
73
77
  def tz(self):
74
- return timezone("Europe/London")
78
+ return ZoneInfo("Europe/London")
75
79
 
76
80
  @property
77
81
  def regular_holidays(self):
@@ -46,10 +46,7 @@ class TradingCalendar(MarketCalendar):
46
46
  if self._ec.close_offset:
47
47
  cls.regular_market_times._set(
48
48
  "market_close",
49
- tuple(
50
- (t[0], t[1], self._ec.close_offset)
51
- for t in cls.regular_market_times["market_close"]
52
- ),
49
+ tuple((t[0], t[1], self._ec.close_offset) for t in cls.regular_market_times["market_close"]),
53
50
  )
54
51
  cls._FINALIZE_TRADING_CALENDAR = False
55
52
 
@@ -71,6 +68,10 @@ class TradingCalendar(MarketCalendar):
71
68
  def name(self):
72
69
  return self._ec.name
73
70
 
71
+ @property
72
+ def full_name(self):
73
+ return self._ec.name
74
+
74
75
  @property
75
76
  def tz(self):
76
77
  return self._ec.tz
@@ -104,13 +105,7 @@ class TradingCalendar(MarketCalendar):
104
105
  if hasattr(self._ec, "weekmask"):
105
106
  if "1" in self._ec.weekmask or "0" in self._ec.weekmask:
106
107
  # Convert 1s & 0s to Day Abbreviations
107
- return " ".join(
108
- [
109
- DAYMASKS[i]
110
- for i, val in enumerate(self._ec.weekmask)
111
- if val == "1"
112
- ]
113
- )
108
+ return " ".join([DAYMASKS[i] for i, val in enumerate(self._ec.weekmask) if val == "1"])
114
109
  else:
115
110
  return self._ec.weekmask
116
111
  else:
@@ -16,11 +16,12 @@
16
16
  from datetime import time
17
17
  from itertools import chain
18
18
  from typing import Literal, Union
19
+ from zoneinfo import ZoneInfo
19
20
 
20
21
  import pandas as pd
21
22
  from pandas.tseries.holiday import AbstractHolidayCalendar
22
23
  from pandas.tseries.offsets import CustomBusinessDay
23
- from pytz import timezone
24
+ from zoneinfo import ZoneInfo
24
25
 
25
26
  from pandas_market_calendars import calendar_utils as u
26
27
  from pandas_market_calendars.holidays.nyse import (
@@ -827,9 +828,13 @@ class NYSEExchangeCalendar(MarketCalendar):
827
828
  def name(self):
828
829
  return "NYSE"
829
830
 
831
+ @property
832
+ def full_name(self):
833
+ return "New York Stock Exchange"
834
+
830
835
  @property
831
836
  def tz(self):
832
- return timezone("America/New_York")
837
+ return ZoneInfo("America/New_York")
833
838
 
834
839
  @property
835
840
  def weekmask(self):
@@ -995,7 +1000,7 @@ class NYSEExchangeCalendar(MarketCalendar):
995
1000
  def special_closes(self):
996
1001
  return [
997
1002
  (
998
- time(11, tzinfo=timezone("America/New_York")),
1003
+ time(11, tzinfo=ZoneInfo("America/New_York")),
999
1004
  AbstractHolidayCalendar(
1000
1005
  rules=[
1001
1006
  KingEdwardDeath11amyClose1910,
@@ -1003,7 +1008,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1003
1008
  ),
1004
1009
  ),
1005
1010
  (
1006
- time(12, tzinfo=timezone("America/New_York")),
1011
+ time(12, tzinfo=ZoneInfo("America/New_York")),
1007
1012
  AbstractHolidayCalendar(
1008
1013
  rules=[
1009
1014
  ParadeOfNationalGuardEarlyClose1917,
@@ -1015,7 +1020,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1015
1020
  ),
1016
1021
  ),
1017
1022
  (
1018
- time(hour=12, minute=30, tzinfo=timezone("America/New_York")),
1023
+ time(hour=12, minute=30, tzinfo=ZoneInfo("America/New_York")),
1019
1024
  AbstractHolidayCalendar(
1020
1025
  rules=[
1021
1026
  RooseveltFuneral1230EarlyClose1919,
@@ -1026,7 +1031,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1026
1031
  ),
1027
1032
  ),
1028
1033
  (
1029
- time(13, tzinfo=timezone("America/New_York")),
1034
+ time(13, tzinfo=ZoneInfo("America/New_York")),
1030
1035
  AbstractHolidayCalendar(
1031
1036
  rules=[
1032
1037
  FridayAfterIndependenceDayNYSEpre2013,
@@ -1039,7 +1044,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1039
1044
  ),
1040
1045
  ),
1041
1046
  (
1042
- time(14, tzinfo=timezone("America/New_York")),
1047
+ time(14, tzinfo=ZoneInfo("America/New_York")),
1043
1048
  AbstractHolidayCalendar(
1044
1049
  rules=[
1045
1050
  DayAfterThanksgiving2pmEarlyCloseBefore1993,
@@ -1051,7 +1056,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1051
1056
  ),
1052
1057
  ),
1053
1058
  (
1054
- time(14, 7, tzinfo=timezone("America/New_York")),
1059
+ time(14, 7, tzinfo=ZoneInfo("America/New_York")),
1055
1060
  AbstractHolidayCalendar(
1056
1061
  rules=[
1057
1062
  KennedyAssassination1407EarlyClose,
@@ -1059,7 +1064,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1059
1064
  ),
1060
1065
  ),
1061
1066
  (
1062
- time(hour=14, minute=30, tzinfo=timezone("America/New_York")),
1067
+ time(hour=14, minute=30, tzinfo=ZoneInfo("America/New_York")),
1063
1068
  AbstractHolidayCalendar(
1064
1069
  rules=[
1065
1070
  FalseArmisticeReport1430EarlyClose1918,
@@ -1070,7 +1075,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1070
1075
  ),
1071
1076
  ),
1072
1077
  (
1073
- time(15, tzinfo=timezone("America/New_York")),
1078
+ time(15, tzinfo=ZoneInfo("America/New_York")),
1074
1079
  AbstractHolidayCalendar(
1075
1080
  rules=[
1076
1081
  HurricaneWatch3pmEarlyClose1976,
@@ -1078,7 +1083,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1078
1083
  ),
1079
1084
  ),
1080
1085
  (
1081
- time(15, 17, tzinfo=timezone("America/New_York")),
1086
+ time(15, 17, tzinfo=ZoneInfo("America/New_York")),
1082
1087
  AbstractHolidayCalendar(
1083
1088
  rules=[
1084
1089
  ReaganAssassAttempt317pmEarlyClose1981,
@@ -1086,7 +1091,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1086
1091
  ),
1087
1092
  ),
1088
1093
  (
1089
- time(15, 28, tzinfo=timezone("America/New_York")),
1094
+ time(15, 28, tzinfo=ZoneInfo("America/New_York")),
1090
1095
  AbstractHolidayCalendar(
1091
1096
  rules=[
1092
1097
  ConEdPowerFail328pmEarlyClose1981,
@@ -1094,7 +1099,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1094
1099
  ),
1095
1100
  ),
1096
1101
  (
1097
- time(15, 30, tzinfo=timezone("America/New_York")),
1102
+ time(15, 30, tzinfo=ZoneInfo("America/New_York")),
1098
1103
  AbstractHolidayCalendar(
1099
1104
  rules=[
1100
1105
  CircuitBreakerTriggered330pmEarlyClose1997,
@@ -1102,7 +1107,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1102
1107
  ),
1103
1108
  ),
1104
1109
  (
1105
- time(15, 56, tzinfo=timezone("America/New_York")),
1110
+ time(15, 56, tzinfo=ZoneInfo("America/New_York")),
1106
1111
  AbstractHolidayCalendar(
1107
1112
  rules=[
1108
1113
  SystemProb356pmEarlyClose2005,
@@ -1122,14 +1127,14 @@ class NYSEExchangeCalendar(MarketCalendar):
1122
1127
 
1123
1128
  return [
1124
1129
  (
1125
- time(13, tzinfo=timezone("America/New_York")),
1130
+ time(13, tzinfo=ZoneInfo("America/New_York")),
1126
1131
  # DaysBeforeIndependenceDay1pmEarlyCloseAdhoc # list
1127
1132
  ChristmasEve1pmEarlyCloseAdhoc
1128
1133
  + DayAfterChristmas1pmEarlyCloseAdhoc
1129
1134
  + BacklogRelief1pmEarlyClose1929,
1130
1135
  ),
1131
1136
  (
1132
- time(14, tzinfo=timezone("America/New_York")),
1137
+ time(14, tzinfo=ZoneInfo("America/New_York")),
1133
1138
  _union_many(
1134
1139
  [
1135
1140
  pd.DatetimeIndex(
@@ -1148,19 +1153,19 @@ class NYSEExchangeCalendar(MarketCalendar):
1148
1153
  ), # index
1149
1154
  ),
1150
1155
  (
1151
- time(14, 30, tzinfo=timezone("America/New_York")),
1156
+ time(14, 30, tzinfo=ZoneInfo("America/New_York")),
1152
1157
  _union_many(
1153
1158
  [PaperworkCrisis230pmEarlyCloses1969, Backlog230pmEarlyCloses1987]
1154
1159
  ), # index
1155
1160
  ),
1156
1161
  (
1157
- time(15, tzinfo=timezone("America/New_York")),
1162
+ time(15, tzinfo=ZoneInfo("America/New_York")),
1158
1163
  _union_many(
1159
1164
  [PaperworkCrisis3pmEarlyCloses1969to1970, Backlog3pmEarlyCloses1987]
1160
1165
  ), # index
1161
1166
  ),
1162
1167
  (
1163
- time(15, 30, tzinfo=timezone("America/New_York")),
1168
+ time(15, 30, tzinfo=ZoneInfo("America/New_York")),
1164
1169
  Backlog330pmEarlyCloses1987, # index
1165
1170
  ),
1166
1171
  ]
@@ -1169,7 +1174,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1169
1174
  def special_opens(self):
1170
1175
  return [
1171
1176
  (
1172
- time(hour=9, minute=31, tzinfo=timezone("America/New_York")),
1177
+ time(hour=9, minute=31, tzinfo=ZoneInfo("America/New_York")),
1173
1178
  AbstractHolidayCalendar(
1174
1179
  rules=[
1175
1180
  ConEdXformer931amLateOpen1990,
@@ -1178,7 +1183,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1178
1183
  ),
1179
1184
  ),
1180
1185
  (
1181
- time(hour=9, minute=32, tzinfo=timezone("America/New_York")),
1186
+ time(hour=9, minute=32, tzinfo=ZoneInfo("America/New_York")),
1182
1187
  AbstractHolidayCalendar(
1183
1188
  rules=[
1184
1189
  IraqiFreedom932amLateOpen2003,
@@ -1188,7 +1193,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1188
1193
  ),
1189
1194
  ),
1190
1195
  (
1191
- time(hour=9, minute=33, tzinfo=timezone("America/New_York")),
1196
+ time(hour=9, minute=33, tzinfo=ZoneInfo("America/New_York")),
1192
1197
  AbstractHolidayCalendar(
1193
1198
  rules=[
1194
1199
  Sept11MomentSilence933amLateOpen2001,
@@ -1196,7 +1201,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1196
1201
  ),
1197
1202
  ),
1198
1203
  (
1199
- time(hour=10, minute=15, tzinfo=timezone("America/New_York")),
1204
+ time(hour=10, minute=15, tzinfo=ZoneInfo("America/New_York")),
1200
1205
  AbstractHolidayCalendar(
1201
1206
  rules=[
1202
1207
  Snow1015LateOpen1967,
@@ -1207,7 +1212,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1207
1212
  ),
1208
1213
  ),
1209
1214
  (
1210
- time(hour=10, minute=30, tzinfo=timezone("America/New_York")),
1215
+ time(hour=10, minute=30, tzinfo=ZoneInfo("America/New_York")),
1211
1216
  AbstractHolidayCalendar(
1212
1217
  rules=[
1213
1218
  TrafficBlockLateOpen1919,
@@ -1217,7 +1222,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1217
1222
  ),
1218
1223
  ),
1219
1224
  (
1220
- time(hour=10, minute=45, tzinfo=timezone("America/New_York")),
1225
+ time(hour=10, minute=45, tzinfo=ZoneInfo("America/New_York")),
1221
1226
  AbstractHolidayCalendar(
1222
1227
  rules=[
1223
1228
  EclipseOfSunLateOpen1925,
@@ -1226,7 +1231,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1226
1231
  ),
1227
1232
  ),
1228
1233
  (
1229
- time(11, tzinfo=timezone("America/New_York")),
1234
+ time(11, tzinfo=ZoneInfo("America/New_York")),
1230
1235
  AbstractHolidayCalendar(
1231
1236
  rules=[
1232
1237
  Snow11amLateOpen1934,
@@ -1241,7 +1246,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1241
1246
  ),
1242
1247
  ),
1243
1248
  (
1244
- time(11, 5, tzinfo=timezone("America/New_York")),
1249
+ time(11, 5, tzinfo=ZoneInfo("America/New_York")),
1245
1250
  AbstractHolidayCalendar(
1246
1251
  rules=[
1247
1252
  PowerFail1105LateOpen,
@@ -1249,7 +1254,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1249
1254
  ),
1250
1255
  ),
1251
1256
  (
1252
- time(11, 15, tzinfo=timezone("America/New_York")),
1257
+ time(11, 15, tzinfo=ZoneInfo("America/New_York")),
1253
1258
  AbstractHolidayCalendar(
1254
1259
  rules=[
1255
1260
  Storm1115LateOpen1976,
@@ -1257,7 +1262,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1257
1262
  ),
1258
1263
  ),
1259
1264
  (
1260
- time(12, tzinfo=timezone("America/New_York")),
1265
+ time(12, tzinfo=ZoneInfo("America/New_York")),
1261
1266
  AbstractHolidayCalendar(
1262
1267
  rules=[
1263
1268
  KingEdwardFuneral12pmOpen1910,
@@ -1269,7 +1274,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1269
1274
  ),
1270
1275
  ),
1271
1276
  (
1272
- time(13, tzinfo=timezone("America/New_York")),
1277
+ time(13, tzinfo=ZoneInfo("America/New_York")),
1273
1278
  AbstractHolidayCalendar(
1274
1279
  rules=[
1275
1280
  AnnunciatorBoardFire1pmLateOpen1921,
@@ -1282,15 +1287,15 @@ class NYSEExchangeCalendar(MarketCalendar):
1282
1287
  def special_opens_adhoc(self):
1283
1288
  return [
1284
1289
  (
1285
- time(9, 31, tzinfo=timezone("America/New_York")),
1290
+ time(9, 31, tzinfo=ZoneInfo("America/New_York")),
1286
1291
  TroopsInGulf931LateOpens1991,
1287
1292
  ),
1288
1293
  (
1289
- time(11, tzinfo=timezone("America/New_York")),
1294
+ time(11, tzinfo=ZoneInfo("America/New_York")),
1290
1295
  HeavyVolume11amLateOpen1933,
1291
1296
  ),
1292
1297
  (
1293
- time(12, tzinfo=timezone("America/New_York")),
1298
+ time(12, tzinfo=ZoneInfo("America/New_York")),
1294
1299
  BacklogRelief12pmLateOpen1929 + HeavyVolume12pmLateOpen1933,
1295
1300
  ),
1296
1301
  ]
@@ -1338,9 +1343,7 @@ class NYSEExchangeCalendar(MarketCalendar):
1338
1343
  normalize=True,
1339
1344
  tz=tz,
1340
1345
  )
1341
- days_post = pd.date_range(
1342
- saturday_end, end_date, freq=self.holidays(), normalize=True, tz=tz
1343
- )
1346
+ days_post = pd.date_range(saturday_end, end_date, freq=self.holidays(), normalize=True, tz=tz)
1344
1347
  return days_pre.union(days_post)
1345
1348
 
1346
1349
  def days_at_time(self, days, market_time, day_offset=0):
@@ -1443,14 +1446,10 @@ class NYSEExchangeCalendar(MarketCalendar):
1443
1446
  **(args | altered_args),
1444
1447
  )
1445
1448
 
1446
- return pd.DatetimeIndex(
1447
- pre[:-1].union(post)[-periods:], dtype="datetime64[ns]"
1448
- )
1449
+ return pd.DatetimeIndex(pre[:-1].union(post)[-periods:], dtype="datetime64[ns]")
1449
1450
  else:
1450
1451
  _, _ = u._standardize_htf_freq(frequency)
1451
- raise ValueError(
1452
- "This should never be raised, the above call should error first"
1453
- )
1452
+ raise ValueError("This should never be raised, the above call should error first")
1454
1453
 
1455
1454
  def early_closes(self, schedule):
1456
1455
  """
@@ -7,7 +7,7 @@ from pandas.tseries.holiday import (
7
7
  Holiday,
8
8
  )
9
9
  from pandas.tseries.offsets import Day, Easter
10
- from pytz import timezone
10
+ from zoneinfo import ZoneInfo
11
11
 
12
12
  from pandas_market_calendars.market_calendar import MarketCalendar
13
13
 
@@ -17,9 +17,7 @@ OSEWednesdayBeforeEaster = Holiday(
17
17
  "Wednesday before Easter", month=1, day=1, offset=[Easter(), Day(-4)]
18
18
  )
19
19
 
20
- OSEMaundyThursday = Holiday(
21
- "Maundy Thursday", month=1, day=1, offset=[Easter(), Day(-3)]
22
- )
20
+ OSEMaundyThursday = Holiday("Maundy Thursday", month=1, day=1, offset=[Easter(), Day(-3)])
23
21
 
24
22
  OSEGoodFriday = GoodFriday
25
23
 
@@ -83,9 +81,13 @@ class OSEExchangeCalendar(MarketCalendar):
83
81
  def name(self):
84
82
  return "OSE"
85
83
 
84
+ @property
85
+ def full_name(self):
86
+ return "Oslo Stock Exchange"
87
+
86
88
  @property
87
89
  def tz(self):
88
- return timezone("Europe/Oslo")
90
+ return ZoneInfo("Europe/Oslo")
89
91
 
90
92
  @property
91
93
  def regular_holidays(self):
@@ -1,7 +1,9 @@
1
1
  from datetime import time
2
+ import functools
2
3
 
4
+ import pandas as pd
3
5
  from pandas.tseries.holiday import AbstractHolidayCalendar
4
- from pytz import timezone
6
+ from zoneinfo import ZoneInfo
5
7
  from itertools import chain
6
8
 
7
9
  ########################################################################################################################
@@ -26,11 +28,13 @@ from pandas_market_calendars.holidays.sifma import (
26
28
  USNewYearsEve2pmEarlyClose,
27
29
  MartinLutherKingJr,
28
30
  USPresidentsDay,
31
+ # --- Good Friday Rules --- #
32
+ is_first_friday,
29
33
  GoodFridayThru2020,
30
34
  DayBeforeGoodFriday2pmEarlyCloseThru2020,
31
- GoodFridayAdHoc,
32
- GoodFriday2pmEarlyCloseAdHoc,
33
- DayBeforeGoodFriday2pmEarlyCloseAdHoc,
35
+ GoodFridayPotentialPost2020, # Potential dates, filtered later
36
+ DayBeforeGoodFridayPotentialPost2020, # Potential dates, filtered later
37
+ # --- End Good Friday Rules --- #
34
38
  DayBeforeUSMemorialDay2pmEarlyClose,
35
39
  USMemorialDay,
36
40
  USJuneteenthAfter2022,
@@ -39,7 +43,6 @@ from pandas_market_calendars.holidays.sifma import (
39
43
  ThursdayBeforeUSIndependenceDay2pmEarlyClose,
40
44
  USLaborDay,
41
45
  USColumbusDay,
42
- USVeteransDay2022,
43
46
  USVeteransDay,
44
47
  USThanksgivingDay,
45
48
  DayAfterThanksgiving2pmEarlyClose,
@@ -110,9 +113,39 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
110
113
  def name(self):
111
114
  return "SIFMA_US"
112
115
 
116
+ @property
117
+ def full_name(self):
118
+ return "Securities Industry and Financial Markets Association"
119
+
113
120
  @property
114
121
  def tz(self):
115
- return timezone("America/New_York")
122
+ return ZoneInfo("America/New_York")
123
+
124
+ # Helper method to calculate and cache dynamic dates
125
+ @functools.lru_cache()
126
+ def _get_dynamic_gf_rules(self):
127
+ # Calculate rules for a wide fixed range to avoid arbitrary cutoffs
128
+ # while preventing infinite generation. 1970-2100 is a reasonable range.
129
+ calc_start = pd.Timestamp("1970-01-01")
130
+ calc_end = pd.Timestamp("2100-12-31")
131
+
132
+ # Filter potential dates based on the start_date of the underlying Holiday rules
133
+ gf_rule_start = GoodFridayPotentialPost2020.start_date
134
+ thurs_rule_start = DayBeforeGoodFridayPotentialPost2020.start_date
135
+
136
+ # Ensure calculation range respects the rule start dates
137
+ effective_gf_start = max(calc_start, gf_rule_start) if gf_rule_start else calc_start
138
+ effective_thurs_start = max(calc_start, thurs_rule_start) if thurs_rule_start else calc_start
139
+
140
+ potential_gf_dates = GoodFridayPotentialPost2020.dates(effective_gf_start, calc_end)
141
+ gf_full_holidays = [d for d in potential_gf_dates if not is_first_friday(d)]
142
+ gf_12pm_early_closes = [d for d in potential_gf_dates if is_first_friday(d)]
143
+
144
+ potential_thurs_dates = DayBeforeGoodFridayPotentialPost2020.dates(effective_thurs_start, calc_end)
145
+ thurs_before_gf_2pm_early_closes = [
146
+ thurs for thurs in potential_thurs_dates if not is_first_friday(thurs + pd.Timedelta(days=1))
147
+ ]
148
+ return gf_full_holidays, gf_12pm_early_closes, thurs_before_gf_2pm_early_closes
116
149
 
117
150
  @property
118
151
  def regular_holidays(self):
@@ -127,7 +160,6 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
127
160
  USIndependenceDay,
128
161
  USLaborDay,
129
162
  USColumbusDay,
130
- USVeteransDay2022,
131
163
  USVeteransDay,
132
164
  USThanksgivingDay,
133
165
  Christmas,
@@ -136,11 +168,8 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
136
168
 
137
169
  @property
138
170
  def adhoc_holidays(self):
139
- return list(
140
- chain(
141
- GoodFridayAdHoc,
142
- )
143
- )
171
+ gf_full_holidays, _, _ = self._get_dynamic_gf_rules()
172
+ return gf_full_holidays
144
173
 
145
174
  @property
146
175
  def special_closes(self):
@@ -164,11 +193,15 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
164
193
 
165
194
  @property
166
195
  def special_closes_adhoc(self):
196
+ _, gf_12pm_early_closes, thurs_before_gf_2pm_early_closes = self._get_dynamic_gf_rules()
167
197
  return [
168
198
  (
169
- time(14, tzinfo=timezone("America/New_York")),
170
- GoodFriday2pmEarlyCloseAdHoc # list
171
- + DayBeforeGoodFriday2pmEarlyCloseAdHoc,
199
+ time(12), # SIFMA rule specifies 12:00 PM ET
200
+ gf_12pm_early_closes,
201
+ ),
202
+ (
203
+ time(14), # SIFMA rule specifies 2:00 PM ET
204
+ thurs_before_gf_2pm_early_closes,
172
205
  ),
173
206
  ]
174
207
 
@@ -205,7 +238,7 @@ class SIFMAUKExchangeCalendar(MarketCalendar):
205
238
 
206
239
  @property
207
240
  def tz(self):
208
- return timezone("Europe/London")
241
+ return ZoneInfo("Europe/London")
209
242
 
210
243
  @property
211
244
  def regular_holidays(self):
@@ -223,7 +256,6 @@ class SIFMAUKExchangeCalendar(MarketCalendar):
223
256
  UKSummerBank,
224
257
  USLaborDay,
225
258
  USColumbusDay,
226
- USVeteransDay2022,
227
259
  USVeteransDay,
228
260
  USThanksgivingDay,
229
261
  UKChristmas,
@@ -295,7 +327,7 @@ class SIFMAJPExchangeCalendar(MarketCalendar):
295
327
 
296
328
  @property
297
329
  def tz(self):
298
- return timezone("Asia/Tokyo")
330
+ return ZoneInfo("Asia/Tokyo")
299
331
 
300
332
  @property
301
333
  def regular_holidays(self):
@@ -327,7 +359,6 @@ class SIFMAJPExchangeCalendar(MarketCalendar):
327
359
  JapanSportsDay2020,
328
360
  JapanHealthAndSportsDay2000To2019,
329
361
  JapanCultureDay,
330
- USVeteransDay2022,
331
362
  USVeteransDay,
332
363
  JapanLaborThanksgivingDay,
333
364
  USThanksgivingDay,
@@ -349,6 +380,4 @@ class SIFMAJPExchangeCalendar(MarketCalendar):
349
380
 
350
381
  @property
351
382
  def special_closes(self):
352
- return [
353
- (time(15), AbstractHolidayCalendar(rules=[UKMayDay, UKWeekendChristmas]))
354
- ]
383
+ return [(time(15), AbstractHolidayCalendar(rules=[UKMayDay, UKWeekendChristmas]))]
@@ -9,7 +9,7 @@ from pandas.tseries.holiday import (
9
9
  Holiday,
10
10
  previous_friday,
11
11
  )
12
- from pytz import timezone
12
+ from zoneinfo import ZoneInfo
13
13
 
14
14
  from pandas_market_calendars.market_calendar import (
15
15
  FRIDAY,
@@ -108,9 +108,13 @@ class SIXExchangeCalendar(MarketCalendar):
108
108
  def name(self):
109
109
  return "SIX"
110
110
 
111
+ @property
112
+ def full_name(self):
113
+ return "SIX Swiss Exchange"
114
+
111
115
  @property
112
116
  def tz(self):
113
- return timezone("Europe/Zurich")
117
+ return ZoneInfo("Europe/Zurich")
114
118
 
115
119
  @property
116
120
  def regular_holidays(self):