3. 暗池数据获取:数据源介绍、解析与存储
做暗池交易,第一步就是搞到数据。这活儿看着简单,其实坑特别多。我刚开始接触暗池数据时,以为跟普通行情一样,找个API一拉就完事了。结果呢?数据格式五花八门,时间戳对不上,还有一堆缺失值等着你。今天咱们就把这块彻底捋清楚。
3.1 数据源介绍:三大主流渠道
暗池数据不像交易所的Level 2数据那么好拿。目前主流的数据源有三个,我一个个说。
3.1.1 FINRA(美国金融业监管局)
FINRA是官方渠道,数据最权威。它提供的是汇总后的暗池交易数据,不是逐笔的。说白了,你只能看到某个时间段内,某只股票在暗池里成交了多少笔、总金额多少,看不到每一笔的细节。
我个人习惯用FINRA的OTC(场外交易)数据,因为它覆盖了大部分暗池。不过要注意,FINRA的数据有延迟——通常是T+1,也就是今天只能看到昨天的数据。做实时策略的朋友,这个渠道就不太够用了。
3.1.2 TAQ(交易与报价数据)
TAQ是交易所直接提供的逐笔交易数据。它记录了每一笔成交的时间、价格、数量,以及买卖方向。这个数据精度高,但价格不便宜。我记得一套NYSE的TAQ数据,一年下来要几万美金。
TAQ里有个字段叫「交易条件码」,这个特别重要。比如条件码是「F」表示场内交易,「O」表示场外交易。暗池交易通常标记为「O」或「D」。我在项目中遇到过,有人没仔细看条件码,把场内交易当暗池数据用了,结果回测结果完全失真。
3.1.3 自建节点
如果你有资源,可以自己搭建数据采集节点。比如接入交易所的原始数据流,或者跟暗池运营商合作。这个门槛最高,但数据最实时、最完整。
我曾经帮一家对冲基金搭建过自建节点。他们跟某家暗池签了协议,能拿到逐笔的订单流数据。那数据量,一天就几百GB。不过好处是,你能看到订单的完整生命周期——从进入暗池到成交或撤销。这对做信号捕捉来说,简直是金矿。
3.2 数据格式解析:别被字段搞晕
不同数据源的格式不一样。我整理了一个对比表,你一看就明白。
| 数据源 | 常见格式 | 关键字段 | 时间精度 |
|---|---|---|---|
| FINRA | CSV、XML | 股票代码、成交时间、成交量、成交金额、加权均价 | 秒级 |
| TAQ | 二进制、CSV | 股票代码、成交时间、成交价、成交量、交易条件码、买卖方向 | 毫秒级 |
| 自建节点 | Protobuf、JSON | 订单ID、时间戳、价格、数量、订单类型、暗池ID | 微秒级 |
嗯,这里要注意。FINRA的CSV格式看起来简单,但它的时间戳是东部时间,而且不带时区信息。你如果直接用,跟其他数据源对不上。我一般会先转成UTC,再统一处理。
TAQ的二进制格式比较麻烦。它用的是NYSE自己的编码方式,每个字段的偏移量都是固定的。解析时得按字节读,错一个位数据就全乱了。我建议用现成的解析库,比如Python的taq-reader,别自己手写解析器。
# 示例:用Python解析TAQ数据
import taq_reader
# 读取一天的TAQ数据
data = taq_reader.load('taq_20250101.bin')
# 筛选暗池交易(条件码为'O'或'D')
dark_pool_trades = data[data['condition'].isin(['O', 'D'])]
print(f"暗池交易笔数:{len(dark_pool_trades)}")
3.3 数据清洗与预处理:脏数据是常态
数据拿到手,别急着用。先清洗。我总结了三步走:
- 去重:同一个数据源可能重复推送。按时间戳+股票代码+价格去重。
- 补缺失:有些字段可能为空。比如TAQ的买卖方向,有时候是空值。我一般用前一条数据填充,或者直接丢弃。
- 对齐时间:不同数据源的时间戳精度不同。FINRA是秒级,TAQ是毫秒级。做分析时,得统一到同一个时间粒度。
举个例子。有一次我处理FINRA数据,发现某只股票在某个时间段的成交量特别大,但价格没怎么动。一开始以为是暗池有大单,后来一查,原来是数据重复了——同一个交易被记录了两次。去重之后,数据就正常了。
3.4 数据存储方案:选对工具省一半力气
暗池数据量大,存储是个问题。我试过几种方案,给你对比一下。
| 存储方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| CSV文件 | 小规模、一次性分析 | 简单、通用 | 查询慢、占用空间大 |
| Parquet | 中等规模、列式分析 | 压缩率高、查询快 | 需要特定库支持 |
| ClickHouse | 大规模、实时查询 | 极速查询、支持SQL | 运维成本高 |
| InfluxDB | 时序数据、高频场景 | 原生支持时间序列 | 不适合复杂关联查询 |
我个人习惯用Parquet做离线存储。它比CSV小很多,而且读取速度快。比如一天的TAQ数据,CSV可能要5GB,Parquet压缩后不到1GB。查询时,只需要读取需要的列,不用全量加载。
如果是实时策略,我会用ClickHouse。它支持毫秒级查询,而且能直接对接Kafka,实现流式写入。不过运维起来确实麻烦,得有人专门盯着。
# 示例:将清洗后的数据保存为Parquet
import pandas as pd
# 假设df是清洗后的DataFrame
df.to_parquet('dark_pool_20250101.parquet', compression='snappy')
# 读取时只加载需要的列
df = pd.read_parquet('dark_pool_20250101.parquet', columns=['time', 'symbol', 'price', 'volume'])
3.5 知识体系总览
下面这张图,把本章的核心逻辑串起来了。你一看就明白数据从哪来、怎么处理、存到哪。
说白了,暗池数据获取就是这三步:找对源、解对格式、存对地方。每一步都有坑,但踩过一次就记住了。我刚开始做的时候,光解析TAQ二进制格式就花了一周。后来发现用现成库,十分钟搞定。所以别重复造轮子,多看看社区有什么好工具。
- FINRA数据免费但粒度粗,适合盘后分析
- TAQ数据精度高但贵,适合中低频策略
- 自建节点门槛高,但数据最实时
- 清洗时先处理缺失值再去重
- 存储推荐Parquet(离线)或ClickHouse(实时)