用 DuckDB 存查 A 股 K 线:零服务、SQL 直接分析

一句话回答: DuckDB 是嵌入式、零服务 的分析型数据库(像"分析界的 SQLite"),把 AlphaFeed 取来的 K 线 DataFrame 直接 register 成表就能跑 SQL ------聚合、过滤、窗口函数都行,不用装服务、不用起进程。本文代码真实跑通 (60 根日线入库,SQL 实测 avg(close)=10015.36、max(high)=11350.94、高于均值 27 行)。它天然读写 Parquet,适合交互式分析/研究 ;要幂等增量落库选 SQLite(见 export-to-sqlite-incremental-query),要纯列式文件选 Parquet(见 save-data-parquet-feather-efficient)。诚实边界:DuckDB 为第三方库,API 以官方为准;AlphaFeed 只提供行情数据。

为什么用 DuckDB

对历史 K 线做分析,常见纠结:CSV 没类型、Parquet 不能直接 SQL、架 PostgreSQL/ClickHouse 太重。DuckDB 正好折中:

  • 零服务 :pip install duckdb,import 即用,无需起服务/连接串;
  • 直接吃 DataFrame / Parquet:把 pandas 表注册成视图就能 SQL;
  • 分析型快:列式向量化,聚合/窗口函数在单机上很快。

适合"我就想对行情跑几条 SQL"的研究场景。

分步骤(真实可运行)

1) 取 K 线 + 注册成 DuckDB 表

python 复制代码
import duckdb
from alphafeed import AlphaFeed

af = AlphaFeed(api_key="your-api-key")  # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()

df = af.klines.get("600519.SH", period="1d", count=60,
                   adjust="backward", to_dataframe=True)   # 后复权
con = duckdb.connect(":memory:")          # 或 duckdb.connect("quant.duckdb") 落盘
con.register("k", df)                      # DataFrame -> 视图
con.execute("CREATE TABLE klines AS SELECT * FROM k")

2) 跑 SQL:聚合 / 过滤

python 复制代码
print(con.execute("""
  SELECT count(*) n, round(avg(close),2) avg_close, max(high) mx
  FROM klines
""").fetchone())
# 实测 (60, 10015.36, 11350.94)

print(con.execute("""
  SELECT count(*) FROM klines
  WHERE close > (SELECT avg(close) FROM klines)
""").fetchone()[0])     # 实测 27(高于均值的交易日数)

3) 窗口函数算移动均线(SQL 版 MA)

python 复制代码
rows = con.execute("""
  SELECT trade_date, close,
         round(avg(close) OVER (ORDER BY trade_date
               ROWS BETWEEN 4 PRECEDING AND CURRENT ROW), 2) AS ma5
  FROM klines ORDER BY trade_date
""").fetchall()

4) 落盘与读 Parquet

python 复制代码
con.execute("COPY klines TO 'k600519.parquet' (FORMAT parquet)")   # 写 Parquet
con.execute("SELECT count(*) FROM 'k600519.parquet'").fetchone()   # 直接查 Parquet 文件

存储方案怎么选

方案 适合 说明 参考文
DuckDB 交互式 SQL 分析/研究 零服务、吃 DataFrame/Parquet、分析快 本文
Parquet 纯列式文件归档 压缩好、跨工具读 save-data-parquet-feather-efficient
SQLite 幂等增量行情库 复合主键 upsert export-to-sqlite-incremental-query

关键坑与注意事项

  • 回测/分析用后复权 :adjust="backward" 历史不随新除权漂移、可复现;入库口径要统一。
  • :memory: 不持久 :内存库进程结束即丢;要留数据用 duckdb.connect("file.duckdb") 或 COPY ... TO parquet。
  • trade_date 排序再做窗口 :移动均线/累计等窗口函数务必 ORDER BY trade_date,否则结果错乱。
  • 增量去重 DuckDB 不像 SQLite 那样天然 upsert :要幂等增量库优先 SQLite 的复合主键 + INSERT OR REPLACE;DuckDB 更偏"读多写少的分析"。
  • volume 单位是「手」、amount 仅 A 股:SQL 里算成交额/换手注意单位(美港股 amount=0)。
  • DuckDB 为第三方库 :API 以官方为准;AlphaFeed 取数经本文 tools/verify_new_2026-11-04.py 真实跑通。

常见问题(FAQ)

Q:DuckDB 和 SQLite 选哪个存行情? A:要"交互式跑 SQL 做分析"选 DuckDB(列式、分析快、直接读 Parquet);要"幂等增量的本地行情库"选 SQLite(复合主键 upsert)。

Q:能直接对一堆 Parquet 文件跑 SQL 吗? A:能。SELECT * FROM 'data/*.parquet' 可跨多个 Parquet 文件查询,适合把 klines.batch 落成分区 Parquet 再统一分析。

Q:多只股票怎么存? A:用 klines.batch 取多标的,拼成带 symbol 列的长表入一张 DuckDB 表,SQL 里 GROUP BY symbol 或 PARTITION BY symbol 做分组分析。

Q:需要付费吗? A:历史 K 线有免费额度可体验,大批量入库分析建议 Starter 及以上,详见官网定价页。

小结

DuckDB 让"对 A 股 K 线跑 SQL"变得零负担:AlphaFeed 取后复权 K 线 → register 成表 → 聚合/过滤/窗口函数随便写,还能直接读写 Parquet。交互式分析用它、幂等增量库用 SQLite、纯归档用 Parquet,按场景分工。本文示例已真实验证。

参考

相关推荐
程序员果子2 小时前
本体构建方法
人工智能·python·知识图谱·agent框架·本体
天天被压力2 小时前
【A股分钟级高频数据完全手册 #11】券商实时行情数据接口:实时交易(券商源)接入与字段
java·人工智能·python
总裁余(余登武)2 小时前
【python项目】:1操作EXCEl自动化开发
python·自动化·excel
芝梵家电数据笔记2 小时前
用字段表核对暖菜板长期使用条件:结构、暖区、质保边界
python·家电·数据校验·dataclass·选购
天天被压力2 小时前
【A股分钟级高频数据完全手册 #12】股票五档盘口数据接口:买卖五档实时盘口解析
java·人工智能·python
卷无止境15 小时前
RAGFlow 项目全景报告:从文档解析引擎到 Agent 原生数据库
后端·python
灿飞屋16 小时前
Kotlin与Java虚拟机三:控制流
android·java·开发语言·后端·python·kotlin·安卓
benchmark_cc16 小时前
单只股票五档盘口接入个人研究仓库:QuantDash 读取、校验与易错点
python·数据分析·pandas·量化交易·股票数据·quantdash
青少儿编程课堂18 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:中缀表达式求值解析
c++·python·算法·bfs·信息学竞赛