第1章:市场微观结构数据:Tick级数据、Level 1/2/3数据、数据清洗与预处理
1.1 数据是量化交易的“原材料”
做量化交易,说白了就是跟数据打交道。我见过太多人,策略模型写得花里胡哨,结果一上实盘就崩。为什么?数据没处理好。
市场微观结构数据,就是最底层、最原始的交易数据。它记录了每一笔订单的生成、撮合、取消全过程。你想想看,如果连原材料都不干净,做出来的菜能好吃吗?
我个人习惯,拿到任何数据源,第一件事不是跑策略,而是先做数据质量检查。这一步省不了,也急不得。
1.2 Tick级数据:最细颗粒度的市场脉搏
Tick级数据,也叫逐笔成交数据。每一笔交易都会生成一条Tick记录。它包含:
- 成交时间:精确到毫秒甚至微秒
- 成交价格:这笔交易的实际成交价
- 成交量:成交的股数或合约数
- 成交方向:买方主动还是卖方主动
我在项目中遇到过一个问题:某交易所的Tick数据,时间戳居然有重复。后来发现是撮合引擎的时钟同步出了问题。嗯,这种坑不踩一次,你根本想不到。
核心要点:Tick数据是最高频的数据,能捕捉到秒级甚至毫秒级的市场变化。但数据量极大,一天可能几千万条。
1.3 Level 1/2/3数据:订单簿的“三层透视”
很多人分不清Level 1、Level 2、Level 3到底有什么区别。我简单解释一下:
| 数据层级 | 包含内容 | 典型用途 |
|---|---|---|
| Level 1 | 最优买卖价(Best Bid/Offer) | 简单策略、盘口监控 |
| Level 2 | 多档买卖盘口(通常5-10档) | 订单簿分析、流动性评估 |
| Level 3 | 全部订单簿深度(全量挂单) | 高频做市、微观结构建模 |
Level 1数据,说白了就是“现在谁出价最高、谁要价最低”。Level 2能看到更深层的挂单情况。Level 3则是全量数据,能看到每一笔挂单的完整信息。
我曾经用Level 3数据做过一个流动性黑洞检测模型。效果不错,但数据清洗的工作量,差点让我崩溃。
个人建议:刚开始做微观结构研究,从Level 2数据入手就够了。Level 3数据太“脏”,处理不好反而引入噪声。
1.4 数据清洗与预处理:避坑指南
数据清洗,是量化交易中最枯燥但最重要的一环。我总结了几条“血泪教训”:
- 时间戳对齐:不同数据源的时间基准可能不同。我遇到过某数据商的时间戳比实际慢了15分钟,整整排查了两天。
- 异常值处理:比如成交价为0、成交量为负数。这些数据必须剔除或修正。
- 缺失值填充:非交易时段的数据如何处理?我个人习惯用前值填充,但要注意边界情况。
- 数据去重:同一笔交易被重复记录,这在某些数据源中很常见。
警告:千万不要在未清洗的数据上直接跑策略。我曾经见过一个团队,因为数据没去重,回测收益虚高了30%。实盘直接亏到怀疑人生。
1.5 数据清洗的代码示例
下面是我常用的数据清洗流程,用Python实现:
import pandas as pd
import numpy as np
# 加载Tick数据
df = pd.read_csv('tick_data.csv')
# 1. 去除成交价为0或负数的记录
df = df[df['price'] > 0]
# 2. 去除成交量为0的记录
df = df[df['volume'] > 0]
# 3. 时间戳去重
df = df.drop_duplicates(subset=['timestamp', 'price', 'volume'])
# 4. 缺失值填充(前值填充)
df = df.fillna(method='ffill')
# 5. 异常值检测(3倍标准差法)
mean_price = df['price'].mean()
std_price = df['price'].std()
df = df[(df['price'] > mean_price - 3*std_price) &
(df['price'] < mean_price + 3*std_price)]
print(f"清洗后数据量:{len(df)} 条")
这段代码看起来简单,但实际项目中,每一步都可能遇到意想不到的问题。比如去重时,不同交易所的时间戳精度不一样,有的精确到毫秒,有的精确到微秒。你想想看,如果不统一精度,去重就会出问题。
1.6 知识体系框架图
下面这张图,概括了本章的核心内容:
1.7 本章小结
市场微观结构数据,是量化交易中最底层、最真实的数据。Tick级数据记录每一笔交易,Level 1/2/3数据展示订单簿的不同深度。数据清洗不是可有可无的步骤,而是决定策略成败的关键。
我个人经验是:花在数据清洗上的时间,永远值得。你省掉的每一步,都会在实盘中加倍还回来。
记住一句话:垃圾数据进,垃圾策略出。数据质量,决定策略上限。