2015-10-13 12 views
13

Próbuję utworzyć kalendarz handlu przy użyciu Pand. Jestem w stanie stworzyć instancję kaliczną na podstawie USFederalHolidayCalendar. USFederalHolidayCalendar nie jest zgodny z kalendarzem Handlowym, ponieważ Kalendarz Handlowy nie obejmuje Dni Kolumba i Dnia Weteranów. Jednak kalendarz handlowy obejmuje Wielki Piątek (nieuwzględnione w USFederalHolidayCalendar). Wszystko z wyjątkiem ostatniej linii w następującym kodzie działa:Utwórz kalendarz świątecznych zakupów z Pandami

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) 

Wydaje się, że instancja tradingCal działa w ten sposób, że mogę wyświetlić reguły świąteczne.

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

Kiedy próbuję listy świąt w zakresie dat, pojawia się następujący błąd:

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) 

Jakieś pomysły?

Odpowiedz

22

Być może jest to łatwiejsze do tworzenia kalendarza handlową od podstaw, tak jak poniżej:

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

Musisz utworzyć nową instancję klasy: cal1 = tradingCal(). To działa dla mnie.

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) 
+0

Perfect, jezrael. Dziękuję Ci. – vlmercado

+4

Myślę, że ma to poważne wady! Użycie '.pop' wpływa na podstawową klasę' pandas.tseries.holiday.USFederalHolidayCalendar', ponieważ jest operacją "na miejscu" (nie jest pewna terminologii). Oznacza to, że jeśli spróbujesz odtworzyć cal2 z 'get_calendar ('USFederalHolidayCalendar')' reguły są takie same, jak 'cal'. tzn. nie dostaniesz * czystej * wersji 'USFederalHolidayCalendar', ponieważ już nie istnieje, zmodyfikowałeś go! – evan54

+0

@ evan54 Właśnie to zauważyłem. Czy masz rozwiązanie? – WillZ

8

Jeśli to pomoże, miałem podobną potrzebę kalendarzy obrotu giełdowego. W projekcie Zipline znalazł się znakomity kod Quantopian. Wyciągnąłem odpowiednią część i stworzyłem nowy projekt do tworzenia kalendarzy giełdowych w pandach. Linki znajdują się tutaj, z niektórymi funkcjami opisanymi poniżej.

https://github.com/rsheftel/pandas_market_calendars

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

Oto co można zrobić przez utworzenie DatetimeIndex pandy wszystkich ważnych otwartych godzin 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) 

Jeśli chcesz po prostu dostać Kalendarz świąt pandy, który może być używany w innych funkcjach pandy, które przyjmują to jako argument:

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

Ta biblioteka nie jest niezawodna. Kiedy go wypróbowałem, 2010-01-01 i inne dni noworoczne pojawiały się w kalendarzu, a także w Wielki Piątek i inne. –

+2

Prawdopodobnie nie używasz pakietu poprawnie. 2010-01-01 oraz wszystkie inne dni noworoczne i wielkie piątki nie są uwzględniane jako dzień sesyjny. Wypróbuj powyższy przykładowy kod. Jeśli chcesz dowiedzieć się, jak korzystać z pakietu, proponuję dokumenty online lub możesz wysłać mi wiadomość bezpośrednio, jeśli nadal masz problemy. –

+0

Masz rację. Sprawdziłem to w stosunku do kalendarza, który testowałem od 1995 roku i było dokładne. Nie pamiętam, jakiej składni używałem, co dawało mi niepożądane rezultaty. –

Powiązane problemy