rsheftel / pandas_market_calendars

Exchange calendars to use with pandas for trading applications
MIT License
803 stars 173 forks source link

Calendars don't include all early close times #155

Closed mattsta closed 3 years ago

mattsta commented 3 years ago

Reference: https://www.marketbeat.com/stock-market-holidays/

NASDAQ and NYSE Partial Holidays(1:00 p.m. Eastern Close) 2021 2022 2023 2024
Day before Independence Day July 2nd July 1st July 3rd July 3rd
The Day Following Thanksgiving November 26th November 25th November 24th November 29th
Christmas Eve December 23rd December 23rd December 22nd December 24th

Calendar coverage is spotty for early closures. Examples include 2020 not having independence day early close listed, 2021 not having independence day or christams early close, 2022 not having independence day or christams early close, 2023 only missing christmas early close...

multi-year check:

import pandas_market_calendars as mcal

n = mcal.get_calendar('NASDAQ')
s = n.schedule(start_date='2020-01-01', end_date='2030-12-31', start="pre", end="post")
n.early_closes(s)

Output:

2020-11-27 2020-11-27 09:00:00+00:00 2020-11-27 14:30:00+00:00 2020-11-27 18:00:00+00:00 2020-11-27 18:00:00+00:00
2020-12-24 2020-12-24 09:00:00+00:00 2020-12-24 14:30:00+00:00 2020-12-24 18:00:00+00:00 2020-12-24 18:00:00+00:00
2021-11-26 2021-11-26 09:00:00+00:00 2021-11-26 14:30:00+00:00 2021-11-26 18:00:00+00:00 2021-11-26 18:00:00+00:00
2022-11-25 2022-11-25 09:00:00+00:00 2022-11-25 14:30:00+00:00 2022-11-25 18:00:00+00:00 2022-11-25 18:00:00+00:00
2023-07-03 2023-07-03 08:00:00+00:00 2023-07-03 13:30:00+00:00 2023-07-03 17:00:00+00:00 2023-07-03 17:00:00+00:00
2023-11-24 2023-11-24 09:00:00+00:00 2023-11-24 14:30:00+00:00 2023-11-24 18:00:00+00:00 2023-11-24 18:00:00+00:00
2024-07-03 2024-07-03 08:00:00+00:00 2024-07-03 13:30:00+00:00 2024-07-03 17:00:00+00:00 2024-07-03 17:00:00+00:00
2024-11-29 2024-11-29 09:00:00+00:00 2024-11-29 14:30:00+00:00 2024-11-29 18:00:00+00:00 2024-11-29 18:00:00+00:00
2024-12-24 2024-12-24 09:00:00+00:00 2024-12-24 14:30:00+00:00 2024-12-24 18:00:00+00:00 2024-12-24 18:00:00+00:00
2025-07-03 2025-07-03 08:00:00+00:00 2025-07-03 13:30:00+00:00 2025-07-03 17:00:00+00:00 2025-07-03 17:00:00+00:00
2025-11-28 2025-11-28 09:00:00+00:00 2025-11-28 14:30:00+00:00 2025-11-28 18:00:00+00:00 2025-11-28 18:00:00+00:00
2025-12-24 2025-12-24 09:00:00+00:00 2025-12-24 14:30:00+00:00 2025-12-24 18:00:00+00:00 2025-12-24 18:00:00+00:00
2026-11-27 2026-11-27 09:00:00+00:00 2026-11-27 14:30:00+00:00 2026-11-27 18:00:00+00:00 2026-11-27 18:00:00+00:00
2026-12-24 2026-12-24 09:00:00+00:00 2026-12-24 14:30:00+00:00 2026-12-24 18:00:00+00:00 2026-12-24 18:00:00+00:00
2027-11-26 2027-11-26 09:00:00+00:00 2027-11-26 14:30:00+00:00 2027-11-26 18:00:00+00:00 2027-11-26 18:00:00+00:00
2028-07-03 2028-07-03 08:00:00+00:00 2028-07-03 13:30:00+00:00 2028-07-03 17:00:00+00:00 2028-07-03 17:00:00+00:00
2028-11-24 2028-11-24 09:00:00+00:00 2028-11-24 14:30:00+00:00 2028-11-24 18:00:00+00:00 2028-11-24 18:00:00+00:00
2029-07-03 2029-07-03 08:00:00+00:00 2029-07-03 13:30:00+00:00 2029-07-03 17:00:00+00:00 2029-07-03 17:00:00+00:00
2029-11-23 2029-11-23 09:00:00+00:00 2029-11-23 14:30:00+00:00 2029-11-23 18:00:00+00:00 2029-11-23 18:00:00+00:00
2029-12-24 2029-12-24 09:00:00+00:00 2029-12-24 14:30:00+00:00 2029-12-24 18:00:00+00:00 2029-12-24 18:00:00+00:00
2030-07-03 2030-07-03 08:00:00+00:00 2030-07-03 13:30:00+00:00 2030-07-03 17:00:00+00:00 2030-07-03 17:00:00+00:00
2030-11-29 2030-11-29 09:00:00+00:00 2030-11-29 14:30:00+00:00 2030-11-29 18:00:00+00:00 2030-11-29 18:00:00+00:00
2030-12-24 2030-12-24 09:00:00+00:00 2030-12-24 14:30:00+00:00 2030-12-24 18:00:00+00:00 2030-12-24 18:00:00+00:00
mattsta commented 3 years ago

also just noticed 2021-12-31 is listed as an active day, but it's the observed date for Saturday 2022-01-01 new years holiday 🤷‍♂️

s = n.schedule(start_date=datetime.datetime.now().date(), end_date='2021-12-31', start="pre", end="post")
                                 pre               market_open              market_close                      post
2021-11-01 2021-11-01 08:00:00+00:00 2021-11-01 13:30:00+00:00 2021-11-01 20:00:00+00:00 2021-11-02 00:00:00+00:00
2021-11-02 2021-11-02 08:00:00+00:00 2021-11-02 13:30:00+00:00 2021-11-02 20:00:00+00:00 2021-11-03 00:00:00+00:00
2021-11-03 2021-11-03 08:00:00+00:00 2021-11-03 13:30:00+00:00 2021-11-03 20:00:00+00:00 2021-11-04 00:00:00+00:00
2021-11-04 2021-11-04 08:00:00+00:00 2021-11-04 13:30:00+00:00 2021-11-04 20:00:00+00:00 2021-11-05 00:00:00+00:00
2021-11-05 2021-11-05 08:00:00+00:00 2021-11-05 13:30:00+00:00 2021-11-05 20:00:00+00:00 2021-11-06 00:00:00+00:00
2021-11-08 2021-11-08 09:00:00+00:00 2021-11-08 14:30:00+00:00 2021-11-08 21:00:00+00:00 2021-11-09 01:00:00+00:00
2021-11-09 2021-11-09 09:00:00+00:00 2021-11-09 14:30:00+00:00 2021-11-09 21:00:00+00:00 2021-11-10 01:00:00+00:00
2021-11-10 2021-11-10 09:00:00+00:00 2021-11-10 14:30:00+00:00 2021-11-10 21:00:00+00:00 2021-11-11 01:00:00+00:00
2021-11-11 2021-11-11 09:00:00+00:00 2021-11-11 14:30:00+00:00 2021-11-11 21:00:00+00:00 2021-11-12 01:00:00+00:00
2021-11-12 2021-11-12 09:00:00+00:00 2021-11-12 14:30:00+00:00 2021-11-12 21:00:00+00:00 2021-11-13 01:00:00+00:00
2021-11-15 2021-11-15 09:00:00+00:00 2021-11-15 14:30:00+00:00 2021-11-15 21:00:00+00:00 2021-11-16 01:00:00+00:00
2021-11-16 2021-11-16 09:00:00+00:00 2021-11-16 14:30:00+00:00 2021-11-16 21:00:00+00:00 2021-11-17 01:00:00+00:00
2021-11-17 2021-11-17 09:00:00+00:00 2021-11-17 14:30:00+00:00 2021-11-17 21:00:00+00:00 2021-11-18 01:00:00+00:00
2021-11-18 2021-11-18 09:00:00+00:00 2021-11-18 14:30:00+00:00 2021-11-18 21:00:00+00:00 2021-11-19 01:00:00+00:00
2021-11-19 2021-11-19 09:00:00+00:00 2021-11-19 14:30:00+00:00 2021-11-19 21:00:00+00:00 2021-11-20 01:00:00+00:00
2021-11-22 2021-11-22 09:00:00+00:00 2021-11-22 14:30:00+00:00 2021-11-22 21:00:00+00:00 2021-11-23 01:00:00+00:00
2021-11-23 2021-11-23 09:00:00+00:00 2021-11-23 14:30:00+00:00 2021-11-23 21:00:00+00:00 2021-11-24 01:00:00+00:00
2021-11-24 2021-11-24 09:00:00+00:00 2021-11-24 14:30:00+00:00 2021-11-24 21:00:00+00:00 2021-11-25 01:00:00+00:00
2021-11-26 2021-11-26 09:00:00+00:00 2021-11-26 14:30:00+00:00 2021-11-26 18:00:00+00:00 2021-11-26 18:00:00+00:00
2021-11-29 2021-11-29 09:00:00+00:00 2021-11-29 14:30:00+00:00 2021-11-29 21:00:00+00:00 2021-11-30 01:00:00+00:00
2021-11-30 2021-11-30 09:00:00+00:00 2021-11-30 14:30:00+00:00 2021-11-30 21:00:00+00:00 2021-12-01 01:00:00+00:00
2021-12-01 2021-12-01 09:00:00+00:00 2021-12-01 14:30:00+00:00 2021-12-01 21:00:00+00:00 2021-12-02 01:00:00+00:00
2021-12-02 2021-12-02 09:00:00+00:00 2021-12-02 14:30:00+00:00 2021-12-02 21:00:00+00:00 2021-12-03 01:00:00+00:00
2021-12-03 2021-12-03 09:00:00+00:00 2021-12-03 14:30:00+00:00 2021-12-03 21:00:00+00:00 2021-12-04 01:00:00+00:00
2021-12-06 2021-12-06 09:00:00+00:00 2021-12-06 14:30:00+00:00 2021-12-06 21:00:00+00:00 2021-12-07 01:00:00+00:00
2021-12-07 2021-12-07 09:00:00+00:00 2021-12-07 14:30:00+00:00 2021-12-07 21:00:00+00:00 2021-12-08 01:00:00+00:00
2021-12-08 2021-12-08 09:00:00+00:00 2021-12-08 14:30:00+00:00 2021-12-08 21:00:00+00:00 2021-12-09 01:00:00+00:00
2021-12-09 2021-12-09 09:00:00+00:00 2021-12-09 14:30:00+00:00 2021-12-09 21:00:00+00:00 2021-12-10 01:00:00+00:00
2021-12-10 2021-12-10 09:00:00+00:00 2021-12-10 14:30:00+00:00 2021-12-10 21:00:00+00:00 2021-12-11 01:00:00+00:00
2021-12-13 2021-12-13 09:00:00+00:00 2021-12-13 14:30:00+00:00 2021-12-13 21:00:00+00:00 2021-12-14 01:00:00+00:00
2021-12-14 2021-12-14 09:00:00+00:00 2021-12-14 14:30:00+00:00 2021-12-14 21:00:00+00:00 2021-12-15 01:00:00+00:00
2021-12-15 2021-12-15 09:00:00+00:00 2021-12-15 14:30:00+00:00 2021-12-15 21:00:00+00:00 2021-12-16 01:00:00+00:00
2021-12-16 2021-12-16 09:00:00+00:00 2021-12-16 14:30:00+00:00 2021-12-16 21:00:00+00:00 2021-12-17 01:00:00+00:00
2021-12-17 2021-12-17 09:00:00+00:00 2021-12-17 14:30:00+00:00 2021-12-17 21:00:00+00:00 2021-12-18 01:00:00+00:00
2021-12-20 2021-12-20 09:00:00+00:00 2021-12-20 14:30:00+00:00 2021-12-20 21:00:00+00:00 2021-12-21 01:00:00+00:00
2021-12-21 2021-12-21 09:00:00+00:00 2021-12-21 14:30:00+00:00 2021-12-21 21:00:00+00:00 2021-12-22 01:00:00+00:00
2021-12-22 2021-12-22 09:00:00+00:00 2021-12-22 14:30:00+00:00 2021-12-22 21:00:00+00:00 2021-12-23 01:00:00+00:00
2021-12-23 2021-12-23 09:00:00+00:00 2021-12-23 14:30:00+00:00 2021-12-23 21:00:00+00:00 2021-12-24 01:00:00+00:00
2021-12-27 2021-12-27 09:00:00+00:00 2021-12-27 14:30:00+00:00 2021-12-27 21:00:00+00:00 2021-12-28 01:00:00+00:00
2021-12-28 2021-12-28 09:00:00+00:00 2021-12-28 14:30:00+00:00 2021-12-28 21:00:00+00:00 2021-12-29 01:00:00+00:00
2021-12-29 2021-12-29 09:00:00+00:00 2021-12-29 14:30:00+00:00 2021-12-29 21:00:00+00:00 2021-12-30 01:00:00+00:00
2021-12-30 2021-12-30 09:00:00+00:00 2021-12-30 14:30:00+00:00 2021-12-30 21:00:00+00:00 2021-12-31 01:00:00+00:00
2021-12-31 2021-12-31 09:00:00+00:00 2021-12-31 14:30:00+00:00 2021-12-31 21:00:00+00:00 2022-01-01 01:00:00+00:00

ref:

NASDAQ and NYSE Holidays 2021 2022 2023 2024
New Year's Day January 1st December 31st January 2nd January 1st
glossner commented 3 years ago

@mattsta

2020 looks to be a difference in historical references. exchange_calendar_nyse.py contains references to all historical data. The calendar reference and your reference have different early close data. I don't personally remember if Friday July 3rd 2020 was an early close but I don't think other Friday July 4th dates were. The rules generating early closes are in holidays_nyse.py (line 285+).

For 2021 a reference is at https://www.nyse.com/markets/hours-calendars. The only early close I see there is Thursday Nov 25th.

For 2022 there is a pull request that includes Juneteenth. Nov 25th is again the only early close I see listed at the NYSE website.

I'm going to close the issue but please feel free to reopen it if you know your data is correct or I've misinterpreted what you were requesting.

mattsta commented 3 years ago

Thanks for the quick check. Sorry for the confusion. Looks like the marketbeat site is using a "logical rules" template for dates instead of the published real dates. Weird how they just confidently publish incorrect dates (plus it's of course the first google result for market holidays).

At best, maybe marketbeat could be assuming bond dates as shown at https://www.marketbeat.com/stock-market-holidays/ but even then it's still displaying fully closed dates not shown anywhere else.