pandas-market-calendars 5.0.0__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.
- pandas_market_calendars/calendar_utils.py +8 -4
- pandas_market_calendars/calendars/sifma.py +42 -15
- pandas_market_calendars/holidays/sifma.py +31 -31
- {pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/METADATA +1 -1
- {pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/RECORD +9 -9
- {pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/WHEEL +1 -1
- {pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/licenses/LICENSE +0 -0
- {pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/licenses/NOTICE +0 -0
- {pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/top_level.txt +0 -0
@@ -106,11 +106,15 @@ def mark_session(
|
|
106
106
|
f"Schedule ends at: {schedule.iloc[-1, -1]}"
|
107
107
|
)
|
108
108
|
|
109
|
+
lte_end = schedule.index <= end.normalize().tz_localize(None)
|
110
|
+
gte_start = schedule.index >= start.normalize().tz_localize(None)
|
111
|
+
|
112
|
+
# Shift both by 1 to keep an extra row on either end if available. Needed in some edge cases.
|
113
|
+
gte_start = np.append(gte_start, True)[1:] # Shifts gte_start by one to the left.
|
114
|
+
lte_end = np.insert(lte_end, 0, True)[:-1] # Shifts lte_end by one to the right.
|
115
|
+
|
109
116
|
# Trim the schedule to match the timeframe covered by the given timeseries
|
110
|
-
schedule = schedule[
|
111
|
-
(schedule.index >= start.normalize().tz_localize(None))
|
112
|
-
& (schedule.index <= end.normalize().tz_localize(None))
|
113
|
-
]
|
117
|
+
schedule = schedule[gte_start & lte_end]
|
114
118
|
|
115
119
|
backfilled_map = DEFAULT_LABEL_MAP | label_map
|
116
120
|
mapped_labels = [backfilled_map[label] for label in session_labels]
|
@@ -1,5 +1,7 @@
|
|
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
6
|
from zoneinfo import ZoneInfo
|
5
7
|
from itertools import chain
|
@@ -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
|
-
|
32
|
-
|
33
|
-
|
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,
|
@@ -118,6 +121,32 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
|
|
118
121
|
def tz(self):
|
119
122
|
return ZoneInfo("America/New_York")
|
120
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
|
149
|
+
|
121
150
|
@property
|
122
151
|
def regular_holidays(self):
|
123
152
|
return AbstractHolidayCalendar(
|
@@ -131,7 +160,6 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
|
|
131
160
|
USIndependenceDay,
|
132
161
|
USLaborDay,
|
133
162
|
USColumbusDay,
|
134
|
-
USVeteransDay2022,
|
135
163
|
USVeteransDay,
|
136
164
|
USThanksgivingDay,
|
137
165
|
Christmas,
|
@@ -140,11 +168,8 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
|
|
140
168
|
|
141
169
|
@property
|
142
170
|
def adhoc_holidays(self):
|
143
|
-
|
144
|
-
|
145
|
-
GoodFridayAdHoc,
|
146
|
-
)
|
147
|
-
)
|
171
|
+
gf_full_holidays, _, _ = self._get_dynamic_gf_rules()
|
172
|
+
return gf_full_holidays
|
148
173
|
|
149
174
|
@property
|
150
175
|
def special_closes(self):
|
@@ -168,11 +193,15 @@ class SIFMAUSExchangeCalendar(MarketCalendar):
|
|
168
193
|
|
169
194
|
@property
|
170
195
|
def special_closes_adhoc(self):
|
196
|
+
_, gf_12pm_early_closes, thurs_before_gf_2pm_early_closes = self._get_dynamic_gf_rules()
|
171
197
|
return [
|
172
198
|
(
|
173
|
-
time(
|
174
|
-
|
175
|
-
|
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,
|
176
205
|
),
|
177
206
|
]
|
178
207
|
|
@@ -227,7 +256,6 @@ class SIFMAUKExchangeCalendar(MarketCalendar):
|
|
227
256
|
UKSummerBank,
|
228
257
|
USLaborDay,
|
229
258
|
USColumbusDay,
|
230
|
-
USVeteransDay2022,
|
231
259
|
USVeteransDay,
|
232
260
|
USThanksgivingDay,
|
233
261
|
UKChristmas,
|
@@ -331,7 +359,6 @@ class SIFMAJPExchangeCalendar(MarketCalendar):
|
|
331
359
|
JapanSportsDay2020,
|
332
360
|
JapanHealthAndSportsDay2000To2019,
|
333
361
|
JapanCultureDay,
|
334
|
-
USVeteransDay2022,
|
335
362
|
USVeteransDay,
|
336
363
|
JapanLaborThanksgivingDay,
|
337
364
|
USThanksgivingDay,
|
@@ -89,27 +89,31 @@ USPresidentsDay = Holiday(
|
|
89
89
|
############################################################
|
90
90
|
# Good Friday
|
91
91
|
############################################################
|
92
|
+
|
93
|
+
|
94
|
+
def is_first_friday(dt):
|
95
|
+
"""Check if date is the first Friday of the month"""
|
96
|
+
# The first Friday of any month must occur on or before the 7th.
|
97
|
+
# This check is sufficient regardless of whether Good Friday is in March or April.
|
98
|
+
return dt.weekday() == FRIDAY and dt.day <= 7
|
99
|
+
|
100
|
+
|
92
101
|
GoodFridayThru2020 = Holiday(
|
93
|
-
"Good Friday
|
102
|
+
"Good Friday Thru 2020",
|
94
103
|
end_date=Timestamp("2020-12-31"),
|
95
104
|
month=1,
|
96
105
|
day=1,
|
97
106
|
offset=[Easter(), Day(-2)],
|
98
107
|
)
|
99
108
|
|
100
|
-
#
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
GoodFriday2pmEarlyCloseAdHoc = [
|
110
|
-
Timestamp("2021-04-02", tz="UTC"),
|
111
|
-
Timestamp("2023-04-07", tz="UTC"),
|
112
|
-
]
|
109
|
+
# Generate potential Good Friday dates post 2020 (will be filtered in calendar class)
|
110
|
+
GoodFridayPotentialPost2020 = Holiday(
|
111
|
+
"Good Friday Potential Post 2020",
|
112
|
+
start_date=Timestamp("2021-01-01"),
|
113
|
+
month=1,
|
114
|
+
day=1,
|
115
|
+
offset=[Easter(), Day(-2)],
|
116
|
+
)
|
113
117
|
|
114
118
|
DayBeforeGoodFriday2pmEarlyCloseThru2020 = Holiday(
|
115
119
|
"Day Before Good Friday Thru 2020",
|
@@ -119,10 +123,14 @@ DayBeforeGoodFriday2pmEarlyCloseThru2020 = Holiday(
|
|
119
123
|
offset=[Easter(), Day(-3)],
|
120
124
|
)
|
121
125
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
+
# Generate potential Thursday before Good Friday dates post 2020 (will be filtered in calendar class)
|
127
|
+
DayBeforeGoodFridayPotentialPost2020 = Holiday(
|
128
|
+
"Day Before Good Friday Potential Post 2020",
|
129
|
+
start_date=Timestamp("2021-01-01"),
|
130
|
+
month=1,
|
131
|
+
day=1,
|
132
|
+
offset=[Easter(), Day(-3)],
|
133
|
+
)
|
126
134
|
|
127
135
|
##################################################
|
128
136
|
# US Memorial Day (Decoration Day) May 30
|
@@ -204,20 +212,14 @@ USColumbusDay = Holiday(
|
|
204
212
|
# When falls on Saturday, no holiday is observed.
|
205
213
|
# When falls on Sunday, the Monday following is a holiday.
|
206
214
|
##########################################################
|
207
|
-
USVeteransDay2022 = Holiday(
|
208
|
-
"Veterans Day Prior to 2023",
|
209
|
-
month=11,
|
210
|
-
day=11,
|
211
|
-
end_date=Timestamp("2022-12-31"),
|
212
|
-
days_of_week=(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY),
|
213
|
-
observance=sunday_to_monday,
|
214
|
-
)
|
215
|
-
|
216
215
|
USVeteransDay = Holiday(
|
217
216
|
"Veterans Day",
|
218
217
|
month=11,
|
219
218
|
day=11,
|
220
|
-
|
219
|
+
# SIFMA guidance for observing only Mon-Fri or Sunday->Monday
|
220
|
+
# appears consistent for many years. This rule doesn't specify
|
221
|
+
# a start_date, letting it apply further back if needed by other logic,
|
222
|
+
# while effectively covering 2023+ due to the days_of_week filter.
|
221
223
|
days_of_week=(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY),
|
222
224
|
observance=sunday_to_monday,
|
223
225
|
)
|
@@ -225,9 +227,7 @@ USVeteransDay = Holiday(
|
|
225
227
|
################################################
|
226
228
|
# US Thanksgiving Nov 30
|
227
229
|
################################################
|
228
|
-
USThanksgivingDay = Holiday(
|
229
|
-
"Thanksgiving", month=11, day=1, offset=DateOffset(weekday=TH(4))
|
230
|
-
)
|
230
|
+
USThanksgivingDay = Holiday("Thanksgiving", month=11, day=1, offset=DateOffset(weekday=TH(4)))
|
231
231
|
|
232
232
|
DayAfterThanksgiving2pmEarlyClose = Holiday(
|
233
233
|
"Black Friday",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
pandas_market_calendars/__init__.py,sha256=9nFwO1i8mOeM9V75vRmbHCz4pcjSjfXHl8CBvrM-_2s,1357
|
2
2
|
pandas_market_calendars/calendar_registry.py,sha256=9ecKkERkztiwVaOXVsWfUcEvaT5_SwwpD5VaUAJhR1Y,2495
|
3
|
-
pandas_market_calendars/calendar_utils.py,sha256=
|
3
|
+
pandas_market_calendars/calendar_utils.py,sha256=bTW3q4l-PvqJaOmXsfh3LCqRn47TZXKlXNvQSFMgLwE,52151
|
4
4
|
pandas_market_calendars/class_registry.py,sha256=-L3nL7lTSc8B7ieMmA-2ifakJn6pzaLT1bUzSdrTlsg,3838
|
5
5
|
pandas_market_calendars/market_calendar.py,sha256=1VSeiz4ZWk54ARiyxJClHjQ_C0NkdsDQClm4SjSVorM,40409
|
6
6
|
pandas_market_calendars/calendars/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -26,7 +26,7 @@ pandas_market_calendars/calendars/lse.py,sha256=G9LMdGJcWPaZQRbaihVGtYbD92b9I6E0
|
|
26
26
|
pandas_market_calendars/calendars/mirror.py,sha256=UVMUV6RMuT9h3U46eNFYllSF8fGFwi6U1L9z_EroiD0,4422
|
27
27
|
pandas_market_calendars/calendars/nyse.py,sha256=IdldsuESaZ47Vzm7RyK2ZvpiVMuoQMAH_zR48weLk8U,66206
|
28
28
|
pandas_market_calendars/calendars/ose.py,sha256=BVgMWrmZRaaPXddyXlgtxHz8GcRMLKdhAshOHc3dnUU,3013
|
29
|
-
pandas_market_calendars/calendars/sifma.py,sha256=
|
29
|
+
pandas_market_calendars/calendars/sifma.py,sha256=o50Gr01x6cl_CtvY2FvvFTCLG9WJcUsVO8AQdOiZijs,11745
|
30
30
|
pandas_market_calendars/calendars/six.py,sha256=zVlaVvNxMx2oRhc054B_A3YrsyD1dtKnUtEGkkx34Xk,2690
|
31
31
|
pandas_market_calendars/calendars/sse.py,sha256=HL5o5WOQr7EZVXW35ujhqdCAgobHyQOEkfQzz7SR6t0,10992
|
32
32
|
pandas_market_calendars/calendars/tase.py,sha256=3zvGAl_fvwVis522zTs3-9QT2UKA1LlHocA-B-UYqmM,8756
|
@@ -39,12 +39,12 @@ pandas_market_calendars/holidays/jp.py,sha256=rqobVw837Uxb-4D1Zq_PyBLoeyhImYW7DB
|
|
39
39
|
pandas_market_calendars/holidays/jpx_equinox.py,sha256=KWbJqWsnkdyzG3fD2gJTXRLQOF3YTWSn9O6sYRL9Dnk,8070
|
40
40
|
pandas_market_calendars/holidays/nyse.py,sha256=jwcz3Xp7NNL0rnwrQG8vuuBuXg7YTSBcg733nmFw-uM,39831
|
41
41
|
pandas_market_calendars/holidays/oz.py,sha256=P77pWe7ZQj4o-731w6fW_Vzmo41PRxh94QpclI3ZyFM,1042
|
42
|
-
pandas_market_calendars/holidays/sifma.py,sha256=
|
42
|
+
pandas_market_calendars/holidays/sifma.py,sha256=PsGYHMHD5fH02o7UUuDB4yadUWawUXRUHH7UDO5GZvc,9183
|
43
43
|
pandas_market_calendars/holidays/uk.py,sha256=dt5TNONlDMXPw8wjyyPBYNnLO5Yz6Mht8VrPUrNqy-M,4719
|
44
44
|
pandas_market_calendars/holidays/us.py,sha256=OBBMMKTRzghD-b9CmPRe5zBh7zQYjWl4-9SogT6ZnBo,11515
|
45
|
-
pandas_market_calendars-5.
|
46
|
-
pandas_market_calendars-5.
|
47
|
-
pandas_market_calendars-5.
|
48
|
-
pandas_market_calendars-5.
|
49
|
-
pandas_market_calendars-5.
|
50
|
-
pandas_market_calendars-5.
|
45
|
+
pandas_market_calendars-5.1.0.dist-info/licenses/LICENSE,sha256=qW51_A-I7YutlB-s8VSKeOP-aL83T-Lb8LqqU1x1ilw,1065
|
46
|
+
pandas_market_calendars-5.1.0.dist-info/licenses/NOTICE,sha256=mmH7c9aF5FsELh1OHXloXw1TajLD_mWDKO4dsVf43_E,11693
|
47
|
+
pandas_market_calendars-5.1.0.dist-info/METADATA,sha256=b9voNNgwPUyYYTXbUDmFrQmUyCOG3pkBfEgtFB49x7k,9641
|
48
|
+
pandas_market_calendars-5.1.0.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
49
|
+
pandas_market_calendars-5.1.0.dist-info/top_level.txt,sha256=_4cUEFr07SuEAzZMT-5p0lJGXxO9imVbEK9_5oqcopQ,24
|
50
|
+
pandas_market_calendars-5.1.0.dist-info/RECORD,,
|
{pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/licenses/NOTICE
RENAMED
File without changes
|
{pandas_market_calendars-5.0.0.dist-info → pandas_market_calendars-5.1.0.dist-info}/top_level.txt
RENAMED
File without changes
|