4、Tick数据存储:CSV格式存储、Parquet格式存储、HDF5格式存储、数据库存储

数据去重和排序搞定了,接下来就是存的问题。

说实话,Tick数据存储这块,我踩过的坑比写过的代码还多。早期做高频回测时,一个月的Tick数据就能把硬盘撑爆,加载一次要等半小时。后来慢慢摸索出几种主流方案,今天一次性讲清楚。

4.1 CSV格式存储——最直接,但别太依赖

CSV是大家最熟悉的格式。说白了就是逗号分隔的文本文件。我刚开始做量化时,所有Tick数据都存CSV,因为简单、直观、任何工具都能打开。

优点:

  • 人类可读,Excel直接打开看
  • 跨平台兼容,Linux/Windows/Mac通吃
  • 生成和解析代码极简

缺点也很明显:

  • 文件体积大——同样的数据,CSV比Parquet大3-5倍
  • 读写速度慢——尤其是几千万行级别的Tick数据
  • 不支持数据类型——所有字段都是字符串,每次要自己转
  • 没有索引——查询某一天的Tick数据,得全文件扫描
⚠️ 我曾经踩过的坑: 有一次存了3个月的股指期货Tick数据,单个CSV文件超过10GB。用Pandas读取时直接内存溢出。后来不得不拆成每天一个文件,但查询跨天数据时又得写一堆拼接逻辑。所以,CSV只适合小规模数据或临时调试。
# 写入CSV示例
import pandas as pd

tick_data = pd.DataFrame({
    'timestamp': ['2024-01-01 09:30:00.123', '2024-01-01 09:30:00.456'],
    'symbol': ['IF2401', 'IF2401'],
    'price': [3500.0, 3501.5],
    'volume': [10, 15],
    'direction': ['buy', 'sell']
})

tick_data.to_csv('tick_data.csv', index=False)

# 读取CSV
df = pd.read_csv('tick_data.csv', parse_dates=['timestamp'])
print(df.head())

4.2 Parquet格式存储——我目前的主力方案

Parquet是列式存储格式。什么意思呢?传统CSV是一行一行存的,Parquet是一列一列存的。你想想看,做量化分析时,我们经常只需要某几列(比如价格和成交量),列式存储就能只读取需要的列,速度飞快。

核心优势:

  • 压缩率高——同样的Tick数据,Parquet体积只有CSV的20%-30%
  • 读取速度快——只读需要的列,IO量大幅减少
  • 自带Schema——每个字段的类型都明确,不用再转换
  • 支持谓词下推——比如只读取某一天的Tick数据,Parquet能在文件层面过滤
💡 我个人习惯: 所有超过100万行的Tick数据,一律用Parquet。配合PyArrow或FastParquet库,读写速度比Pandas原生快5-10倍。
# Parquet读写示例
import pandas as pd
import pyarrow.parquet as pq

# 写入Parquet
tick_data.to_parquet('tick_data.parquet', compression='snappy')

# 读取Parquet——只读需要的列
df = pd.read_parquet('tick_data.parquet', columns=['timestamp', 'price', 'volume'])

# 使用PyArrow直接读取,速度更快
table = pq.read_table('tick_data.parquet', columns=['timestamp', 'price'])
print(table.to_pandas().head())

4.3 HDF5格式存储——适合大规模时间序列

HDF5是层次化数据格式。我在做期权高频策略时,需要同时存储Tick数据、分钟数据、日线数据,还要存一些中间计算结果。HDF5的树状结构正好满足这种需求。

特点:

  • 支持多维数组——可以存矩阵、图像等复杂数据
  • 内部目录结构——一个文件就是一个数据库
  • 支持压缩和分块——大文件也能高效读写
  • 跨语言支持——Python、C++、Java、MATLAB都能用
📌 避坑指南: 我曾经用HDF5存了5年的Tick数据,结果文件超过50GB。后来发现HDF5在单文件过大时,写入性能会急剧下降。建议每个HDF5文件控制在10GB以内,或者按年份拆分。
# HDF5读写示例
import pandas as pd
import h5py

# 使用Pandas直接写入HDF5
tick_data.to_hdf('tick_data.h5', key='tick_20240101', mode='a')

# 读取HDF5
df = pd.read_hdf('tick_data.h5', key='tick_20240101')

# 使用h5py更底层操作
with h5py.File('tick_data.h5', 'r') as f:
    # 查看文件内部结构
    print(list(f.keys()))
    # 读取数据集
    dataset = f['tick_20240101']
    print(dataset.shape)

4.4 数据库存储——生产环境的标配

如果你做的是实盘交易系统,数据库几乎是唯一选择。为什么?因为数据库提供了事务、并发控制、权限管理、备份恢复等企业级功能。

常见选择:

数据库 适用场景 读写性能 我的评价
PostgreSQL + TimescaleDB 中小规模Tick数据(<1亿条/天) 写入2万条/秒,读取快 我最常用的方案,稳定可靠
ClickHouse 大规模Tick数据(>1亿条/天) 写入10万条/秒,分析极快 适合做数据分析,不适合频繁更新
InfluxDB 时序数据专用 写入5万条/秒,查询灵活 适合监控类场景,Tick数据也能用
MongoDB 灵活Schema的Tick数据 写入3万条/秒,读取一般 适合字段不固定的场景
💡 我建议: 如果你刚开始做Tick数据存储,先用Parquet文件存历史数据,用PostgreSQL+TimescaleDB存实时数据。等数据量上来了,再考虑ClickHouse。别一上来就上分布式数据库,维护成本太高。
# PostgreSQL + TimescaleDB 示例
import psycopg2
from psycopg2.extras import execute_values

conn = psycopg2.connect(
    host='localhost',
    database='tick_db',
    user='quant',
    password='your_password'
)
cur = conn.cursor()

# 创建超表(TimescaleDB特性)
cur.execute("""
    CREATE TABLE tick_data (
        time TIMESTAMPTZ NOT NULL,
        symbol TEXT NOT NULL,
        price DOUBLE PRECISION,
        volume INTEGER,
        direction TEXT
    );
""")
cur.execute("SELECT create_hypertable('tick_data', 'time');")

# 批量插入Tick数据
tick_records = [
    ('2024-01-01 09:30:00.123+08', 'IF2401', 3500.0, 10, 'buy'),
    ('2024-01-01 09:30:00.456+08', 'IF2401', 3501.5, 15, 'sell')
]

execute_values(cur, 
    "INSERT INTO tick_data (time, symbol, price, volume, direction) VALUES %s",
    tick_records
)
conn.commit()

# 查询某一天的Tick数据
cur.execute("""
    SELECT * FROM tick_data 
    WHERE time >= '2024-01-01' AND time < '2024-01-02'
    AND symbol = 'IF2401'
    ORDER BY time
""")
rows = cur.fetchall()
print(f"查询到 {len(rows)} 条Tick数据")

4.5 四种方案对比总结

嗯,这里我直接给结论吧。四种方案各有千秋,没有银弹。

维度 CSV Parquet HDF5 数据库
存储效率 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
读取速度 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
写入速度 ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
查询灵活性 ⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
并发支持
适合场景 临时调试 历史数据存储 复杂数据结构 生产环境
📌 我的最终建议: 历史Tick数据用Parquet存,实时Tick数据用TimescaleDB存。两者之间通过ETL流程同步。这样既保证了历史数据的压缩率和读取速度,又保证了实时数据的写入和查询性能。我在实盘系统中就是这么干的,跑了两年多没出过问题。
Tick数据存储方案选择流程图 Tick数据源 数据量? 小规模 CSV 中等规模 Parquet / HDF5 大规模 数据库 是否需要 复杂查询? Parquet HDF5 根据数据规模和查询需求选择合适的存储方案

好了,四种存储方案都讲完了。CSV适合临时用,Parquet是我最推荐的离线存储方案,HDF5适合复杂数据结构,数据库是生产环境标配。你根据自己实际场景选就行。

专注资料整理