3、数据格式标准化:CSV、Parquet、HDF5格式对比、字段定义与元数据管理
做Tick级回测,数据格式选不对,后面全白费。我见过太多团队,一开始图省事用CSV,结果回测跑起来慢得像蜗牛,最后不得不返工重写整个数据管道。今天咱们就把这事聊透。
3.1 三种主流格式:CSV、Parquet、HDF5
先说结论:CSV适合小规模探索,Parquet适合大规模分析,HDF5适合高频实时写入。但具体怎么选,得看你的场景。
3.1.1 CSV——最熟悉的陌生人
CSV的好处是简单,任何工具都能打开。但Tick数据量巨大,一天几千万条,CSV的缺点就暴露了:
- 存储膨胀:文本存储,数字转字符串,体积比二进制大3-5倍
- 读取慢:必须全量解析,没法只读某几列
- 无类型信息:时间戳读进来可能是字符串,还得手动转
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:卖一到卖五挂单量
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),记录:
- 每个文件的路径、大小、行数
- 数据的时间跨度
- 数据质量统计(缺失率、异常率)
- 处理流水线(谁生成的、用什么参数)
3.4 知识体系总览
下面这张图,把数据格式、字段定义、元数据管理的关系串起来了。你想想看,从原始数据到回测引擎,中间经历了什么?
嗯,这张图把整个流程串起来了。从原始数据到格式选择,再到字段定义和元数据管理,最后喂给回测引擎。每一步都环环相扣。
3.5 实战建议
最后给几个实在的建议:
- 小项目用Parquet就够了,别折腾HDF5,除非你有实时写入需求
- 字段命名统一用snake_case,别混用驼峰和下划线,否则后期处理很痛苦
- 时间戳一定要带时区信息,我吃过亏——某次回测因为时区没对齐,策略信号全偏了
- 元数据要自动化生成,别手动维护,人总会犯错