首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >云原生量化实践:基于 Docker + Python 搭建全自动多市场「量化数据 ETL 跑批系统」

云原生量化实践:基于 Docker + Python 搭建全自动多市场「量化数据 ETL 跑批系统」

原创
作者头像
用户9138916
发布2026-07-09 17:13:58
发布2026-07-09 17:13:58
290
举报

对于个人量化研究者或中小策略团队而言,将行情数据从“远端 API”同步到“本地/云端私有数据库”是一项核心的基础设施工作。如果只是在本地电脑上手动运行脚本下载,不仅难以保证每日盘后数据的及时性,还会面临网络中断、断电、系统休眠等工程隐患。

在云原生(Cloud Native)理念普及的今天,更优雅的方案是:在云服务器(如腾讯云 Lighthouse)上部署一个轻量级、容器化(Docker)的自动化 ETL 跑批系统

本文将分享如何使用 Docker + Python + SQLAlchemy,结合多市场统一金融 API QuantDash,搭建一个安全可靠、开箱即用的量化行情 ETL 跑批任务,并在容器中实现自动化定时调度。


一、 跑批系统架构设计

我们的量化数据 ETL(Extract-Transform-Load)跑批系统,整体设计逻辑如下:

代码语言:txt
复制
┌────────────────────────────────────────────────────────┐
│               腾讯云服务器 (Docker Container)            │
│                                                        │
│  ┌────────────┐     1. 触发任务     ┌──────────────┐   │
│  │ 定时调度器  │ ─────────────────> │ Python ETL   │   │
│  │ (APScheduler)│                    │ 跑批主程序   │   │
│  └────────────┘                    └──────┬───────┘   │
│                                           │            │
│  ┌────────────┐     3. 转换并落库   ┌─────▼────────┐   │
│  │ 结构化数据库│ <───────────────── │ 2. 抓取原始  │   │
│  │ (SQLite/PG) │                    │ 行情数据     │   │
│  └────────────┘                    └──────▲───────┘   │
└───────────────────────────────────────────┼────────────┘
                                            │
                                  ┌─────────┴────────┐
                                  │ QuantDash 云 API │
                                  └──────────────────┘
  1. Extraction(数据提取):定时调度器触发跑批程序,通过 QuantDash API 提取 A股、美股、港股的日K线或日内分时数据。
  2. Transformation(数据转换):利用 Pandas 对原始 JSON 数据进行清洗,统一时区格式,计算简单的技术指标(如 MA、EMA 均线),以便下游策略开箱即用。
  3. Loading(数据加载):使用 SQLAlchemy 对象关系映射器,将清洗后的结构化数据增量写入云端数据库(如本地 SQLite 或云数据库 PostgreSQL)。
  4. Containerization(容器化):将所有运行环境和调度依赖打包入 Docker 镜像,实现一键部署与环境隔离。

二、 ETL 跑批主程序实现

首先,我们编写核心的数据抽取、清洗与落库逻辑(文件名为 etl_job.py)。

在代码中,我们引入 QuantDash (quantdash.net) 作为上游 API,利用其原生支持 Pandas DataFrame 和跨市场字段对齐的特性,极大地简化了 Transform(转换) 阶段的时区和代码转换工作。

代码语言:python
复制
import os
import sys
import logging
from datetime import datetime
from sqlalchemy import create_engine
from quantdash import QuantDash

# 配置日志系统
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")

# 1. 初始化环境变量
API_KEY = os.getenv("QUANTDASH_API_KEY")
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///quant_market_data.db")
TARGET_SYMBOLS = os.getenv("TARGET_SYMBOLS", "600519.SH,AAPL.US,00700.HK")

if not API_KEY:
    logging.error("未配置 QUANTDASH_API_KEY 环境变量,程序退出。")
    sys.exit(1)

# 初始化云端数据库引擎与 QuantDash 客户端
engine = create_engine(DATABASE_URL)
qd = QuantDash(api_key=API_KEY)

def run_etl():
    logging.info("================ 开始运行每日行情 ETL 跑批任务 ================")
    symbols = [s.strip() for s in TARGET_SYMBOLS.split(",")]
    
    for symbol in symbols:
        logging.info(f"[Extract] 正在从 QuantDash 提取标的 {symbol} 的日K线...")
        try:
            # 1. Extraction: 提取原始数据 (直接获取 DataFrame 格式)
            df = qd.klines.get(symbol=symbol, period="1d", to_dataframe=True)
            if df.empty:
                logging.warning(f"标的 {symbol} 返回数据为空,跳过。")
                continue
                
            # 2. Transformation: 数据清洗与转换
            # 统一将交易日期列转换为标准的 datetime 格式
            df['trade_date'] = pd.to_datetime(df['trade_date'])
            # 增量处理:增加更新时间戳,便于审计数据
            df['updated_at'] = datetime.utcnow()
            
            # 计算简单衍生指标:例如 5 日均线、10 日均线
            df['ma_5'] = df['close'].rolling(window=5).mean()
            df['ma_10'] = df['close'].rolling(window=10).mean()
            
            # 3. Loading: 写入数据库
            # 使用 SQLAlchemy 引擎,由于是跑批更新,我们对表采用 append (增量追加) 或 replace
            # 生产环境建议通过唯一索引 (symbol + trade_date) 进行 upsert 处理,这里简化为 replace/append 演示
            table_name = "kline_daily"
            df.to_sql(name=table_name, con=engine, if_exists="replace", index=False)
            logging.info(f"[Load] 标的 {symbol} 成功导入数据库表 {table_name},共 {len(df)} 行数据。")
            
        except Exception as e:
            logging.error(f"处理标的 {symbol} 时发生异常: {e}")
            
    logging.info("================ ETL 跑批任务顺利完成 ================")

if __name__ == "__main__":
    run_etl()

三、 自动化定时调度设计

为了让这个 ETL 脚本自动在每天 A 股、港股、美股全部收盘后的深夜运行,我们可以使用 Python 的 APScheduler 写一个轻量级常驻服务进程,或者直接在 Docker 中配置定时任务。

这里,我们编写一个轻量级的调度常驻主程序(main.py):

代码语言:python
复制
import time
import logging
from apscheduler.schedulers.blocking import BlockingScheduler
from etl_job import run_etl

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")

if __name__ == "__main__":
    logging.info("启动量化数据调度服务,等待定时触发...")
    
    scheduler = BlockingScheduler()
    # 设定每日北京时间 23:30 自动执行 ETL 跑批(通常此时多市场已收盘并完成结算)
    scheduler.add_job(run_etl, 'cron', hour=23, minute=30, timezone='Asia/Shanghai')
    
    try:
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        logging.info("调度服务安全退出。")

四、 云原生容器化部署(Docker)

为了避免在云服务器上繁琐地安装 Python 环境、依赖库并预防不同软件版本冲突,我们使用 Docker 进行容器化封装。

1. 编写 requirements.txt
代码语言:txt
复制
quantdash>=0.1.0
pandas>=1.5.0
sqlalchemy>=1.4.0
apscheduler>=3.9.0
pyarrow>=9.0.0
2. 编写 Dockerfile
代码语言:dockerfile
复制
# 使用轻量级 Python 基础镜像
FROM python:3.10-slim

# 设置容器内工作目录
WORKDIR /app

# 设置时区为亚洲/上海,确保 cron/scheduler 定时逻辑准确
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 复制依赖描述文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制代码到容器内
COPY . .

# 启动定时调度主程序
CMD ["python", "main.py"]
3. 构建与运行容器

在包含上述文件的目录中,运行以下命令即可完成部署:

代码语言:bash
复制
# 1. 构建 Docker 镜像
docker build -t quant-etl-system:v1 .

# 2. 运行容器,通过环境变量传入 API Key 以及你要监控的自选股
docker run -d \
  --name my-quant-etl \
  -e QUANTDASH_API_KEY="您的QuantDash真实APIKEY" \
  -e TARGET_SYMBOLS="600519.SH,AAPL.US,00700.HK,000001.SZ" \
  -v $(pwd)/data:/app/data \
  quant-etl-system:v1

提示:-v $(pwd)/data:/app/data 选项将容器内的数据库目录映射到宿主机,确保容器重启或更新镜像时,您的历史行情数据库不会丢失(实现数据持久化)。


五、 架构演进与容错探讨

对于生产级别的企业或专业私募投研中台,该系统还可以在腾讯云生态下进行如下平滑演进:

  1. 云数据库替代本地 SQLite:当自选股池扩展到数千只时,读写锁竞争和存储空间会成为 SQLite 的瓶颈。可一键将环境变量 DATABASE_URL 修改为腾讯云 PostgreSQL 实例,由于使用 SQLAlchemy 标准连接,无需重写任何 SQL 代码。
  2. 死信队列与任务监控:若跑批过程因极端网络波动导致某一标的数据获取彻底中断,除程序内捕获异常外,可结合腾讯云 CLS 日志服务对特定级别(如 [Error])的日志输出设置告警规则,实现异常秒级推送至企业微信或微信助手。

六、 总结

量化交易的生命线是数据,而数据的生命线是“自动化”与“稳定性”。

本文展示的架构通过 Docker 屏蔽了底层硬件与操作系统环境的差异,并基于 QuantDash 统一了 A股/港股/美股 的复杂 API 适配。这套轻量级数据 ETL 看似简单,却能够极低成本地在任何云服务器上长久运行,为您后续的多因子分析、策略回测提供极其干净、稳定的数据底座。

参考文档:https://docs.quantdash.net/

(免责声明:本文提供之技术架构仅供学术交流与量化工程实践参考,不构成任何投资建议)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、 跑批系统架构设计
  • 二、 ETL 跑批主程序实现
  • 三、 自动化定时调度设计
  • 四、 云原生容器化部署(Docker)
    • 1. 编写 requirements.txt
    • 2. 编写 Dockerfile
    • 3. 构建与运行容器
  • 五、 架构演进与容错探讨
  • 六、 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档