Datetime Python - Next Business Day
doing more than one business day
def next_business_day(start_day, business_days, HOLIDAYS):
ONE_DAY = datetime.timedelta(days=1)
temp_day = start_day
for i in range(0, business_days):
next_day = temp_day + ONE_DAY
while next_day.weekday() in [5,6] or next_day in HOLIDAYS:
next_day += ONE_DAY
temp_day = next_day
return temp_day
This question is common and there are different levels of solutions:
Simplest: use something like your approach of checking the weekday. One common idom is something like
d = datetime.date(2012,2,7)
next = d + datetime.timedelta(days= 7-d.weekday() if d.weekday()>3 else 1)
Once you want holidays, you can roll your own datetime "TradingDateChecker" that has to scan for the "predictable" holidays like Jan 1, July 4, Dec 25 the Friday before or Monday after those if they fall on a weekend, last Monday in May, first Monday in Sept etc.
I won't even bother posting that code here because for trading holidays, it still is insufficient.
- Good Friday the NYSE is closed and futures and bond markets are open
- Columbus day and Veterans Day, the banks are closed and the stock market is open.
The stock and futures markets have different holidays. If you want NYSE holidays (a common request) see below. You can't really get around keeping your own calendar since the closing dates are usually only announced for a couple of years in the future.
# For a longer list of NYSE closed dates see: http://www.chronos-st.org/NYSE_Observed_Holidays-1885-Present.html
holidays = [datetime.date(2000, 1, 17),
datetime.date(2000, 2, 21),
datetime.date(2000, 4, 21),
datetime.date(2000, 5, 29),
datetime.date(2000, 7, 4),
datetime.date(2000, 9, 4),
datetime.date(2000, 11, 23),
datetime.date(2000, 12, 25),
datetime.date(2001, 1, 1),
datetime.date(2001, 1, 15),
datetime.date(2001, 2, 19),
datetime.date(2001, 5, 28),
datetime.date(2001, 7, 4),
datetime.date(2001, 9, 3),
datetime.date(2001, 9, 11),
datetime.date(2001, 9, 12),
datetime.date(2001, 9, 13),
datetime.date(2001, 9, 14),
datetime.date(2001, 11, 22),
datetime.date(2001, 12, 25),
datetime.date(2002, 1, 1),
datetime.date(2002, 1, 21),
datetime.date(2002, 2, 18),
datetime.date(2002, 3, 29),
datetime.date(2002, 5, 27),
datetime.date(2002, 7, 4),
datetime.date(2002, 9, 2),
datetime.date(2002, 11, 28),
datetime.date(2002, 12, 25),
datetime.date(2003, 1, 1),
datetime.date(2003, 1, 20),
datetime.date(2003, 2, 17),
datetime.date(2003, 4, 18),
datetime.date(2003, 5, 26),
datetime.date(2003, 7, 4),
datetime.date(2003, 9, 1),
datetime.date(2003, 11, 27),
datetime.date(2003, 12, 25),
datetime.date(2004, 1, 1),
datetime.date(2004, 1, 19),
datetime.date(2004, 2, 16),
datetime.date(2004, 4, 9),
datetime.date(2004, 5, 31),
datetime.date(2004, 6, 11),
datetime.date(2004, 7, 5),
datetime.date(2004, 9, 6),
datetime.date(2004, 11, 25),
datetime.date(2004, 12, 24),
datetime.date(2005, 1, 17),
datetime.date(2005, 2, 21),
datetime.date(2005, 3, 25),
datetime.date(2005, 5, 30),
datetime.date(2005, 7, 4),
datetime.date(2005, 9, 5),
datetime.date(2005, 11, 24),
datetime.date(2005, 12, 26),
datetime.date(2006, 1, 2),
datetime.date(2006, 1, 16),
datetime.date(2006, 2, 20),
datetime.date(2006, 4, 14),
datetime.date(2006, 5, 29),
datetime.date(2006, 7, 4),
datetime.date(2006, 9, 4),
datetime.date(2006, 11, 23),
datetime.date(2006, 12, 25),
datetime.date(2007, 1, 1),
datetime.date(2007, 1, 2),
datetime.date(2007, 1, 15),
datetime.date(2007, 2, 19),
datetime.date(2007, 4, 6),
datetime.date(2007, 5, 28),
datetime.date(2007, 7, 4),
datetime.date(2007, 9, 3),
datetime.date(2007, 11, 22),
datetime.date(2007, 12, 25),
datetime.date(2008, 1, 1),
datetime.date(2008, 1, 21),
datetime.date(2008, 2, 18),
datetime.date(2008, 3, 21),
datetime.date(2008, 5, 26),
datetime.date(2008, 7, 4),
datetime.date(2008, 9, 1),
datetime.date(2008, 11, 27),
datetime.date(2008, 12, 25),
datetime.date(2009, 1, 1),
datetime.date(2009, 1, 19),
datetime.date(2009, 2, 16),
datetime.date(2009, 4, 10),
datetime.date(2009, 5, 25),
datetime.date(2009, 7, 3),
datetime.date(2009, 9, 7),
datetime.date(2009, 11, 26),
datetime.date(2009, 12, 25),
datetime.date(2010, 1, 1),
datetime.date(2010, 1, 18),
datetime.date(2010, 2, 15),
datetime.date(2010, 4, 2),
datetime.date(2010, 5, 31),
datetime.date(2010, 7, 5),
datetime.date(2010, 9, 6),
datetime.date(2010, 11, 25),
datetime.date(2010, 12, 24),
datetime.date(2011, 1, 17),
datetime.date(2011, 2, 21),
datetime.date(2011, 4, 22),
datetime.date(2011, 5, 30),
datetime.date(2011, 7, 4),
datetime.date(2011, 9, 5),
datetime.date(2011, 11, 24),
datetime.date(2011, 12, 26),
datetime.date(2012, 1, 2),
datetime.date(2012, 1, 16),
datetime.date(2012, 2, 20),
datetime.date(2012, 4, 6),
datetime.date(2012, 5, 28),
datetime.date(2012, 7, 4),
datetime.date(2012, 9, 3),
datetime.date(2012, 11, 22),
datetime.date(2012, 12, 25),
datetime.date(2013, 1, 1),
datetime.date(2013, 1, 21),
datetime.date(2013, 2, 18),
datetime.date(2013, 3, 29),
datetime.date(2013, 5, 27),
datetime.date(2013, 7, 4),
datetime.date(2013, 9, 2),
datetime.date(2013, 11, 28),
datetime.date(2013, 12, 25)]
I used the holidays package.
$ pip install holidays
Here is the function I made to determine the next business day after today.
import datetime
import holidays
ONE_DAY = datetime.timedelta(days=1)
HOLIDAYS_US = holidays.US()
def next_business_day():
next_day = datetime.date.today() + ONE_DAY
while next_day.weekday() in holidays.WEEKEND or next_day in HOLIDAYS_US:
next_day += ONE_DAY
return next_day
It will return tomorrow's date, if tomorrow is not a weekend and not a holiday. Otherwise it will find the next* day that isn't either of those things. Example run on Wednesday, 15 March 2017:
>>> next_business_day()
datetime.date(2017, 3, 16)
* Caution, in the event President Camacho declares every day a holiday, this could infinite loop.
I would use dateutil.rrule
:
import datetime
from dateutil import rrule
holidays = [
datetime.date(2012, 5, 1,),
datetime.date(2012, 6, 1,),
# ...
]
# Create a rule to recur every weekday starting today
r = rrule.rrule(rrule.DAILY,
byweekday=[rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR],
dtstart=datetime.date.today())
# Create a rruleset
rs = rrule.rruleset()
# Attach our rrule to it
rs.rrule(r)
# Add holidays as exclusion days
for exdate in holidays:
rs.exdate(exdate)
print rs[0]