2. 时间序列数据基础:时间戳处理、重采样、滑窗概念,Pandas时间序列操作
做量化交易,说白了就是跟时间赛跑。你想想看,每一笔报价、每一次成交,背后都带着一个精确的时间戳。没有时间这根轴,价格数据就是一盘散沙。今天这章,我就带你把这些基础打牢。
2.1 时间戳:交易的「身份证」
时间戳是什么?就是数据点上的一个标签,告诉你在哪个时刻发生了什么事。在量化里,我们通常用两种格式:
- 字符串格式:比如
'2024-01-15 09:30:00',人类友好,但机器处理慢 - 数值格式:比如
1705293000(Unix时间戳),机器友好,但人类看着头疼
我个人习惯,在数据清洗阶段先用字符串,方便肉眼检查。等进入计算环节,一律转成 Pandas 的 DatetimeIndex,性能好得多。
核心原则:永远不要用字符串做时间运算。加减一秒、比较先后,这些操作在字符串上跑起来慢得你想哭。
2.2 重采样:把数据「揉」成你想要的形状
重采样,说白了就是改变数据的时间频率。高频数据转低频叫「降采样」,低频转高频叫「升采样」。在量化里,降采样用得最多。
举个例子,你拿到的是 tick 级数据(每笔成交),但策略只需要分钟级 K 线。这时候就要做降采样:
import pandas as pd
import numpy as np
# 模拟 tick 数据
tick_data = pd.DataFrame({
'price': np.random.rand(100) * 10 + 100,
'volume': np.random.randint(1, 100, 100)
}, index=pd.date_range('2024-01-15 09:30:00', periods=100, freq='1s'))
# 降采样到 1 分钟 K 线
minute_bar = tick_data.resample('1min').agg({
'price': 'ohlc', # Open, High, Low, Close
'volume': 'sum'
})
print(minute_bar.head())
我在项目中遇到过一个问题:重采样时数据量突然少了。后来发现是时间索引没对齐,有些时间戳落在了采样窗口的边界上。嗯,这里要注意,resample 默认用左闭右开区间,你可以通过 label 和 closed 参数调整。
小技巧:降采样时,如果数据有缺失,可以用 fillna() 或 interpolate() 补上。但别盲目补,先搞清楚缺失的原因——是停牌?还是数据源本身就有问题?
2.3 滑窗:滚动计算的核心
滑窗,就是在一个固定大小的窗口里,不断往前滑动做计算。移动平均线、布林带、RSI……这些技术指标,底层全是滑窗。
Pandas 里用 rolling() 实现:
# 计算 5 分钟移动平均
close_prices = minute_bar['price']['close']
ma_5 = close_prices.rolling(window=5).mean()
# 计算 20 分钟标准差(布林带用)
std_20 = close_prices.rolling(window=20).std()
为什么会这样?因为滑窗本质上是一个「延迟计算」的过程。窗口内的数据全部到位后,才会输出结果。所以刚开盘那几分钟,窗口没填满,输出是 NaN。
避坑指南:我曾经在实盘策略里直接用 rolling().mean(),结果发现信号延迟了整整一个窗口长度。后来才意识到,rolling() 默认用窗口的最后一个时间点作为输出位置。如果你想要「当前时刻」的均值,得用 rolling(window).mean().shift(1) 把结果往前挪一位。
2.4 Pandas 时间序列操作速查
下面这张表,是我平时用得最多的几个操作,你直接拿去用:
| 操作 | 代码 | 说明 |
|---|---|---|
| 创建时间序列 | pd.date_range(start, end, freq='1min') |
生成等间隔时间索引 |
| 转换时间戳 | pd.to_datetime(df['time_col']) |
字符串转时间类型 |
| 设置索引 | df.set_index('time_col', inplace=True) |
把时间列设为行索引 |
| 重采样 | df.resample('5min').mean() |
降采样到 5 分钟 |
| 滑窗计算 | df['col'].rolling(10).mean() |
10 期移动平均 |
| 时间偏移 | df.shift(1) |
数据整体往后挪一行 |
| 时间差计算 | df.index.to_series().diff() |
计算相邻时间戳间隔 |
2.5 知识体系总览
我把这章的核心逻辑画了张图,你看一眼就能串起来:
这张图把三个核心模块串起来了。你从左边开始,先搞定时间戳格式,然后通过重采样统一数据频率,最后用滑窗提取特征。每一步都踩稳了,后面的实时特征工程才能跑得顺。
我的经验:刚开始做量化时,我总想一步到位搞复杂模型。后来发现,80% 的问题出在时间处理上——时间戳没对齐、重采样参数设错了、滑窗延迟没考虑。把基础打牢,比什么都重要。