解决方案
无需遍历每个日期。请参阅此实现:
逻辑:
- 在日期范围内搜索有效交易日。使用大于您需要的日期范围 (
num_trading_days)。我们另外添加100days 以扩展搜索日期范围。
- 接下来我们从可用的交易日期中选择第一个
num_trading_days。
- 并选择第一个
num_trading_days 的最后一天作为next_day。
- 最后我们返回一个元组:
(next_day, valid_trading_days)。
#!pip install pandas_market_calendars
import pandas_market_calendars as mcal
import numpy as np
import pandas as pd
import datetime
def next_trading_day(start_day=None, num_trading_days=7, direction=1, SAFE_DELTA = 100, as_string=True):
"""Returns the next/previous trading date separated by a certain number of
trading days.
This function returns the next/previous trading day. The parameter num_trading_days
determines how many days back or into the future, direction determines whether
backward (-1) or forward (1).
Parameters
----------
start_day: datetime.date or a str object. (default is today's UTC date).
Date of starting day.
num_trading_days: int. (default is 7)
direction: int. (default is 1 (forward))
Use 1 for forward/future and -1 for backward/past.
as_string: bool (default is True)
This controls the data type of the returned value of next_day.
Returns the next_day as a string if True, else as a datetime.date object.
SAFE_DELTA: int. (default is 100)
SAFE_DELTA = 100 adds 100 additional days to extend the range of dates and
then finds which dates are valid trading dates.
Returns
-------
next_day: str or datetime.date object.
valid_trading_days: pandas.Series object of datetime.date objects.
"""
if start_day is None:
start_day = datetime.datetime.utcnow().date()
start = pd.to_datetime(start_day)
end = start + np.timedelta64(num_trading_days+SAFE_DELTA, 'D')*direction
business_days = mcal.get_calendar('NYSE').valid_days(start_date=start, end_date=end)
valid_trading_days = pd.DataFrame(business_days[:num_trading_days], columns=['DT']).DT.dt.date
next_day = business_days[num_trading_days].date()
if as_string:
next_day = next_day.strftime("%Y-%m-%d")
# if the series of trading days from start_day to next_day are not required,
# then use:
# >>> valid_trading_days = None
# You may also comment out the valid_trading_days variable creation line above.
# And change the function-output accordingly.
return (next_day, valid_trading_days)
测试
start_day='2019-12-18' # (Wednesday)
num_trading_days = 7
next_day, valid_trading_days = next_trading_day(start_day = start_day,
num_trading_days = num_trading_days,
direction = 1,
SAFE_DELTA = 100)
print('next_day: {} (after {} trading days)\n'.format(next_day, num_trading_days))
print('valid_trading_days: \n\n{}'.format(valid_trading_days))
输出:
next_day: 2019-12-30 (after 7 trading days)
valid_trading_days:
0 2019-12-18
1 2019-12-19
2 2019-12-20
3 2019-12-23
4 2019-12-24
5 2019-12-26
6 2019-12-27
Name: DT, dtype: object