Featured image of post 用 DuckDB 搭建股票市场分析流水线:从数据导入到自动化报告

用 DuckDB 搭建股票市场分析流水线:从数据导入到自动化报告

手把手教你用 DuckDB 搭建完整的股票市场分析系统:CSV 批量导入、窗口函数计算月度收益、标准差波动率分析、Cron 定时生成并推送日报。一个人完成小团队的分析工作。

用 DuckDB 搭建股票市场分析流水线:从数据导入到自动化报告

难度:⭐⭐⭐ | 预计耗时:2 小时搭建,之后每天 30 秒生成报告


一、为什么用 DuckDB 做股票分析?

很多独立投资者、理财顾问和小微投研团队都有一个共同痛点:每天需要看市场概况和组合表现,但手动整理数据太慢,商业分析工具(Tableau、Power BI)太重,自己写 Python + Pandas 又不够优雅。

DuckDB 恰好填补了这个空白——它在 SQLite 般的简单性下,提供了比 Pandas 快 10 倍的聚合性能。你只需要写 SQL,就能搞定从数据导入到报告生成的一条龙流程。

本文教你搭建一个每日自动生成的股票组合分析报告系统,你可以:

  • 卖给需要每日市场简报的理财顾问
  • 封装成 API 给中小基金做后台
  • 做成 Newsletter 吸引订阅用户

二、系统架构

整个系统由 3 个核心部分组成:

数据源(CSV/API) → DuckDB(.duckdb) → SQL 分析 → 文本/CSV 报告 → 推送(Telegram/邮件)
  1. 数据层:从 CSV/API 导入股票数据 → DuckDB 数据库文件
  2. 分析层:用 SQL 做聚合、排名、趋势分析
  3. 输出层:生成文本报告,自动推送到 Telegram 或邮件

三、完整代码实现

Step 1:创建数据库并批量导入数据

import duckdb

# 连接(文件模式:数据持久化)
conn = duckdb.connect('portfolio.db')

# 创建表结构
conn.execute("""
CREATE TABLE IF NOT EXISTS stock_prices (
    date DATE,
    ticker VARCHAR,
    open DOUBLE,
    high DOUBLE,
    low DOUBLE,
    close DOUBLE,
    volume BIGINT
);
""")

# 从 CSV 批量导入(比 INSERT 快 100 倍)
conn.execute("""
COPY stock_prices FROM 'stock_data.csv'
    (FORMAT CSV, HEADER, DELIMITER ',');
""")

# 创建索引加速查询
conn.execute("CREATE INDEX IF NOT EXISTS idx_date ON stock_prices(date);")
conn.execute("CREATE INDEX IF NOT EXISTS idx_ticker ON stock_prices(ticker);")

关键点COPY FROM 批量导入比逐行 INSERT 快 100 倍以上。对于百万行级别的日K线数据,这个差距会非常明显。

Step 2:组合概览分析

SELECT 
    ticker,
    ROUND(AVG(close), 2) AS avg_price,
    ROUND(MAX(close), 2) AS peak_price,
    ROUND(MIN(close), 2) AS bottom_price,
    ROUND(LAST(close), 2) AS latest_price,
    ROUND((LAST(close) - FIRST(close)) / FIRST(close) * 100, 2) AS total_return_pct
FROM stock_prices
GROUP BY ticker
ORDER BY total_return_pct DESC;

输出示例:

📈 AMZN — 均价 $184.91 峰值 $191.30 最低 $179.66 最新 $184.20 总收益 +2.18% 📈 AAPL — 均价 $174.97 峰值 $182.91 最低 $168.97 最新 $176.34 总收益 +0.97% 📉 GOOG — 均价 $174.81 峰值 $182.09 最低 $167.61 最新 $173.87 总收益 +0.71%

这里使用了 LAST()FIRST() 函数,它们是 DuckDB 的聚合函数,直接取分组中最后一行和第一行的值,非常简洁。

Step 3:波动率分析 — 发现市场热点

波动率是专业投资者最关注的指标之一。谁在剧烈波动,谁就蕴含机会:

SELECT 
    ticker,
    ROUND(STDDEV(close), 2) AS vol_abs,
    ROUND(STDDEV(close) / AVG(close) * 100, 2) AS vol_pct,
    ROUND(AVG(volume) / 1000000, 1) AS avg_vol_m
FROM stock_prices
GROUP BY ticker
ORDER BY vol_pct DESC;

输出示例:

  • AAPL — 波动率 1.46%,日均量 25.3M ← 高波动 + 高流动性 = 短线优选
  • AMZN — 波动率 1.39%,日均量 24.9M
  • MSFT — 波动率 0.60%,日均量 25.6M ← 低波动 = 防御配置

Step 4:月度收益率排名 — 窗口函数的威力

WITH monthly AS (
    SELECT 
        ticker,
        FIRST_VALUE(close) OVER w AS month_start,
        LAST_VALUE(close) OVER w AS month_end
    FROM stock_prices
    WHERE EXTRACT(MONTH FROM date) = 6
    WINDOW w AS (
        PARTITION BY ticker 
        ORDER BY date 
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    )
)
SELECT DISTINCT ticker,
       ROUND((month_end - month_start) / month_start * 100, 2) AS return_pct
FROM monthly
ORDER BY return_pct DESC;

输出示例:

  • TSLA — 6 月收益 +2.47% ← 本月最强
  • AMZN — 6 月收益 +0.02% ← 基本持平
  • AAPL — 6 月收益 -0.39% ← 小幅回调
  • GOOG — 6 月收益 -0.46%
  • MSFT — 6 月收益 -0.63% ← 本月最弱

关键点LAST_VALUE + WINDOW 是 DuckDB 的杀手锏。一句话搞定月度收益率排名,不需要 Pandas 的 pivotgroupby 操作。ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 确保 LAST_VALUE 取到窗口最后一行(不加这个子句,LAST_VALUE 默认只到当前行)。

Step 5:性能验证 — 为什么选 DuckDB?

import time

# 100 次聚合查询的耗时
start = time.time()
for _ in range(100):
    conn.execute("""
        SELECT AVG(close), STDDEV(close) 
        FROM stock_prices 
        WHERE date BETWEEN '2026-01-01' AND '2026-06-28'
    """).fetchall()
elapsed_ms = (time.time() - start) * 1000
print(f"100 次查询总耗时: {elapsed_ms:.1f}ms(平均 {elapsed_ms/100:.2f}ms/次)")

实测结果:840 行数据,100 次查询仅耗时 39.6ms(平均 0.40ms/次)

即使数据量扩大到百万行级别,DuckDB 的向量化执行引擎依然能保持亚秒级响应。这正是商业场景下的核心优势——你的用户不需要等。


四、与传统工具的性能对比

工具100 万行聚合查询内存占用学习曲线部署难度
DuckDB~50ms~50MBSQL 即可零依赖
Pandas~2000ms~500MBPython 编程需安装库
PostgreSQL~200ms~100MBSQL + 运维需安装服务
Excel~30000ms~1GB公式零依赖但慢

DuckDB 在查询速度和内存效率上全面领先,且不需要任何数据库服务进程——这就是所谓的"零运维"。


五、自动化部署

Python 主脚本

import duckdb
import smtplib
from email.mime.text import MIMEText
from datetime import datetime

def generate_report(db_path='portfolio.db'):
    conn = duckdb.connect(db_path)
    
    # 生成报告文本
    lines = []
    lines.append(f"📊 每日市场简报 — {datetime.now().strftime('%Y-%m-%d')}")
    lines.append("")
    
    # 1. 组合概览
    lines.append("═══ 组合概览 ═══")
    for row in conn.execute("""
        SELECT ticker, 
               ROUND(LAST(close), 2),
               ROUND((LAST(close) - FIRST(close)) / FIRST(close) * 100, 2)
        FROM stock_prices
        GROUP BY ticker
        ORDER BY (LAST(close) - FIRST(close)) / FIRST(close) DESC
    """).fetchall():
        direction = "📈" if row[2] > 0 else "📉"
        lines.append(f"  {direction} {row[0]}: ${row[1]} ({row[2]}%)")
    
    lines.append("")
    
    # 2. 波动率排行
    lines.append("═══ 波动率排行 ═══")
    for row in conn.execute("""
        SELECT ticker, ROUND(STDDEV(close) / AVG(close) * 100, 2)
        FROM stock_prices GROUP BY ticker ORDER BY 2 DESC LIMIT 3
    """).fetchall():
        lines.append(f"  🔥 {row[0]}: {row[1]}%")
    
    return "\n".join(lines)

report = generate_report()
print(report)

# 发送报告(邮件 / Telegram Bot API)
# msg = MIMEText(report)
# msg['Subject'] = '每日市场简报'
# msg['From'] = '[email protected]'
# msg['To'] = '[email protected]'
# smtplib.SMTP('smtp.gmail.com', 587).send_message(msg)

用 Cron 定时执行

# 每天 21:00 自动生成并发送邮件
0 21 * * * /usr/bin/python3 /opt/scripts/stock_report.py

六、变现路径

这套系统有四种直接变现方式:

1. 数据产品 — 将报告打包成付费 Telegram 频道 / Newsletter,¥99-299/月
2. API 服务 — 封装分析逻辑,为其他公司提供市场数据 API,¥500-2000/请求
3. 咨询方案 — 为投资机构搭建自定义分析管道,¥3000-10000/项目
4. SaaS 后端 — 用 DuckDB 做 SaaS 产品的分析引擎,免费开源但降低 90% 服务器成本

核心逻辑:DuckDB 让你一个人就能完成一个小团队的工作。当别人还在买服务器、雇 DBA 的时候,你已经用几行 SQL 交付了产品。


七、关键要点总结

  1. COPY FROM 优于 INSERT — 批量导入比逐行 INSERT 快 100 倍以上
  2. LAST_VALUE + WINDOW 是利器 — 一句话搞定月度收益率,不需要 Pandas 的 pivot
  3. 索引按需创建 — 对 date 和 ticker 建索引,查询速度提升 10 倍+
  4. 文件模式持久化 — 使用 .duckdb 文件代替 :memory:,数据跨会话存活
  5. 0.4ms 的查询速度 — 即使你的数据量增长 1000 倍,DuckDB 的向量化引擎依然扛得住

这套系统从搭建到跑通只需 30 分钟。真正值钱的是你后续添加的洞察和差异化分析——那是你的核心竞争力,不是工具本身。


💡 本文的所有 SQL 模板和 Python 脚本已整理成可运行的项目仓库,包含实时数据获取、自动推送和性能调优指南。想深入学习 DuckDB 在金融场景的应用,duckdblab.org 上有完整的实战教程系列,从基础查询到企业级部署逐一拆解。

📺 Watch video tutorials → DuckDB Lab YouTube

Subscribe for more DuckDB & AI automation tutorials

使用 Hugo 构建
主题 StackJimmy 设计