Python 使用 Pandas 创建交易假期日历

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33094297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 12:46:43  来源:igfitidea点击:

Create trading holiday calendar with Pandas

pythonpandascalendar

提问by vlmercado

I'm trying to create a Trading calendar using Pandas. I'm able to create a cal instance based on the USFederalHolidayCalendar. The USFederalHolidayCalendar is not consistent with the Trading calendar in that the Trading calendar doesn't include Columbus Day and Veteran's Day. However, the Trading calendar includes Good Friday (not included in the USFederalHolidayCalendar). Everything except for the last line in following code works:

我正在尝试使用 Pandas 创建一个交易日历。我能够创建一个基于 USFederalHolidayCalendar 的 cal 实例。USFederalHolidayCalendar 与交易日历不一致,因为交易日历不包括哥伦布日和退伍军人节。但是,交易日历包括耶稣受难日(不包括在 USFederalHolidayCalendar 中)。除了以下代码中的最后一行之外,所有内容都有效:

from pandas.tseries.holiday import get_calendar, HolidayCalendarFactory, GoodFriday
from datetime import datetime

cal = get_calendar('USFederalHolidayCalendar')  # Create calendar instance
cal.rules.pop(7)                                # Remove Veteran's Day rule
cal.rules.pop(6)                                # Remove Columbus Day rule
tradingCal = HolidayCalendarFactory('TradingCalendar', cal, GoodFriday)

The tradingCal instance seems to work in that I'm able to view the Holiday rules.

TradingCal 实例似乎有效,因为我可以查看假期规则。

In[10]: tradingCal.rules
Out[10]: 
[Holiday: Labor Day (month=9, day=1, offset=<DateOffset: kwds={'weekday': MO(+1)}>),
 Holiday: Presidents Day (month=2, day=1, offset=<DateOffset: kwds={'weekday': MO(+3)}>),
 Holiday: Good Friday (month=1, day=1, offset=[<Easter>, <-2 * Days>]),
 Holiday: Dr. Martin Luther King Jr. (month=1, day=1, offset=<DateOffset: kwds={'weekday': MO(+3)}>),
 Holiday: New Years Day (month=1, day=1, observance=<function nearest_workday at 0x000000000A190BA8>),
 Holiday: Thanksgiving (month=11, day=1, offset=<DateOffset: kwds={'weekday': TH(+4)}>),
 Holiday: July 4th (month=7, day=4, observance=<function nearest_workday at 0x000000000A190BA8>),
 Holiday: Christmas (month=12, day=25, observance=<function nearest_workday at 0x000000000A190BA8>),
 Holiday: MemorialDay (month=5, day=31, offset=<DateOffset: kwds={'weekday': MO(-1)}>)]

When I try to list the holidays in a date range, I get the following error:

当我尝试在日期范围内列出假期时,出现以下错误:

In[11]: tradingCal.holidays(datetime(2014, 12, 31), datetime(2016, 12, 31))
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\IPython\core\interactiveshell.py", line 3035, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-12-2708cd2db7a0>", line 1, in <module>
    tradingCal.holidays(datetime(2014, 12, 31), datetime(2016, 12, 31))
TypeError: unbound method holidays() must be called with TradingCalendar instance as first argument (got datetime instance instead)

Any ideas?

有任何想法吗?

采纳答案by Pierre Boutquin

Perhaps it is more straightforward to create the trade calendar from scratch, like so:

也许从头开始创建交易日历更直接,如下所示:

import datetime as dt

from pandas.tseries.holiday import AbstractHolidayCalendar, Holiday, nearest_workday, \
    USMartinLutherKingJr, USPresidentsDay, GoodFriday, USMemorialDay, \
    USLaborDay, USThanksgivingDay


class USTradingCalendar(AbstractHolidayCalendar):
    rules = [
        Holiday('NewYearsDay', month=1, day=1, observance=nearest_workday),
        USMartinLutherKingJr,
        USPresidentsDay,
        GoodFriday,
        USMemorialDay,
        Holiday('USIndependenceDay', month=7, day=4, observance=nearest_workday),
        USLaborDay,
        USThanksgivingDay,
        Holiday('Christmas', month=12, day=25, observance=nearest_workday)
    ]


def get_trading_close_holidays(year):
    inst = USTradingCalendar()

    return inst.holidays(dt.datetime(year-1, 12, 31), dt.datetime(year, 12, 31))


if __name__ == '__main__':
    print(get_trading_close_holidays(2016))
    #    DatetimeIndex(['2016-01-01', '2016-01-18', '2016-02-15', '2016-03-25',
    #                   '2016-05-30', '2016-07-04', '2016-09-05', '2016-11-24',
    #                   '2016-12-26'],
    #                  dtype='datetime64[ns]', freq=None)

回答by jezrael

You have to create new instance of class: cal1 = tradingCal(). This works for me.

您必须创建类的新实例:cal1 = tradingCal(). 这对我有用。

from pandas.tseries.holiday import get_calendar, HolidayCalendarFactory, GoodFriday
from datetime import datetime

cal = get_calendar('USFederalHolidayCalendar')  # Create calendar instance
cal.rules.pop(7)                                # Remove Veteran's Day rule
cal.rules.pop(6)                                # Remove Columbus Day rule
tradingCal = HolidayCalendarFactory('TradingCalendar', cal, GoodFriday)
print tradingCal.rules

#new instance of class
cal1 = tradingCal()

print cal1.holidays(datetime(2014, 12, 31), datetime(2016, 12, 31))

#DatetimeIndex(['2015-01-01', '2015-01-19', '2015-02-16', '2015-04-03',
#               '2015-05-25', '2015-07-03', '2015-09-07', '2015-11-26',
#               '2015-12-25', '2016-01-01', '2016-01-18', '2016-02-15',
#              '2016-03-25', '2016-05-30', '2016-07-04', '2016-09-05',
#               '2016-11-24', '2016-12-26'],
#              dtype='datetime64[ns]', freq=None, tz=None)

回答by Ryan Sheftel

If it helps, I had a similar need for exchange trading calendars. There was some excellent code buried in the Zipline project by Quantopian. I extracted out the relevant part and created a new project for creating market exchange trading calendars in pandas. The links are here, with some of the functionality described below.

如果有帮助,我对交易所交易日历也有类似的需求。Quantopian 的 Zipline 项目中隐藏了一些优秀的代码。我提取了相关部分并创建了一个新项目,用于在熊猫中创建市场交易所交易日历。链接在这里,其中的一些功能如下所述。

https://github.com/rsheftel/pandas_market_calendars

https://github.com/rsheftel/pandas_market_calendars

https://pypi.python.org/pypi/pandas-market-calendars

https://pypi.python.org/pypi/pandas-market-calendars

Here is what it can do by creating a pandas DatetimeIndex of all of the valid open hours for the NYSE:

以下是它可以通过创建纽约证券交易所所有有效开放时间的 pandas DatetimeIndex 来执行的操作:

import pandas_market_calendars as mcal
nyse = mcal.get_calendar('NYSE')

early = nyse.schedule(start_date='2012-07-01', end_date='2012-07-10')
early

                  market_open             market_close
=========== ========================= =========================
2012-07-02 2012-07-02 13:30:00+00:00 2012-07-02 20:00:00+00:00
2012-07-03 2012-07-03 13:30:00+00:00 2012-07-03 17:00:00+00:00
2012-07-05 2012-07-05 13:30:00+00:00 2012-07-05 20:00:00+00:00
2012-07-06 2012-07-06 13:30:00+00:00 2012-07-06 20:00:00+00:00
2012-07-09 2012-07-09 13:30:00+00:00 2012-07-09 20:00:00+00:00
2012-07-10 2012-07-10 13:30:00+00:00 2012-07-10 20:00:00+00:00

mcal.date_range(early, frequency='1D')

DatetimeIndex(['2012-07-02 20:00:00+00:00', '2012-07-03 17:00:00+00:00',
               '2012-07-05 20:00:00+00:00', '2012-07-06 20:00:00+00:00',
               '2012-07-09 20:00:00+00:00', '2012-07-10 20:00:00+00:00'],
               dtype='datetime64[ns, UTC]', freq=None)

mcal.date_range(early, frequency='1H')

DatetimeIndex(['2012-07-02 14:30:00+00:00', '2012-07-02 15:30:00+00:00',
               '2012-07-02 16:30:00+00:00', '2012-07-02 17:30:00+00:00',
               '2012-07-02 18:30:00+00:00', '2012-07-02 19:30:00+00:00',
               '2012-07-02 20:00:00+00:00', '2012-07-03 14:30:00+00:00',
               '2012-07-03 15:30:00+00:00', '2012-07-03 16:30:00+00:00',
               '2012-07-03 17:00:00+00:00', '2012-07-05 14:30:00+00:00',
               '2012-07-05 15:30:00+00:00', '2012-07-05 16:30:00+00:00',
               '2012-07-05 17:30:00+00:00', '2012-07-05 18:30:00+00:00',
               '2012-07-05 19:30:00+00:00', '2012-07-05 20:00:00+00:00',
               '2012-07-06 14:30:00+00:00', '2012-07-06 15:30:00+00:00',
               '2012-07-06 16:30:00+00:00', '2012-07-06 17:30:00+00:00',
               '2012-07-06 18:30:00+00:00', '2012-07-06 19:30:00+00:00',
               '2012-07-06 20:00:00+00:00', '2012-07-09 14:30:00+00:00',
               '2012-07-09 15:30:00+00:00', '2012-07-09 16:30:00+00:00',
               '2012-07-09 17:30:00+00:00', '2012-07-09 18:30:00+00:00',
               '2012-07-09 19:30:00+00:00', '2012-07-09 20:00:00+00:00',
               '2012-07-10 14:30:00+00:00', '2012-07-10 15:30:00+00:00',
               '2012-07-10 16:30:00+00:00', '2012-07-10 17:30:00+00:00',
               '2012-07-10 18:30:00+00:00', '2012-07-10 19:30:00+00:00',
               '2012-07-10 20:00:00+00:00'],
              dtype='datetime64[ns, UTC]', freq=None)

If you just want to get the pandas Holiday Calendar that can be used in other pandas functions that take that as an argument:

如果您只想获取可以在其他以该参数为参数的 Pandas 函数中使用的 Pandas Holiday Calendar:

holidays = nyse.holidays()

holidays.holidays[-5:]
(numpy.datetime64('2030-05-27'),
 numpy.datetime64('2030-07-04'),
 numpy.datetime64('2030-09-02'),
 numpy.datetime64('2030-11-28'),
 numpy.datetime64('2030-12-25'))