对于个人量化研究者或中小策略团队而言,将行情数据从“远端 API”同步到“本地/云端私有数据库”是一项核心的基础设施工作。如果只是在本地电脑上手动运行脚本下载,不仅难以保证每日盘后数据的及时性,还会面临网络中断、断电、系统休眠等工程隐患。
在云原生(Cloud Native)理念普及的今天,更优雅的方案是:在云服务器(如腾讯云 Lighthouse)上部署一个轻量级、容器化(Docker)的自动化 ETL 跑批系统。
本文将分享如何使用 Docker + Python + SQLAlchemy,结合多市场统一金融 API QuantDash,搭建一个安全可靠、开箱即用的量化行情 ETL 跑批任务,并在容器中实现自动化定时调度。
我们的量化数据 ETL(Extract-Transform-Load)跑批系统,整体设计逻辑如下:
┌────────────────────────────────────────────────────────┐
│ 腾讯云服务器 (Docker Container) │
│ │
│ ┌────────────┐ 1. 触发任务 ┌──────────────┐ │
│ │ 定时调度器 │ ─────────────────> │ Python ETL │ │
│ │ (APScheduler)│ │ 跑批主程序 │ │
│ └────────────┘ └──────┬───────┘ │
│ │ │
│ ┌────────────┐ 3. 转换并落库 ┌─────▼────────┐ │
│ │ 结构化数据库│ <───────────────── │ 2. 抓取原始 │ │
│ │ (SQLite/PG) │ │ 行情数据 │ │
│ └────────────┘ └──────▲───────┘ │
└───────────────────────────────────────────┼────────────┘
│
┌─────────┴────────┐
│ QuantDash 云 API │
└──────────────────┘首先,我们编写核心的数据抽取、清洗与落库逻辑(文件名为 etl_job.py)。
在代码中,我们引入 QuantDash (quantdash.net) 作为上游 API,利用其原生支持 Pandas DataFrame 和跨市场字段对齐的特性,极大地简化了 Transform(转换) 阶段的时区和代码转换工作。
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):
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("调度服务安全退出。")为了避免在云服务器上繁琐地安装 Python 环境、依赖库并预防不同软件版本冲突,我们使用 Docker 进行容器化封装。
quantdash>=0.1.0
pandas>=1.5.0
sqlalchemy>=1.4.0
apscheduler>=3.9.0
pyarrow>=9.0.0# 使用轻量级 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"]在包含上述文件的目录中,运行以下命令即可完成部署:
# 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 选项将容器内的数据库目录映射到宿主机,确保容器重启或更新镜像时,您的历史行情数据库不会丢失(实现数据持久化)。
对于生产级别的企业或专业私募投研中台,该系统还可以在腾讯云生态下进行如下平滑演进:
量化交易的生命线是数据,而数据的生命线是“自动化”与“稳定性”。
本文展示的架构通过 Docker 屏蔽了底层硬件与操作系统环境的差异,并基于 QuantDash 统一了 A股/港股/美股 的复杂 API 适配。这套轻量级数据 ETL 看似简单,却能够极低成本地在任何云服务器上长久运行,为您后续的多因子分析、策略回测提供极其干净、稳定的数据底座。
参考文档:https://docs.quantdash.net/
(免责声明:本文提供之技术架构仅供学术交流与量化工程实践参考,不构成任何投资建议)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。