2. 数据源与格式:常见Tick数据源与存储格式对比

做高频回测,第一步就是搞数据。这一步要是没走对,后面全白搭。我见过太多人花大把时间调策略,最后发现是数据本身有问题——那种感觉,真的挺崩溃的。

今天咱们就聊聊Tick数据的来源,以及怎么存、怎么读效率最高。说白了,就是搞清楚「数据从哪来」和「数据怎么放」这两个问题。

2.1 常见Tick数据源

Tick数据的来源,大致分三类:交易所直连、券商接口、第三方数据商。各有各的优缺点,我一个个说。

2.1.1 交易所直连

这是最原始、最干净的数据源。像上交所、深交所、中金所,都会提供Level-2行情数据。我早年做期货高频时,直接拉过中金所的Tick数据,那叫一个爽——毫秒级精度,没有中间商赚差价。

  • 优点:数据最完整,延迟最低,没有第三方加工痕迹
  • 缺点:贵。非常贵。而且接口复杂,需要专线,一般人搞不定
  • 适用场景:机构级高频策略,或者你钱多任性
注意:交易所直连的数据通常是二进制格式,需要自己解析。我当年第一次解析上交所的STEP协议,折腾了整整两天。嗯,这个坑你们可以绕过去——直接用现成的解析库就好。

2.1.2 券商接口

大部分个人交易者接触到的,其实是券商提供的行情数据。比如你用的通达信、同花顺、QMT这些,背后都是券商在转发交易所的数据。

  • 优点:门槛低,开户就能用,很多还免费
  • 缺点:数据有延迟,而且券商可能会做「数据清洗」——说白了就是过滤掉一些他们认为「异常」的Tick。你想想看,这多危险?
  • 适用场景:策略开发初期,或者做低频回测

我个人习惯,用券商数据做初步验证可以,但真要跑实盘级别的回测,还是得找更靠谱的源。

2.1.3 第三方数据商

这是目前最主流的选择。像Wind、聚宽、米筐、Tushare这些,都提供历史Tick数据。还有一些国外的,比如Quandl、Polygon。

数据商 覆盖市场 数据精度 价格 我的评价
Wind A股、期货、期权 毫秒级 贵(机构价) 数据最全,但API有点老
聚宽 A股、期货 毫秒级 中等 适合量化,文档友好
米筐 A股、期货、美股 毫秒级 中等 回测平台不错
Tushare A股 秒级 免费/低 入门首选,但精度有限
我的建议:如果你刚开始做高频回测,先用Tushare或聚宽的数据跑通流程。等策略稳定了,再考虑买更高质量的数据。别一上来就砸钱,万一策略不行呢?

2.2 数据存储格式对比

数据拿到手了,怎么存?这问题看着简单,其实门道不少。我见过有人把几百G的Tick数据全塞进CSV里,结果每次回测光读数据就要半小时——这还玩个啥?

目前主流的格式有三种:CSV、Parquet、Arrow。咱们一个一个看。

2.2.1 CSV格式

CSV是最通用的格式,几乎任何工具都能打开。但说实话,它真的不适合高频数据。

# 一个典型的Tick CSV文件
timestamp,symbol,price,volume,side
2024-01-01 09:30:00.123,000001.SZ,10.25,100,B
2024-01-01 09:30:00.125,000001.SZ,10.26,200,S
2024-01-01 09:30:00.127,000001.SZ,10.25,150,B
...
  • 优点:人类可读,任何语言都能解析,调试方便
  • 缺点:文件巨大(文本存储),读写慢,没有压缩,不支持列式筛选
  • 适用场景:数据量小(百万行以内),或者做数据交换
避坑指南:我曾经用CSV存了一年的A股Tick数据,大概500G。结果每次回测光解析就要20分钟。后来换成Parquet,同样的数据压缩到80G,读取时间降到10秒。你说这差距大不大?

2.2.2 Parquet格式

Parquet是列式存储格式,专门为大数据场景设计的。现在几乎成了量化领域的标配。

# 用pandas读写Parquet
import pandas as pd

# 读取Parquet文件
df = pd.read_parquet('tick_data.parquet')

# 写入Parquet文件
df.to_parquet('tick_data.parquet', compression='snappy')
  • 优点:压缩率高(通常能压到CSV的1/5到1/10),读取速度快(列式存储,只读需要的列),支持复杂嵌套结构
  • 缺点:写入稍慢,不直观(不能直接文本打开看)
  • 适用场景:大规模Tick数据存储,高频回测
小技巧:用Parquet时,记得按日期分区存储。比如每天一个文件,这样回测时只需要加载对应日期的数据,速度能再快一个数量级。

2.2.3 Arrow格式

Arrow是这两年火起来的内存列式格式。它和Parquet最大的区别是:Parquet是磁盘格式,Arrow是内存格式。

# 用pyarrow操作Arrow格式
import pyarrow as pa
import pyarrow.parquet as pq

# 从Parquet读到Arrow Table
table = pq.read_table('tick_data.parquet')

# 直接操作Arrow数据
# 零拷贝,速度极快
filtered = table.filter(pa.compute.greater(table.column('price'), 10.0))
  • 优点:内存中零拷贝,跨语言共享数据(C++/Python/Java/Rust都能用),向量化计算极快
  • 缺点:占用内存大,不适合长期存储
  • 适用场景:高频回测时的内存数据交换,实时计算管道

2.3 三种格式对比总结

特性 CSV Parquet Arrow
存储类型 行式文本 列式二进制 列式内存
压缩率 无(或很低) 高(5-10倍) 中等
读取速度 极快
写入速度 中等
人类可读
跨语言支持 全支持 广泛支持 原生支持
推荐场景 小数据量/调试 磁盘存储/回测 内存计算/实时

2.4 我的推荐方案

说了这么多,到底怎么选?我个人的经验是这样的:

  1. 原始数据落地:用Parquet。压缩率高,读取快,适合长期保存
  2. 回测时加载:从Parquet读到Arrow。这样在内存里操作极快,而且可以跨语言共享
  3. 调试和检查:偶尔导出CSV。用Excel或者文本编辑器看一眼,确认数据没问题

你想想看,一套流程下来,数据从磁盘到内存再到计算,每一步都用最合适的格式。这才是做高频回测该有的态度。

核心要点:数据源选靠谱的第三方,存储格式用Parquet+Arrow组合。别在CSV上浪费时间,除非你只是做个小实验。
Tick数据全流程架构 数据源层 交易所直连 券商接口 第三方数据商 存储层 CSV(调试用) Parquet(磁盘存储) Arrow(内存计算) 应用层 高频回测引擎 实时交易系统 数据质量监控

这张图把整个流程串起来了。从数据源到存储再到应用,每一层都有对应的最佳实践。记住这个架构,后面咱们写代码的时候,每一步都会对应到这里。

最后说一句:数据格式的选择,本质上是在「空间」和「时间」之间做权衡。CSV省了你的思考时间,但浪费了你的机器时间。Parquet和Arrow正好反过来。做高频的,时间就是金钱,你懂的。