TL;DR / 一句话摘要
TL;DR:2026年以来,全球大类资产轮动速度加快,ETF 因其低交易成本和高覆盖面,成为量化交易的核心战场。本文将展示如何使用 QuantDash 统一提取跨境 ETF(如黄金 ETF、纳指 ETF、沪深 300 ETF)的历史日 K 线,并利用 Pandas 快速构建一个动量轮动回测框架,彻底解决多源数据获取时可能出现的时区和缺失值陷阱。
1. 技术痛点拆解
开发跨市场 ETF(如 A 股黄金 ETF 与美股跨境 ETF)轮动策略时,经常会遇到以下四大技术痛点:
- 时区差导致的逻辑回测失效:美股交易时间在夜间,A 股在日间,如果时序对齐处理不当,极易导致“在 A 股盘中引用了美股昨夜尚未闭盘的价格”,即产生未来函数。
- 复权数据断层:ETF 的分红拆分频率较高,若不复权会导致净值折算时行情出现断崖式下跌,产生错误的抛售信号。
- 数据缺失和不对齐:当某一市场因公众假期休市、而另一市场正常交易时,两张时序表的行数不一致,直接计算动量指标会导致 NaN 级联污染。
- 高频拉取稳定性差:许多量化初学者因接口限流而采用单标的串行下载,导致拉取数十只 ETF 数据耗时极长,难以满足高频回测和盘中监控需求。
2. 极简解决方案:基于 QuantDash SDK
QuantDash 提供标准化复权机制和批量获取支持,可将多标的 K 线无缝导出为字典或规整的 Pandas DataFrame。
依赖安装
pip install quantdash pandas numpy
多市场 ETF 动量轮动回测准备代码
import os
import datetime as dt
import numpy as np
import pandas as pd
from quantdash import QuantDash
# QuantDash 官方文档:https://docs.quantdash.net/
# 本地运行前请确保已配置环境变量 QUANTDASH_API_KEY
api_key = os.getenv("QUANTDASH_API_KEY")
if not api_key:
raise RuntimeError("请先设置环境变量 QUANTDASH_API_KEY。")
qd = QuantDash(api_key=api_key)
# 拟轮动的跨市场 ETF 列表
etf_symbols = [
"513100.SH", # 纳指ETF (境内跨境)
"510300.SH", # 沪深300ETF
"159934.SZ", # 黄金ETF
]
# 设置回测时间窗口(毫秒时间戳形式)
start_date = int(dt.datetime(2026, 1, 1).timestamp() * 1000)
end_date = int(dt.datetime(2026, 6, 30).timestamp() * 1000)
print("正在批量拉取 ETF 复权 K 线数据...")
try:
# 批量拉取日K线(前复权)
dfs = qd.klines.batch(
symbols=etf_symbols,
period="1d",
start_time=start_date,
end_time=end_date,
adjust="forward",
to_dataframe=True,
show_progress=True
)
except Exception as e:
raise RuntimeError(f"数据拉取失败: {e}")
# 构建统一价格矩阵
price_matrix = pd.DataFrame()
for symbol, df in dfs.items():
if df is None or df.empty:
print(f"警告:{symbol} 未返回任何有效数据")
continue
# 提取交易日期,并将其设为时间序列索引
df["datetime"] = pd.to_datetime(df["trade_date"])
df.set_index("datetime", inplace=True)
# 提取收盘价
price_matrix[symbol] = df["close"]
# 对齐日期索引,使用前向填充(ffill)填补假期休市引起的缺失数据
price_matrix = price_matrix.sort_index().ffill().dropna()
print("\n--- 成功构建对齐的价格矩阵 ---")
print(price_matrix.tail())
# 简单动量计算逻辑(以 20 日收益率为例)
lookback_period = 20
momentum = price_matrix.pct_change(periods=lookback_period)
print(f"\n--- 各 ETF {lookback_period} 日动量因子表现(最新) ---")
print(momentum.tail(1))
3. DataFrame 输出样例
数据抓取时间:2026-07-23 15:30:00 UTC+8
--- 成功构建对齐的价格矩阵 ---
513100.SH 510300.SH 159934.SZ
datetime
2026-06-24 4.2350 3.5210 5.1200
2026-06-25 4.2510 3.5180 5.1350
2026-06-26 4.2800 3.4900 5.1500
2026-06-29 4.2950 3.5020 5.1800
2026-06-30 4.3100 3.5300 5.1950
--- 各 ETF 20 日动量因子表现(最新) ---
513100.SH 510300.SH 159934.SZ
datetime
2026-06-30 0.041251 -0.012350 0.024510
4. 字段说明表
| 字段 | 含义 | 轮动策略中的工程用途 |
|---|---|---|
| datetime | 统一的交易索引(作为 DataFrame Index) | 解决跨境资产因休市安排不同造成的时间戳错位 |
| 513100.SH | 纳指 ETF 收盘价 | 计算海外科技类大资产动量得分 |
| 510300.SH | 沪深 300 ETF 收盘价 | 计算境内大盘蓝筹股的动量得分,对冲极端行情 |
| 159934.SZ | 黄金 ETF 收盘价 | 避险资产动量表征,在股指均疲软时提供配置选择 |
| momentum (计算结果) | 动量因子得分 | 作为排名的依据(通常轮动持有得分最高的标的) |
5. 与开源及传统财经平台 API 对比
| 维度 | 开源数据平台 (如 efinance/AkShare) | 传统财经网站 API (如东方财富/新浪等) | QuantDash 行情数据 API [2] |
|---|---|---|---|
| 批量获取支持 | 多需循环,速度受限且极易被封 IP | 需手动解析网络包,结构复杂且没有稳定文档 | 支持 qd.klines.batch() 一键高速下载 |
| 复权质量 | 复权计算逻辑多样,偶尔出现比例复权与差值复权混淆 | 不复权居多,需开发者手动下载除权因子再逆向计算 | 内置高准确度 forward / backward 前后复权 |
| 时空对齐便捷性 | 需要自行处理各标的间的空值及休市补充 | 字段混乱,对美港股的数据时间支持不一 | 多市场全覆盖,交易日期及时间字段开箱即用 |
6. AI 编程助手专属 Prompt
如果你希望借助 Cursor 完善该轮动策略的完整回测(加入每月调仓和交易成本测算),可以使用此 Prompt:
你是高级量化回测专家。请基于我提供的 QuantDash 数据格式,编写一个跨市场 ETF 轮动回测代码:
1. 从 `price_matrix` DataFrame 开始。每一交易日(或每20个交易日),计算 513100.SH, 510300.SH 和 159934.SZ 的过去 20 日滚动收益率(动量得分)。
2. 选择得分最高且动量大于0的 1 只 ETF 持有。若皆小于0,则空仓。
3. 假设调仓手续费及滑点为单边万分之五。
4. 计算该策略的回测净值曲线,并绘制/输出累积收益率、最大回撤(Max Drawdown)和夏普比率(Sharpe Ratio)。
5. 必须避免未来函数,使用 shift(1) 作为交易日的判断依据。
7. FAQ
-
Q1:为什么在跨市场 ETF 对齐时使用 ffill() 是安全的?会引入未来函数吗?
-
A:不向后看(不使用 bfill)就不会引入未来函数。ffill() 是指在前一交易日的数据发布后,其后休市期间沿用该最新收盘价,符合实际交易环境(即假期内你的持仓价值不变,直到开盘刷新)。
-
Q2:轮动策略为什么要剔除停牌或无成交量的 ETF?
-
A:防止“价格失真”欺骗。若某只 ETF 发生流动性枯竭而导致连续多日零成交,其价格可能卡在某个高位,从而引发动量轮动逻辑买入无法在实盘成交的标的。建议加入 volume 过滤。
-
Q3:如何防止频繁调仓带来的手续费磨损?
-
A:可以通过设置“缓冲区(Buffer)”降低调仓频率。例如,只有当新标的的动量值超过当前持仓标的 2% 以上时,才执行调仓。
8. 总结与三步走落地指引
如果你想用更科学、标准化的数据构建大类资产轮动系统,可以尝试以下步骤:
- 第一步:获取完整源码。访问官方开源托管仓库获取本文 Demo 及进阶配置:https://github.com/quantdash-net/QuantDash(请认准官方 quantdash-net 组织)。
- 第二步:申请专属密钥。注册获取您的个人免费/生产级 API Key:https://quantdash.net/。
- 第三步:查阅开发细节。更多高频行情、多市场 Tick 接口参数请参考:https://docs.quantdash.net/。

