利用1分钟数据合成15分钟数据
由qxiao创建,最终由qxiao 被浏览 94 用户
BigQuant 平台已经提供了股票、期货、可转债、基金等各类资产的1分钟数据,比如股票的分钟数据见如下链接:https://bigquant.com/data/datasources/cn_stock_bar1m。那么,基于1分钟数据,如果需要更长周期的分钟数据,怎么办呢?本着“受人鱼不如授人以渔”的态度,BigQuant 平台不加工更长周期的分钟数据,因为每个交易者的需求不同,加工细节也不一样,但平台提供教程,告诉大家如何加工更长周期的分钟数据。
以15分钟行情数据为例,首先,我们以 000002.SZ 在 2025-02-14 这一天的分钟数据为例,加工 15分钟数据。原数据如下:
一、简单方法:pandas 的 resample 函数
pandas 自带 resample 方法用于处理时间序列数据。它允许你将时间序列数据从一个频率重采样到另一个频率。例如,你可以将每日数据重采样为每月数据,或者将每小时数据重采样为每日数据。具体用法网上有很多教程,或者咨询 quantchat。我们对原始1分钟数据利用 resample 函数重采样为15分钟数据,代码如下:
df = bar1m.copy()
df.set_index("date", inplace=True)
resampled_df = df.resample("15T", closed="left", label="right").agg({
"instrument": "last",
"open": "first",
"high": "max",
"low": "min",
"close": "last"
}).dropna()
resampled_df
重采样时采用“左闭右开”方法,得到的15分钟数据如下:
date | instrument | open | high | low | close |
---|---|---|---|---|---|
2025-02-14 09:30:00 | 000002.SZ | 7.93 | 7.93 | 7.93 | 7.93 |
2025-02-14 09:45:00 | 000002.SZ | 7.93 | 8.05 | 7.81 | 7.86 |
2025-02-14 10:00:00 | 000002.SZ | 7.85 | 7.86 | 7.76 | 7.78 |
2025-02-14 10:15:00 | 000002.SZ | 7.78 | 7.85 | 7.78 | 7.82 |
2025-02-14 10:30:00 | 000002.SZ | 7.82 | 7.82 | 7.75 | 7.77 |
2025-02-14 10:45:00 | 000002.SZ | 7.78 | 7.78 | 7.75 | 7.77 |
2025-02-14 11:00:00 | 000002.SZ | 7.77 | 7.8 | 7.76 | 7.77 |
2025-02-14 11:15:00 | 000002.SZ | 7.77 | 7.81 | 7.77 | 7.81 |
2025-02-14 11:30:00 | 000002.SZ | 7.8 | 7.83 | 7.79 | 7.81 |
2025-02-14 11:45:00 | 000002.SZ | 7.81 | 7.82 | 7.81 | 7.81 |
2025-02-14 13:15:00 | 000002.SZ | 7.82 | 7.87 | 7.82 | 7.84 |
2025-02-14 13:30:00 | 000002.SZ | 7.85 | 7.85 | 7.8 | 7.8 |
2025-02-14 13:45:00 | 000002.SZ | 7.8 | 7.81 | 7.76 | 7.76 |
2025-02-14 14:00:00 | 000002.SZ | 7.76 | 7.79 | 7.76 | 7.76 |
2025-02-14 14:15:00 | 000002.SZ | 7.77 | 7.77 | 7.71 | 7.77 |
2025-02-14 14:30:00 | 000002.SZ | 7.77 | 7.79 | 7.75 | 7.78 |
2025-02-14 14:45:00 | 000002.SZ | 7.78 | 7.81 | 7.77 | 7.8 |
2025-02-14 15:00:00 | 000002.SZ | 7.8 | 7.81 | 7.78 | 7.81 |
2025-02-14 15:15:00 | 000002.SZ | 7.81 | 7.81 | 7.81 | 7.81 |
上述数据基本符合预期,但是可以看到在上午收盘和下午收盘的两个时间点多出了两条数据,分别是 2025-02-14 11:45:00 和 2025-02-14 15:15:00。这也说明了 resample() 函数的局限性,因为我们采用“左闭右开”的形式,既在时间序列中采用如下形式:[t1, t2, …, t15),这样我们会把 t1 这一分钟的数据纳入重采样的范围,而 t15 这一分钟不回纳入重采样的范围。针对上述时序数据,对于最后15分钟,既 [14:45:00, 14:46:00, …, 15:00:00),resample() 函数会把 15:00:00 这一分钟的数据纳入下一个15分钟频率的样本中,这样就会多出一条数据。”左开右闭”也存在类似的问题。
因此,我们可以利用 resample() 函数快速得到不同时间频率的数据,只需要把多出的数据剔除即可。但这种方法却不够精细,如果需要精确的15分钟数据,可以参考下面自定义的方法。
二、精细方法:自定义时间区间
无论什么资产品种,国内市场的交易时间都是不连续的,会存在中间休市的情况,期货里面尤为突出。resample()函数无法重采样为更为精确的15分钟数据,因此我们提供以下代码供大家参考:
df = bar1m.copy()
df["time"] = df["date"].dt.strftime("%H%M%S").astype(int)
time_sets = {
1: [90000, 91500, 93000, 94500, 100000, 101500, 103000, 104500, 110000, 111500, 113000],
2: [130000, 131500, 133000, 134500, 140000, 141500, 143000, 144500, 150000],
}
df_list = []
for index, time_sereis in time_sets.items():
for i in range(1, len(time_sereis)):
start_time = time_sereis[i-1]
end_time = time_sereis[i]
if i-1 == 0: # 第一个时间段实行“左闭右闭”的方式,包含开始分钟的数据
group_df = df[(df["time"]>=start_time) & (df["time"]<=end_time)]
else: # 其他时间段则实行“左开右闭”的方式,不包含开始分钟的数据
group_df = df[(df["time"]>start_time) & (df["time"]<=end_time)]
if group_df.shape[0] == 0:
continue
bar1_nm = {
"instrument": group_df["date"].values[-1],
"date": group_df["date"].values[-1],
"high": group_df["high"].max(),
"open": group_df["open"].values[0],
"low": group_df["low"].min(),
"close": group_df["close"].values[-1],
}
df_list.append(pd.DataFrame(bar1_nm, index=[0]))
bar15m = pd.concat(df_list, axis=0)
bar15m
上述代码自定义了上午开市和下午开市的时间间隔,采用15分钟为间隙。这样,我们循环遍历每个时间间隔,这样,对于特殊的时间间隔,就能采用“左闭右闭“的方式获取完整的分钟数据。
上述方法的优点是自由度高,可以根据需求加工各种类型的分钟、小时数据,且更加精确;但是缺点是代码更复杂,且加工效率不如 pandas 自带的函数。当然,我们也可以采用并发的方式优化数据构建效率。
instrument | date | high | open | low | close | |
---|---|---|---|---|---|---|
0 | 2025-02-14 09:25:00 | 2025-02-14 09:25:00 | 7.93 | 7.93 | 7.93 | 7.93 |
0 | 2025-02-14 09:45:00 | 2025-02-14 09:45:00 | 8.05 | 7.93 | 7.81 | 7.82 |
0 | 2025-02-14 10:00:00 | 2025-02-14 10:00:00 | 7.83 | 7.83 | 7.76 | 7.78 |
0 | 2025-02-14 10:15:00 | 2025-02-14 10:15:00 | 7.85 | 7.79 | 7.79 | 7.81 |
0 | 2025-02-14 10:30:00 | 2025-02-14 10:30:00 | 7.81 | 7.81 | 7.75 | 7.77 |
0 | 2025-02-14 10:45:00 | 2025-02-14 10:45:00 | 7.78 | 7.76 | 7.75 | 7.76 |
0 | 2025-02-14 11:00:00 | 2025-02-14 11:00:00 | 7.8 | 7.77 | 7.76 | 7.78 |
0 | 2025-02-14 11:15:00 | 2025-02-14 11:15:00 | 7.81 | 7.78 | 7.77 | 7.81 |
0 | 2025-02-14 11:30:00 | 2025-02-14 11:30:00 | 7.83 | 7.8 | 7.79 | 7.81 |
0 | 2025-02-14 13:15:00 | 2025-02-14 13:15:00 | 7.87 | 7.82 | 7.82 | 7.83 |
0 | 2025-02-14 13:30:00 | 2025-02-14 13:30:00 | 7.84 | 7.83 | 7.8 | 7.8 |
0 | 2025-02-14 13:45:00 | 2025-02-14 13:45:00 | 7.81 | 7.8 | 7.76 | 7.78 |
0 | 2025-02-14 14:00:00 | 2025-02-14 14:00:00 | 7.79 | 7.77 | 7.76 | 7.76 |
0 | 2025-02-14 14:15:00 | 2025-02-14 14:15:00 | 7.78 | 7.76 | 7.71 | 7.78 |
0 | 2025-02-14 14:30:00 | 2025-02-14 14:30:00 | 7.79 | 7.77 | 7.75 | 7.79 |
0 | 2025-02-14 14:45:00 | 2025-02-14 14:45:00 | 7.81 | 7.79 | 7.78 | 7.81 |
0 | 2025-02-14 15:00:00 | 2025-02-14 15:00:00 | 7.81 | 7.81 | 7.78 | 7.81 |
附录 完整代码
https://bigquant.com/codesharev3/1da1b229-5dad-4388-9708-dd1a23bd4a4a
\