【问题标题】:Convert list of trading days to holidays将交易日列表转换为节假日
【发布时间】:2020-04-10 17:18:38
【问题描述】:

我正在使用下面的函数,它使用交易日列表,这似乎会减慢速度。是否可以将该列表转换为节假日以使其更快?

import pandas_market_calendars as mcal
def next_trading_day(start_day, num_trading_days, direction):
    '''returns the next/previous trading day. Business_days determines how many days
    back or into the future, direction determines wether back (-1) or forward (1)'''
    for i in range(0, num_trading_days, direction):
        next_day = start_day +datetime.timedelta(days=direction)    
        while next_day.weekday() in [5,6] or next_day not in set(mcal.get_calendar('NYSE').valid_days(start_date='2016-12-20', end_date='2020-01-10')):
            next_day +=  datetime.timedelta(days=direction)
        start_day = next_day
    return start_day

请注意,我不能使用 Python 必须提供的其他假期功能,因为它们与交易日无关,而是与联邦假期等有关。所以它必须基于 pandas_market_calendars。

【问题讨论】:

    标签: python pandas date


    【解决方案1】:

    解决方案

    无需遍历每个日期。请参阅此实现:

    逻辑

    1. 在日期范围内搜索有效交易日。使用大于您需要的日期范围 (num_trading_days)。我们另外添加100days 以扩展搜索日期范围。
    2. 接下来我们从可用的交易日期中选择第一个num_trading_days
    3. 并选择第一个num_trading_days 的最后一天作为next_day
    4. 最后我们返回一个元组:(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
    

    【讨论】:

    • @Tartaglia 请试试这个,如果您有任何问题,请告诉我。
    猜你喜欢
    • 2021-02-27
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    相关资源
    最近更新 更多