3、数据格式标准化:CSV、Parquet、HDF5格式对比、字段定义与元数据管理

做Tick级回测,数据格式选不对,后面全白费。我见过太多团队,一开始图省事用CSV,结果回测跑起来慢得像蜗牛,最后不得不返工重写整个数据管道。今天咱们就把这事聊透。

3.1 三种主流格式:CSV、Parquet、HDF5

先说结论:CSV适合小规模探索,Parquet适合大规模分析,HDF5适合高频实时写入。但具体怎么选,得看你的场景。

3.1.1 CSV——最熟悉的陌生人

CSV的好处是简单,任何工具都能打开。但Tick数据量巨大,一天几千万条,CSV的缺点就暴露了:

  • 存储膨胀:文本存储,数字转字符串,体积比二进制大3-5倍
  • 读取慢:必须全量解析,没法只读某几列
  • 无类型信息:时间戳读进来可能是字符串,还得手动转
⚠️ 避坑指南:我曾经用CSV存了3个月的Tick数据,结果一个简单的“查询某只股票某天的所有Tick”查询,跑了整整40分钟。后来换成Parquet,同样的查询只要8秒。

3.1.2 Parquet——列式存储的王者

Parquet是我个人最推荐的回测数据格式。它有几个杀手锏:

  • 列式压缩:只读需要的列,IO量大幅减少
  • 谓词下推:查询时先过滤,再读取,效率极高
  • Schema自带:字段类型、嵌套结构都写在文件里

举个例子,你只想看某只股票14:30到15:00的成交价和成交量。用Parquet,它先读时间戳列过滤出时间范围,再读价格和成交量列。CSV呢?得把整行数据全读进来再过滤。差距就在这里。

3.1.3 HDF5——高性能写入的利器

HDF5适合做实时数据采集。它的特点是:

  • 写入极快:追加写入几乎不损耗性能
  • 支持多维数组:天然适合存储矩阵、时间序列
  • 元数据丰富:可以在文件里存任意属性

但HDF5有个坑——并发写入容易损坏。我在项目中遇到过,多个进程同时写同一个HDF5文件,结果文件直接打不开了。所以生产环境一定要做好锁机制。

3.1.4 格式对比一览

特性 CSV Parquet HDF5
存储效率 低(文本) 高(列式压缩) 高(二进制)
读取速度 慢(全量扫描) 快(列裁剪+谓词下推) 快(直接寻址)
写入速度 中等 中等(需编码) 快(追加模式)
并发安全 差(需锁文件) 好(不可变文件) 差(单写多读)
跨语言支持 极好
适用场景 小数据、调试 大规模分析、回测 实时采集、科学计算

3.2 字段定义:Tick数据的核心骨架

不管用什么格式,字段定义必须统一。我总结了一套经过实战检验的字段标准:

3.2.1 核心字段

  • timestamp:纳秒级时间戳,统一用UTC,避免时区问题
  • symbol:股票代码,建议用字符串,别用数字
  • price:成交价,用float64,别用float32——精度不够
  • volume:成交量,用int64,别用int32——大单会溢出
  • side:买卖方向,用枚举或int8(0=买,1=卖)

3.2.2 买卖盘口字段

做Tick回测,光有成交数据不够,盘口数据才是精华。我建议至少包含:

  • bid_price_1 ~ bid_price_5:买一到买五价格
  • bid_volume_1 ~ bid_volume_5:买一到买五挂单量
  • ask_price_1 ~ ask_price_5:卖一到卖五价格
  • ask_volume_1 ~ ask_volume_5:卖一到卖五挂单量
💡 小技巧:盘口字段用固定长度数组存储,比用嵌套结构快得多。比如Parquet里直接定义10个float64列,比用List类型快3倍以上。

3.2.3 元数据字段

这些字段不参与回测计算,但能帮你快速定位问题:

  • exchange:交易所代码
  • data_source:数据来源(如L1、L2、模拟)
  • quality_flag:数据质量标记(0=正常,1=异常,2=插值)
  • version:数据版本号,方便回滚

3.3 元数据管理:让数据可追溯

数据格式和字段定义好了,还得管好元数据。说白了,元数据就是数据的“身份证”。

3.3.1 文件级元数据

每个数据文件都应该包含:

  • 生成时间
  • 数据时间范围
  • 包含的股票列表
  • 字段版本号
  • 校验和(防止文件损坏)

Parquet和HDF5都支持在文件头部写入元数据。CSV不行,得单独建一个元数据文件。这也是我为什么不太推荐CSV的原因之一。

3.3.2 数据库级元数据

当数据量大了,文件级元数据不够用。我建议建一个轻量级的元数据库(比如SQLite),记录:

  • 每个文件的路径、大小、行数
  • 数据的时间跨度
  • 数据质量统计(缺失率、异常率)
  • 处理流水线(谁生成的、用什么参数)
🔑 核心原则:元数据要跟数据分离存储,但必须能通过唯一ID关联。这样即使数据文件损坏,元数据还能帮你快速定位问题。

3.4 知识体系总览

下面这张图,把数据格式、字段定义、元数据管理的关系串起来了。你想想看,从原始数据到回测引擎,中间经历了什么?

Tick级回测数据存储与检索体系 原始Tick数据 交易所L1/L2行情 · 模拟生成数据 · 历史回放数据 字段:timestamp, symbol, price, volume, bid/ask, side 数据格式标准化 CSV 小规模调试 Parquet 大规模分析 HDF5 实时写入 字段定义与元数据管理 核心字段 + 盘口字段 + 元数据字段 文件级元数据 + 数据库级元数据 回测引擎 · 高性能检索

嗯,这张图把整个流程串起来了。从原始数据到格式选择,再到字段定义和元数据管理,最后喂给回测引擎。每一步都环环相扣。

3.5 实战建议

最后给几个实在的建议:

  • 小项目用Parquet就够了,别折腾HDF5,除非你有实时写入需求
  • 字段命名统一用snake_case,别混用驼峰和下划线,否则后期处理很痛苦
  • 时间戳一定要带时区信息,我吃过亏——某次回测因为时区没对齐,策略信号全偏了
  • 元数据要自动化生成,别手动维护,人总会犯错
📌 一句话总结:数据格式选Parquet,字段定义标准化,元数据自动化管理。这三件事做好了,Tick级回测的数据基础就稳了。

专注资料整理