第三章:数据采集与预处理——Tick级数据获取、数据清洗、缺失值处理

做期权做市,说白了就是跟市场抢时间。你比别人快0.1秒,可能就多赚一个点差。但前提是——你得有干净的数据。

我见过太多团队,策略模型写得天花乱坠,结果一上实盘就崩。为什么?数据源就有问题。Tick级数据里藏着各种坑,今天我就把这些坑一个个给你指出来。

3.1 Tick级数据获取:你得知道你要什么

先问个问题:你真的需要Tick级数据吗?

我个人习惯是,做市策略必须用Tick级。因为期权定价对波动率极其敏感,而波动率在Tick级别变化最快。如果你用1分钟K线做做市,那基本等于闭着眼睛开车。

3.1.1 数据源的选择

目前主流的数据源有几种:

  • 交易所直连:延迟最低,但成本高,适合机构
  • 第三方数据商:如Wind、聚宽、Tushare,适合回测和研发
  • 券商API:实盘常用,但注意限流

我在项目中遇到过一个问题:某数据商的Tick数据居然有重复的时间戳。同一毫秒内出现两笔完全相同的报价,这明显是数据拼接时的bug。所以不管你用哪个源,一定要做校验。

3.1.2 Tick数据的字段结构

一个标准的期权Tick数据,至少包含这些字段:

字段名 说明 示例
timestamp 时间戳(精确到毫秒) 2024-01-15 09:30:00.123
symbol 合约代码 510050C2401M02500
bid_price 买一价 0.0520
bid_volume 买一量 100
ask_price 卖一价 0.0525
ask_volume 卖一量 200
last_price 最新成交价 0.0522
volume 累计成交量 15000

嗯,这里要注意:有些数据源会把bid/ask的深度也给你,比如五档十档。但做市策略其实只需要最优价,多了反而增加计算负担。

3.2 数据清洗:脏数据是策略的毒药

你想想看,如果数据里混进一个异常值,你的定价模型可能瞬间报出离谱的价格。轻则亏钱,重则被交易所处罚。

我曾经在实盘中遇到过:某合约的卖一价突然从0.05跳到0.50,然后又跳回来。后来查证是数据源的一个字段解析错误。如果当时没有清洗逻辑,我的做市机器人就会以0.50的价格买入,那损失就大了。

3.2.1 常见的脏数据类型

  • 价格异常:超出合理范围(比如期权价格大于标的资产价格)
  • 买卖价倒挂:bid_price > ask_price,这在正常市场不可能出现
  • 时间戳乱序:后一条数据的时间戳比前一条还早
  • 重复数据:完全相同的数据出现多次
  • 零值或负值:价格或数量出现0或负数

3.2.2 清洗规则示例

我一般会写一个清洗函数,像这样:

def clean_tick_data(df):
    # 1. 移除买卖价倒挂
    df = df[df['bid_price'] < df['ask_price']]
    
    # 2. 移除价格超出合理范围
    df = df[(df['bid_price'] > 0) & (df['ask_price'] > 0)]
    df = df[df['bid_price'] < df['ask_price'] * 1.5]  # 价差不能太大
    
    # 3. 移除时间戳乱序
    df = df.sort_values('timestamp')
    df = df[df['timestamp'].diff() >= pd.Timedelta(0)]
    
    # 4. 去重
    df = df.drop_duplicates(subset=['timestamp', 'symbol'])
    
    return df
注意:清洗规则不能太激进。比如价差限制,在极端行情下价差确实会变大。我建议用动态阈值,比如基于历史数据的3倍标准差。

3.3 缺失值处理:别让数据断档

Tick数据缺失是常态。原因很多:网络抖动、交易所撮合暂停、数据商缓存问题。但你的策略不能因为数据缺失就罢工。

3.3.1 缺失的类型

  • 单点缺失:某一条数据丢了
  • 连续缺失:几秒甚至几分钟没有数据
  • 开盘/收盘缺失:集合竞价阶段数据不完整

3.3.2 处理方法

我个人习惯分情况处理:

缺失类型 处理方法 适用场景
单点缺失 前向填充(ffill) 价格变化不大时
连续缺失(<1秒) 线性插值 波动率计算需要连续数据
连续缺失(>1秒) 标记为无效,跳过 避免引入错误信息
开盘前30秒 使用前一日收盘价 做市商需要基准价

说白了,缺失值处理的核心原则是:宁可缺失,不要乱填。你想想看,如果连续缺失5秒,你用插值填了一堆假数据进去,策略基于这些假数据做决策,那结果可想而知。

我的经验:对于做市策略,我建议在缺失超过500毫秒时直接暂停报价。等数据恢复后再重新计算。虽然会损失一些交易机会,但比报错价格强得多。

3.4 知识体系总览

下面这张图,是我做数据预处理时的完整流程。你可以把它当作一个检查清单:

Tick级数据预处理流程 数据获取 交易所直连 / 第三方 / 券商API 数据清洗 去重 / 去异常 / 去倒挂 缺失值处理 填充 / 插值 / 跳过 检查:买卖价倒挂、价格范围、时间戳 检查:重复数据、零值、负值 判断:单点缺失 / 连续缺失 / 开盘缺失 干净可用的Tick数据 用于定价、波动率计算、做市决策 注意:每一步都需要做日志记录,方便回溯问题 核心原则 宁可缺失,不要乱填 | 清洗规则要动态 | 实盘前必须做回测验证

3.5 实战中的几个坑

最后,分享几个我踩过的坑,希望能帮你省点时间:

  • 坑一:不要相信数据商的时间戳。我遇到过某数据商的时间戳比交易所慢了200毫秒。解决办法是拿自己的系统时间做交叉验证。
  • 坑二:期权合约会到期。如果你不做合约映射,数据里会出现大量过期合约的Tick,白白浪费存储和计算资源。
  • 坑三:Tick数据量巨大。一天的数据可能几个G。我建议用Parquet格式存储,比CSV压缩率高5倍,读取速度也快。

一句话总结:数据预处理不是技术活,是态度活。你花多少心思在数据上,策略就给你多少回报。


公众号:蓝海资料掘金营,微信deep3321