数据准备:获取历史Tick数据、数据清洗与对齐、成交量分布特征分析
做VWAP执行框架,最磨人的不是策略本身,而是数据准备。我见过太多人一上来就写核心逻辑,结果数据一跑全是坑。今天咱们就把这块硬骨头啃下来。
一、历史Tick数据的获取
Tick数据,说白了就是每一笔成交的原始记录。它包含时间、价格、成交量、买卖方向这些最细粒度的信息。我个人的习惯是,先搞清楚数据源再动手。
常见的获取渠道有这么几个:
- 交易所直连:最干净,但门槛高。适合机构用户。
- 数据服务商:比如Wind、聚宽、Tushare。我早期做回测时用的就是Tushare,免费版够用,但高频场景下延迟明显。
- 券商API:部分券商提供历史Tick下载,但格式不统一,需要自己解析。
举个例子,用Python从Tushare拉取某只股票一天的Tick数据:
import tushare as ts
# 初始化接口
pro = ts.pro_api('your_token_here')
# 获取2024年1月15日贵州茅台的Tick数据
df = pro.tick_data(ts_code='600519.SH', trade_date='20240115',
start_time='093000', end_time='150000')
print(df.head())
嗯,这里要注意。Tick数据量非常大,一天可能几十万条。我建议你按日期分片存储,别一股脑全塞内存里。我曾经有个项目,直接加载三个月的数据,结果内存爆了,排查了半天才发现是数据加载的问题。
二、数据清洗与对齐
拿到原始Tick数据后,你会发现它脏得不行。缺失值、异常值、重复记录,什么妖魔鬼怪都有。数据清洗这一步,我建议你按这个顺序来:
- 去重:同一时间戳的重复成交记录,只保留一条。
- 处理缺失值:价格或成交量为空的,直接删除或向前填充。
- 过滤异常值:比如价格突然跳空超过10%,或者成交量异常放大。这些往往是数据错误。
- 时间对齐:不同数据源的时间戳可能不同步,需要统一到同一个时间基准上。
数据对齐这块,我踩过一个大坑。当时做跨品种套利,需要把两只股票的Tick数据对齐到同一时间轴上。结果发现A股票的时间戳是精确到秒,B股票是精确到毫秒。直接合并的话,时间戳根本对不上。
我的解决方案是:先统一精度,再按时间窗口聚合。比如把毫秒级的数据向下取整到秒,然后按秒做聚合。代码大概长这样:
import pandas as pd
# 假设df1和df2是两个不同精度的Tick数据
df1['time'] = pd.to_datetime(df1['time']).dt.floor('S') # 向下取整到秒
df2['time'] = pd.to_datetime(df2['time']).dt.floor('S')
# 按时间合并
merged = pd.merge_asof(df1.sort_values('time'),
df2.sort_values('time'),
on='time',
tolerance=pd.Timedelta('1s'))
你想想看,如果这一步没做好,后面算出来的VWAP全是错的。所以数据对齐再怎么强调都不过分。
三、成交量分布特征分析
数据洗干净了,接下来就是分析成交量的分布特征。为什么要做这个?因为VWAP的核心就是成交量加权,你得知道成交量在一天里是怎么分布的。
我个人习惯从三个维度来分析:
- 时间维度:成交量在开盘、盘中、收盘的分布情况。
- 价格维度:成交量在不同价格区间的集中程度。
- 买卖方向:主动买和主动卖的比例。
举个例子,我统计过A股某只蓝筹股一天的成交量分布,结果是这样的:
| 时间段 | 成交量占比 | 特征描述 |
|---|---|---|
| 9:30 - 10:00 | 25% | 开盘密集成交,多空博弈激烈 |
| 10:00 - 11:30 | 35% | 盘中平稳,偶有脉冲 |
| 13:00 - 14:30 | 20% | 午盘后缩量,观望情绪浓 |
| 14:30 - 15:00 | 20% | 尾盘放量,机构调仓 |
看到没?开盘和尾盘占了将近一半的成交量。这就是为什么很多VWAP策略会在开盘和尾盘加大执行力度。
为了更直观地展示这个分析过程,我画了一张流程图:
分析完分布特征后,你会发现一些规律。比如,很多股票在开盘前15分钟成交量特别大,但价格波动也剧烈。这时候如果直接按VWAP执行,很容易被扫到不好的价格。
最后,成交量分布特征分析还有一个隐藏用途——检测异常行情。如果某一天的成交量分布和过去30天的平均分布偏差超过3个标准差,那大概率是有突发事件。这时候VWAP策略应该暂停执行,或者切换到更保守的参数。
嗯,数据准备这块就讲这么多。记住一句话:数据质量决定了策略的上限。你花80%的时间在数据上,一点都不亏。