2

交易数据在非节假日工作日上午 9:30 开始记录,并定期记录(5 秒、5 分钟、30 分钟等)直到下午 4:00。例如,非节假日工作日的 [9:30AM, 9:35AM,...,3:50PM, 3:55PM] 是有 5 分钟数据的时间。

是否pandas具备正确使用这种时间结构所需的能力?我已经看到有一些方法可以将自定义假期添加到工作日(上午 9:00 到下午 4:00)。但是我还没有看到定义自定义工作时间,比如(9:30AM-4:00PM)。例如,是否可以定义自定义交易时间[9:30AM, 10:30AM, ... 3:30PM],或者利用任何代码为营业时间提供支持的交易 5 分钟

例如,是否有一种pandas动力方式来生成DatetimeIndex遵循交易时间规则的 5 分钟频率:

  • 周一:上午 9 点 30 分、上午 9 点 35 分、... 下午 3 点 50 分、下午 3 点 55 分
  • 周二:上午 9 点 30 分、上午 9 点 35 分、... 下午 3 点 50 分、下午 3 点 55 分
  • ...
  • 周五:上午 9:30、上午 9:35、... 下午 3:50、下午 3:55
  • 星期一:联邦假期,没有时间
  • 周二:上午 9 点 30 分、上午 9 点 35 分、... 下午 3 点 50 分、下午 3 点 55 分
  • (等等)

或者这只是目前不支持?

换句话说,pandas目前有哪些方法/类来实现这种功能?如果没有,有人知道其他可以提供帮助的库吗?

4

2 回答 2

2

我有同样的问题,至少关于

有没有一种由 Pandas 驱动的方法来生成一个 DatetimeIndex,比如说,5 分钟的频率,遵循交易时间的规则?

我在下面有一个答案,但首先,关于:

pandas 是否具备正确处理这种时间结构所需的能力?

“一起工作”这个词相当含糊。你想做什么“工作”?
Pandas 绝对可以在这种时间结构下正常工作,做一些事情,但也许不能做其他事情。

和关于。

例如,是否可以定义自定义交易时间 [9:30AM, 10:30AM, ... 3:30PM] ...?

答案是肯定的,但是我将在下面描述一些限制。也就是说,我将主要关注生成遵循交易时间和交易日规则的日期时间索引的能力,并在下面演示如何使用 pandas 来做到这一点。首先我会提到一些现有的 pandas 工具及其局限性。

我昨天晚上大部分时间都在研究这个。pandas 必须生成日期时间索引范围的大多数函数都接受输入频率freq作为字符串(例如'15T'15 分钟或'D'每天)。

这些相同的函数通常也会接受pandas 时间序列偏移对象来代替频率。有许多不同类型的偏移量:每种都定义了一个可以有规则的频率,例如跳过周末(例如,offsets.BusinessDay )或仅针对营业时间(例如仅从上午 9 点到下午 5 点)生成日期时间索引。

我遇到的频率和偏移对象的主要问题是(在大多数情况下)没有办法将它们组合起来。

例如,使用BusinessHour 偏移类,我可以指定我想生成一个只包含营业时间(交易时间)的索引,我什至可以只在工作日(超过一堆日期)这样做,但我不能将它与指定频率,例如每分钟一次或每 15 分钟一次。相反,BusinessHour偏移类似乎默认为仅每小时一次的频率,并且我没有发现任何方法可以更改它。

或者,例如,我可以使用pandas.bdate_range()指定频率'30T'每 30 分钟生成一个索引点,但将包括非工作日。如果我将频率设置'B'为仅工作日,那么它会跳过非工作日,但我每天只能获得一个索引点。我发现没有办法将这两个频率结合起来。

我想出的最简单的解决方案是生成一个工作日列表(交易日),然后循环遍历该列表,从开盘开始以所需的频率(1 分钟、5 分钟或 15 分钟)为每个日期生成一个索引直到每个日期的关闭时间。然后我使用 pandasDatetimeIndex.union_many()方法将日期时间索引合并为一个。代码如下所示:

def trading_day_range(bday_start=None,bday_end=None,bday_freq='B',
                      open_time='09:30',close_time='16:00',iday_freq='15T',weekmask=None):

    if bday_start is None: bday_start = pd.Timestamp.today()
    if bday_end   is None: bday_end = bday_start + pd.Timedelta(days=1)

    daily = []
    for d in pd.bdate_range(start=bday_start,end=bday_end,freq=bday_freq,weekmask=weekmask):
        topen  = pd.Timestamp(open_time)
        d1    = d.replace(hour=topen.hour,minute=topen.minute)
        tclose = pd.Timestamp(close_time)
        d2    = d.replace(hour=tclose.hour,minute=tclose.minute+1)
        daily.append(pd.date_range(d1,d2,freq=iday_freq))
   
    index = daily[0].union_many(daily[1:])
    return index

以下是一些使用它的示例:

ix = trading_day_range()
print('len(ix)=',len(ix))
print(ix[20:40])
print(ix[-20:])
len(ix)= 54
DatetimeIndex(['2021-04-13 14:30:00', '2021-04-13 14:45:00',
               '2021-04-13 15:00:00', '2021-04-13 15:15:00',
               '2021-04-13 15:30:00', '2021-04-13 15:45:00',
               '2021-04-13 16:00:00', '2021-04-14 09:30:00',
               '2021-04-14 09:45:00', '2021-04-14 10:00:00',
               '2021-04-14 10:15:00', '2021-04-14 10:30:00',
               '2021-04-14 10:45:00', '2021-04-14 11:00:00',
               '2021-04-14 11:15:00', '2021-04-14 11:30:00',
               '2021-04-14 11:45:00', '2021-04-14 12:00:00',
               '2021-04-14 12:15:00', '2021-04-14 12:30:00'],
              dtype='datetime64[ns]', freq=None)
DatetimeIndex(['2021-04-14 11:15:00', '2021-04-14 11:30:00',
               '2021-04-14 11:45:00', '2021-04-14 12:00:00',
               '2021-04-14 12:15:00', '2021-04-14 12:30:00',
               '2021-04-14 12:45:00', '2021-04-14 13:00:00',
               '2021-04-14 13:15:00', '2021-04-14 13:30:00',
               '2021-04-14 13:45:00', '2021-04-14 14:00:00',
               '2021-04-14 14:15:00', '2021-04-14 14:30:00',
               '2021-04-14 14:45:00', '2021-04-14 15:00:00',
               '2021-04-14 15:15:00', '2021-04-14 15:30:00',
               '2021-04-14 15:45:00', '2021-04-14 16:00:00'],
              dtype='datetime64[ns]', freq=None)
ix1 = trading_day_range('01/01/2021 09:30','01/13/2021 16:00',
                         bday_freq='C',iday_freq='30T',weekmask='Wed Thu Fri')
print('len(ix1)=',len(ix1))
print(ix1[20:40])
print(ix1[-20:])
len(ix1)= 70
DatetimeIndex(['2021-01-06 12:30:00', '2021-01-06 13:00:00',
               '2021-01-06 13:30:00', '2021-01-06 14:00:00',
               '2021-01-06 14:30:00', '2021-01-06 15:00:00',
               '2021-01-06 15:30:00', '2021-01-06 16:00:00',
               '2021-01-07 09:30:00', '2021-01-07 10:00:00',
               '2021-01-07 10:30:00', '2021-01-07 11:00:00',
               '2021-01-07 11:30:00', '2021-01-07 12:00:00',
               '2021-01-07 12:30:00', '2021-01-07 13:00:00',
               '2021-01-07 13:30:00', '2021-01-07 14:00:00',
               '2021-01-07 14:30:00', '2021-01-07 15:00:00'],
              dtype='datetime64[ns]', freq=None)
DatetimeIndex(['2021-01-08 13:30:00', '2021-01-08 14:00:00',
               '2021-01-08 14:30:00', '2021-01-08 15:00:00',
               '2021-01-08 15:30:00', '2021-01-08 16:00:00',
               '2021-01-13 09:30:00', '2021-01-13 10:00:00',
               '2021-01-13 10:30:00', '2021-01-13 11:00:00',
               '2021-01-13 11:30:00', '2021-01-13 12:00:00',
               '2021-01-13 12:30:00', '2021-01-13 13:00:00',
               '2021-01-13 13:30:00', '2021-01-13 14:00:00',
               '2021-01-13 14:30:00', '2021-01-13 15:00:00',
               '2021-01-13 15:30:00', '2021-01-13 16:00:00'],
              dtype='datetime64[ns]', freq=None)
于 2021-04-13T18:30:44.323 回答
0

您可以以正常方式生成 5 分钟代码,然后使用 DatetimeIndex.indexer_between_time 获取自定义交易时间的 datetimeindex ( https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DatetimeIndex.indexer_between_time.html )

示例:如果 i 是您创建的日期时间索引,则下面的代码将为您提供交易时间的自定义日期时间索引

i [i.indexer_between_time('09:30:00', '04:00:00', include_end=False) ]

于 2018-03-26T06:26:18.363 回答