Подтвердить что ты не робот

Создайте праздничный календарь праздников с Pandas

Я пытаюсь создать торговый календарь, используя Pandas. Я могу создать экземпляр cal, основанный на USFederalHolidayCalendar. 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 Day rule
cal.rules.pop(6)                                # Remove Columbus Day rule
tradingCal = HolidayCalendarFactory('TradingCalendar', cal, GoodFriday)

Экземпляр tradingCal, похоже, работает в том, что я могу просматривать правила Holiday.

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)}>)]

Когда я пытаюсь перечислить праздники в диапазоне дат, я получаю следующую ошибку:

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)

Любые идеи?

4b9b3361

Ответ 1

Возможно, проще создать торговый календарь с нуля, например:

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)

Ответ 2

Если это помогает, у меня была аналогичная потребность в биржевых торговых календарях. Был некоторый превосходный код, похороненный в проекте Zipline Quantopian. Я извлек соответствующую часть и создал новый проект для создания торговых календарей биржевой торговли в pandas. Ссылки здесь, с некоторыми функциями, описанными ниже.

https://github.com/rsheftel/pandas_market_calendars

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

Вот что он может сделать, создав pandas DatetimeIndex всех действительных часов работы NYSE:

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)

Если вы просто хотите получить календарь pandas Holiday Calendar, который можно использовать в других функциях pandas, которые принимают это как аргумент:

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'))

Ответ 3

Вам нужно создать новый экземпляр класса: 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 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)