rsheftel / pandas_market_calendars

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

weekmask issue with NYSE #207

Open tvr101 opened 2 years ago

tvr101 commented 2 years ago

Hi the NYSE weekmask includes saturday, but this causes issues when the holidays() method is called since the CustomBusinessDay object includes saturday as a valid business day without checking if after 1952, here is an example that roll sunday 6/26 back to saturday 6/25:

import pandas_market_calendars as mcal nyse = mcal.get_calendar("NYSE") holidays = nyse.holidays() holidays.rollback("2022-06-26")

Timestamp('2022-06-25 00:00:00')

Stryder-Git commented 2 years ago

Hi @tvr101, what I sometimes do is this:

from pandas.tseries.offsets import CustomBusinessDay
import pandas_market_calendars as mcal
nyse = mcal.get_calendar("NYSE")

hols = CustomBusinessDay(holidays= nyse.adhoc_holidays, 
                          calendar= nyse.regular_holidays,
                          weekmask= "1111100")

hols.rollback("2022-06-26")
>> Timestamp('2022-06-24 00:00:00')

This has also bugged me a few times, I will try to have a look how this could be made more user friendly without losing the functionality. If you have any suggestions I'd be happy to hear them.

pavelstovicek commented 2 years ago

I found a workaround: use XNYS (Mic code for NYSE) instead of NYSE:

import pandas_market_calendars as mcal

nyse = mcal.get_calendar('NYSE')
xnys = mcal.get_calendar('XNYS')
print('NYSE weekmask', nyse.weekmask)
print('XNYS weekmask', xnys.weekmask)

returns

NYSE weekmask Mon Tue Wed Thu Fri Sat
XNYS weekmask Mon Tue Wed Thu Fri

But anyway, the issue should be corrected at NYSE calendar

tvr101 commented 2 years ago

given that the weekmask has changed historically, and custombusinessday object doesnt support that level of functionaltiy (changing weekmasks), i think possibly the holidays() method should be deprecated. force users to use the pandas_market_calendar calendar object directly to figure out rollbacks.

pavelstovicek commented 2 years ago

I have not found how to get rollbacks with pandas_market_calendars. Can you give me help, please? I assumed the pandas_market_calendars should provide this functionality.

Basically, I need third trading day from given date.

What I am using currently:

from pandas.tseries.offsets import CustomBusinessDay
import pandas_market_calendars as mcal

mic = 'XNYS'
market_calendar = mcal.get_calendar(mic)
pandas_calendar = CustomBusinessDay(weekmask=market_calendar.weekmask,
                                    holidays=market_calendar.holidays().holidays)
date = pd.Timestamp('2022-09-12') + 3 * pandas_calendar
print(date)
maread99 commented 2 years ago

Hi @pavelstovicek, not sure how this might be done within pandas_market_calendars, although you could use the session_offset method of the exchange_calendars calendar...

> import exchange_calendars as xcals
> xnys = xcals.get_calendar("XNYS")
> xnys.session_offset('2022-09-12', 3)
Timestamp('2022-09-15 00:00:00', freq='C')

If you need to be able to work forwards from a date that might not be a session then first use the date_to_session method to anchor the offset on a session.

The data will be the same as the "XNYS" calendar you're using (pandas_market_calendars mirrors this calendar from exchange_calendars). Worth noting that historically "XNYS" is probably less accurate than pandas_market_calendars' native "NYSE" calendar (at least further back than say 20 years ago).