3. 暗池数据获取:数据源介绍、解析与存储

做暗池交易,第一步就是搞到数据。这活儿看着简单,其实坑特别多。我刚开始接触暗池数据时,以为跟普通行情一样,找个API一拉就完事了。结果呢?数据格式五花八门,时间戳对不上,还有一堆缺失值等着你。今天咱们就把这块彻底捋清楚。

3.1 数据源介绍:三大主流渠道

暗池数据不像交易所的Level 2数据那么好拿。目前主流的数据源有三个,我一个个说。

3.1.1 FINRA(美国金融业监管局)

FINRA是官方渠道,数据最权威。它提供的是汇总后的暗池交易数据,不是逐笔的。说白了,你只能看到某个时间段内,某只股票在暗池里成交了多少笔、总金额多少,看不到每一笔的细节。

我个人习惯用FINRA的OTC(场外交易)数据,因为它覆盖了大部分暗池。不过要注意,FINRA的数据有延迟——通常是T+1,也就是今天只能看到昨天的数据。做实时策略的朋友,这个渠道就不太够用了。

关键点:FINRA数据免费,但粒度粗。适合做盘后分析,不适合高频。

3.1.2 TAQ(交易与报价数据)

TAQ是交易所直接提供的逐笔交易数据。它记录了每一笔成交的时间、价格、数量,以及买卖方向。这个数据精度高,但价格不便宜。我记得一套NYSE的TAQ数据,一年下来要几万美金。

TAQ里有个字段叫「交易条件码」,这个特别重要。比如条件码是「F」表示场内交易,「O」表示场外交易。暗池交易通常标记为「O」或「D」。我在项目中遇到过,有人没仔细看条件码,把场内交易当暗池数据用了,结果回测结果完全失真。

避坑指南:TAQ数据量巨大。一天的数据可能几个GB。你想想看,全美几千只股票,每只股票每秒可能成交几十笔,一天下来数据量能不大吗?存储和解析都是挑战。

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 数据清洗与预处理:脏数据是常态

数据拿到手,别急着用。先清洗。我总结了三步走:

  1. 去重:同一个数据源可能重复推送。按时间戳+股票代码+价格去重。
  2. 补缺失:有些字段可能为空。比如TAQ的买卖方向,有时候是空值。我一般用前一条数据填充,或者直接丢弃。
  3. 对齐时间:不同数据源的时间戳精度不同。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'])
注意:Parquet文件不支持追加写入。如果你要增量更新,得用其他方案。比如每天生成一个新文件,或者用Delta Lake这种支持ACID的存储格式。

3.5 知识体系总览

下面这张图,把本章的核心逻辑串起来了。你一看就明白数据从哪来、怎么处理、存到哪。

暗池数据获取与处理流程 数据源 FINRA / TAQ / 自建节点 格式解析 CSV / 二进制 / Protobuf 清洗与预处理 去重 / 补缺失 / 对齐时间 数据存储方案 CSV / Parquet / ClickHouse / InfluxDB 输出:清洗后的暗池交易数据 图:暗池数据从采集到存储的完整链路

说白了,暗池数据获取就是这三步:找对源、解对格式、存对地方。每一步都有坑,但踩过一次就记住了。我刚开始做的时候,光解析TAQ二进制格式就花了一周。后来发现用现成库,十分钟搞定。所以别重复造轮子,多看看社区有什么好工具。

核心总结:
  • FINRA数据免费但粒度粗,适合盘后分析
  • TAQ数据精度高但贵,适合中低频策略
  • 自建节点门槛高,但数据最实时
  • 清洗时先处理缺失值再去重
  • 存储推荐Parquet(离线)或ClickHouse(实时)

专注资料整理