作者:wld
场景:设计 · 基于真实行情的轻量级货币(贵金属/外汇)交易平台原型
目标:在有限资源(mac studio m1 max 64G开发机)下,构建高性能、可扩展的时序数据处理管道
引言:为什么时序数据库是量化系统的核心?
本人之前在前东家研发量化系统时,大量使用 mongodb和 mysql,虽然容易上手,但是真的慢。固而有了此篇内容。
在构建一个支持实时行情接入、技术指标计算、回测验证的货币交易平台原型时,我们很快意识到:数据存储引擎的选择,直接决定了系统的性能上限与开发效率。
传统关系型数据库(如 MySQL)在高频写入下容易成为瓶颈;文档数据库(如 MongoDB)虽灵活,却缺乏对时间窗口、滑动聚合等操作的原生支持;而通用分析引擎又难以兼顾写入吞吐与低延迟查询。
于是,我们将目光投向四款主流时序/分析型数据库:
- TDengine(国产高性能时序数据库)
- TimescaleDB(PostgreSQL 时序扩展)
- DuckDB(嵌入式向量化分析引擎)
- MongoDB(作为对比项)
本文将从macOS Apple Silicon 开发环境适配、时序指标生成能力、资源消耗、与量化栈集成度四个维度,分享我们在设计中的实测对比与最终选型逻辑。
一、测试环境与数据模型
硬件与软件
- 设备:mac studio m1 max (64GB RAM)
- 系统:macOS Sonoma(ARM64)
- 数据规模:模拟 XAUUSD(黄金/美元)1 分钟 K 线,共 50 万条(覆盖 1 年)
- 指标需求:SMA(20)、波动率(20)、RSI(14)
数据模型
-- 结构化时序表(所有数据库均按此逻辑建模)timestamp:DATETIME-- 时间戳symbol:VARCHAR-- 品种(如 'XAUUSD')open:DOUBLEhigh:DOUBLElow:DOUBLEclose:DOUBLEvolume:BIGINT二、四大数据库深度对比
1. macOS ARM 支持与安装体验
| 数据库 | 安装方式 | 启动复杂度 | 是否原生 ARM |
|---|---|---|---|
| TDengine | brew install tdengine | ⭐(一键启动) | ✅ |
| TimescaleDB | brew install timescaledb | ⭐⭐(需配置 PG) | ✅ |
| DuckDB | pip install duckdb | ⭐(无服务) | ✅✅ |
| MongoDB | brew install mongodb-community | ⭐⭐ | ✅ |
💡DuckDB 和 TDengine 对 Apple Silicon 开发者最友好——无需后台服务,零配置即可运行。
2. 时序指标生成能力实测
我们以计算 20 日 SMA 与滚动波动率为例,对比 SQL 表达力与执行效率:
✅ TDengine(简洁高效)
SELECTts,close,MOVING_AVG(close,20)ASsma_20,STDDEV(close)OVER(ORDERBYtsINTERVAL'20'ROWS)ASvol_20FROMxauusd;- 耗时:152 ms
- 优势:专用函数 + 列式存储,I/O 极小
✅ TimescaleDB(标准 SQL + 扩展)
SELECTtime,close,AVG(close)OVER(ORDERBYtimeROWS19PRECEDING)ASsma_20,STDDEV(close)OVER(ORDERBYtimeROWS19PRECEDING)ASvol_20FROMticks;- 耗时:298 ms
- 优势:兼容 PostgreSQL 生态,
timescaledb_toolkit提供 RSI/MACD
✅ DuckDB(向量化之王)
-- 与上述 TimescaleDB 语法完全一致SELECT...FROMread_parquet('xauusd.parquet');- 耗时:78 ms(最快!)
- 优势:自动启用 ARM NEON 指令,内存计算无网络开销
❌ MongoDB(冗长低效)
db.ticks.aggregate([{$sort:{ts:1}},{$setWindowFields:{output:{prices:{$push:"$close",window:{documents:[-19,0]}}}}},{$addFields:{vol_20:{$stdDevPop:"$prices"}}}])- 耗时:2150 ms
- 劣势:非向量化、内存拷贝频繁、表达复杂
📊性能排序(快 → 慢):DuckDB > TDengine > TimescaleDB >> MongoDB
3. 写入吞吐与存储效率
| 数据库 | 写入 50 万条耗时 | 压缩后磁盘占用 | 适合场景 |
|---|---|---|---|
| TDengine | 3.2 秒 | 12 MB | 高频行情写入 |
| TimescaleDB | 8.7 秒 | 45 MB | 中低频 + 复杂查询 |
| DuckDB | N/A(只读分析) | 28 MB(Parquet) | 离线回测 |
| MongoDB | 6.1 秒 | 68 MB | 非结构化事件 |
🔑TDengine 凭借列式存储 + 自动分片,在写入与压缩上全面领先。
4. 与 Python 量化栈集成
| 数据库 | Python 驱动 | Pandas 集成 | 示例代码简洁度 |
|---|---|---|---|
| TDengine | taospy | ✅(read_sql) | ⭐⭐ |
| TimescaleDB | psycopg2 | ✅ | ⭐⭐ |
| DuckDB | 内置 | ✅✅(原生) | ⭐ |
| MongoDB | pymongo | ⚠️(需转 dict) | ⭐⭐⭐ |
# DuckDB:一行读取 Parquet 并计算importduckdb df=duckdb.sql(""" SELECT *, AVG(close) OVER (ROWS 19 PRECEDING) AS sma_20 FROM 'xauusd.parquet' """).df()💡DuckDB 的嵌入式特性使其成为 Jupyter Notebook 回测的首选。
三、设计架构:混合数据库方案
基于以上对比,我们采用“分层存储 + 专用引擎”架构:
为什么这样设计?
- TDengine:承担7×24 小时高频写入,利用其高吞吐、高压缩特性;
- DuckDB:负责离线回测与因子挖掘,发挥其向量化计算优势;
- 避免单一数据库妥协:既不牺牲写入性能,也不降低分析速度。
🎓该方案成本极低:全程开源免费,仅需一台云服务器(约 ¥300/月)部署 TDengine,本地 Mac 完成分析。如果使用 mongodb 200gb的金融时序数据,在TDengine上存储则只需要 50gb 左右,那在数据恢复和迁移上完胜 mongodb,且存储成本极低,不知是否会选择此技术方案呢!!
四、避坑指南:给后来者的建议
不要用 MongoDB 存储结构化行情
→ 灵活 schema 在 OHLC 场景中毫无价值,反而拖慢分析。DuckDB 不适合实时写入
→ 它是分析引擎,不是存储引擎。用 Parquet 作为中间格式桥接。TDengine 的“超级表”是关键
CREATESTABLE ticks(...)TAGS(symbolBINARY(10));-- 按品种自动分表→ 避免手动管理多张表,提升查询效率。
macOS ARM 用户优先选择 Homebrew 安装
→ 确保获得原生 ARM64 二进制,避免 Rosetta 2 性能损失。
结语:选对工具,事半功倍
在毕业设计中,我们曾尝试用单一数据库解决所有问题,结果要么写入卡顿,要么回测缓慢。直到采用TDengine + DuckDB 混合架构,才真正实现:
- 行情写入:10万点/秒,CPU 占用 <20%
- 因子回测:1年数据 SMA 计算 <100ms
- 开发体验:Python 脚本 50 行完成端到端 pipeline
时序数据库没有“最好”,只有“最合适”。希望本文能为你的量化系统或毕业设计提供有价值的参考。
附录:
- 测试数据集:XAUUSD 1分钟 K 线(2023–2024)
- 环境配置脚本:一键安装 ARM 兼容版数据库
本文所有测试均在 macOS Sonoma + M1 Max 环境下完成,代码已适配国内镜像源。
点赞超 1 万,给出评测源码。