一、前言

做量化交易久了,数据会越积越多。实时行情、历史K线、Tick数据、回测结果、交易记录……这些数据如果都放在内存里,不仅占用资源,程序重启后还会丢失。

这时候就需要一个数据库来持久化存储数据。但数据库种类很多——SQLite、MySQL、PostgreSQL、InfluxDB、MongoDB……到底该选哪个?

本文从量化交易的实际需求出发,对比5种常用的数据存储方案,帮你找到最适合的那个。

本文将介绍:

  • 5种数据存储方案的特点
  • 各方案在量化场景下的表现
  • 选择建议与代码示例

二、量化数据存储的特殊需求

量化交易的数据存储有一些特殊需求:

需求 说明
时间序列为主 大部分数据都是时间序列(K线、Tick)
写入频繁 实时行情需要高频写入
查询速度快 回测和策略需要快速读取历史数据
数据量大 长期积累的数据量可能很大
简单易用 个人投资者不需要太复杂的方案

三、5种存储方案对比

3.1 SQLite —— 最简单的选择

定位:轻量级文件数据库,无需服务器

SQLite是最简单的数据库方案,数据存在一个文件里,不需要安装数据库服务器,Python内置支持。

优点

  • 零配置,开箱即用
  • 单文件,备份方便
  • 性能在小数据量时足够

缺点

  • 并发写入性能有限
  • 不适合大数据量(GB级别以上)
import sqlite3
import pandas as pd
from datetime import datetime

# 创建数据库
conn = sqlite3.connect("futures_data.db")

# 存储K线数据
df = pd.DataFrame({
    "datetime": pd.date_range("2025-01-01", periods=100, freq="1H"),
    "open": [3350 + i for i in range(100)],
    "high": [3360 + i for i in range(100)],
    "low": [3340 + i for i in range(100)],
    "close": [3355 + i for i in range(100)],
    "volume": [1000 + i*10 for i in range(100)]
})

df.to_sql("klines_rb", conn, if_exists="replace", index=False)

# 查询数据
query = "SELECT * FROM klines_rb WHERE datetime >= '2025-01-01 10:00:00'"
result = pd.read_sql(query, conn)
print(result.head())

conn.close()

适用场景

  • 个人投资者,数据量不大(< 1GB)
  • 单机运行,不需要多进程访问
  • 快速原型开发

3.2 PostgreSQL + TimescaleDB —— 专业级时序数据库

定位:关系型数据库 + 时序扩展

PostgreSQL是功能强大的关系型数据库,配合TimescaleDB扩展,专门优化了时序数据的存储和查询。

优点

  • 时序数据查询性能优秀
  • 支持SQL,学习成本低
  • 数据完整性保证好

缺点

  • 需要安装和配置数据库服务器
  • 资源占用较大
import psycopg2
import pandas as pd

# 连接数据库
conn = psycopg2.connect(
    host="localhost",
    database="futures",
    user="postgres",
    password="password"
)

# 创建时序表(TimescaleDB)
cursor = conn.cursor()
cursor.execute("""
    CREATE TABLE IF NOT EXISTS klines (
        time TIMESTAMPTZ NOT NULL,
        symbol VARCHAR(20) NOT NULL,
        open FLOAT,
        high FLOAT,
        low FLOAT,
        close FLOAT,
        volume BIGINT
    );
    
    SELECT create_hypertable('klines', 'time');
""")
conn.commit()

# 插入数据
df.to_sql("klines", conn, if_exists="append", index=False)

# 查询最近100根K线
query = """
    SELECT * FROM klines 
    WHERE symbol = 'SHFE.rb2510' 
    ORDER BY time DESC 
    LIMIT 100
"""
result = pd.read_sql(query, conn)

适用场景

  • 数据量大(GB到TB级别)
  • 需要复杂查询和分析
  • 多进程/多机器访问

3.3 InfluxDB —— 专为时序数据设计

定位:专业的时序数据库

InfluxDB是专门为时序数据设计的数据库,在写入和查询时序数据方面性能优异。

优点

  • 时序数据性能极佳
  • 自动数据压缩,节省空间
  • 支持数据保留策略(自动删除旧数据)

缺点

  • 学习曲线较陡(需要了解InfluxQL)
  • 不适合非时序数据
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS

# 连接InfluxDB
client = InfluxDBClient(
    url="http://localhost:8086",
    token="your-token",
    org="your-org"
)

write_api = client.write_api(write_options=SYNCHRONOUS)

# 写入K线数据
for _, row in df.iterrows():
    point = Point("klines") \
        .tag("symbol", "SHFE.rb2510") \
        .field("open", row["open"]) \
        .field("high", row["high"]) \
        .field("low", row["low"]) \
        .field("close", row["close"]) \
        .field("volume", row["volume"]) \
        .time(row["datetime"])
    write_api.write(bucket="futures", record=point)

# 查询数据
query = '''
    from(bucket: "futures")
        |> range(start: -7d)
        |> filter(fn: (r) => r["_measurement"] == "klines")
        |> filter(fn: (r) => r["symbol"] == "SHFE.rb2510")
'''
result = client.query_api().query_data_frame(query)

适用场景

  • 大量时序数据(Tick、分钟K线)
  • 需要高频写入
  • 主要做时序查询

3.4 HDF5 —— 科学计算常用格式

定位:高性能数据文件格式

HDF5不是传统意义上的数据库,而是一种文件格式,在科学计算领域广泛使用。pandas原生支持HDF5。

优点

  • 读写速度快(特别是pandas)
  • 压缩率高,节省空间
  • 支持分层数据结构

缺点

  • 不是数据库,不支持SQL查询
  • 并发写入需要额外处理
import pandas as pd

# 存储数据
df.to_hdf("futures_data.h5", key="klines_rb", mode="w")

# 读取数据
data = pd.read_hdf("futures_data.h5", key="klines_rb")

# 追加数据
new_data = pd.DataFrame({...})
new_data.to_hdf("futures_data.h5", key="klines_rb", mode="a", append=True)

适用场景

  • 单机存储,数据量中等
  • 主要用pandas处理数据
  • 不需要复杂查询

3.5 MongoDB —— 灵活的文档数据库

定位:NoSQL文档数据库

MongoDB是NoSQL数据库,数据以JSON格式存储,结构灵活。

优点

  • 结构灵活,适合存储非结构化数据
  • 支持复杂查询
  • 水平扩展能力强

缺点

  • 时序数据性能不如专门时序数据库
  • 资源占用较大
from pymongo import MongoClient
from datetime import datetime

# 连接MongoDB
client = MongoClient("mongodb://localhost:27017/")
db = client["futures"]

# 存储K线数据
collection = db["klines"]
for _, row in df.iterrows():
    doc = {
        "datetime": row["datetime"],
        "symbol": "SHFE.rb2510",
        "open": row["open"],
        "high": row["high"],
        "low": row["low"],
        "close": row["close"],
        "volume": row["volume"]
    }
    collection.insert_one(doc)

# 查询数据
query = {
    "symbol": "SHFE.rb2510",
    "datetime": {"$gte": datetime(2025, 1, 1)}
}
results = list(collection.find(query).sort("datetime", -1).limit(100))

适用场景

  • 数据结构经常变化
  • 需要存储策略配置、交易记录等非时序数据
  • 需要灵活的查询

四、综合对比

方案 学习难度 性能 适用数据量 并发支持 推荐度
SQLite ⭐⭐⭐ < 1GB ⭐⭐ ⭐⭐⭐⭐
PostgreSQL+TimescaleDB ⭐⭐⭐ ⭐⭐⭐⭐⭐ GB-TB ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
InfluxDB ⭐⭐⭐ ⭐⭐⭐⭐⭐ GB-TB ⭐⭐⭐⭐ ⭐⭐⭐⭐
HDF5 ⭐⭐ ⭐⭐⭐⭐ GB级别 ⭐⭐ ⭐⭐⭐
MongoDB ⭐⭐⭐ ⭐⭐⭐⭐ GB-TB ⭐⭐⭐⭐ ⭐⭐⭐

五、选择建议

你的情况 推荐方案 理由
个人投资者,数据量小 SQLite 简单,零配置
数据量大,需要时序优化 PostgreSQL+TimescaleDB 性能好,功能全
大量Tick数据 InfluxDB 时序数据库专业
主要用pandas处理 HDF5 pandas原生支持
数据结构灵活 MongoDB NoSQL灵活

六、实际使用建议

6.1 混合使用

实际项目中,可以混合使用多种方案:

# 实时行情 → InfluxDB(高频写入)
# 历史K线 → PostgreSQL(查询方便)
# 回测结果 → SQLite(单文件,备份方便)
# 策略配置 → MongoDB(结构灵活)

6.2 数据分层

  • 热数据(最近1个月):放在内存或SSD
  • 温数据(1-12个月):放在数据库
  • 冷数据(1年以上):压缩归档

七、总结

要点 说明
从简单开始 SQLite够用就先不用复杂的
按需选择 不同数据用不同方案
考虑扩展 数据量大时提前规划
做好备份 数据是量化交易的资产

数据存储方案的选择没有标准答案,关键是要适合你的数据规模和访问模式。希望这篇对比能帮你找到合适的方案。


免责声明:本文仅供学习交流使用,不构成任何投资建议。期货交易有风险,入市需谨慎。

更多资源

  • 天勤量化官网:https://www.shinnytech.com
  • GitHub开源地址:https://github.com/shinnytech/tqsdk-python
  • 官方文档:https://doc.shinnytech.com/tqsdk/latest
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐