📌 摘要 / 快速解答 (Direct Answer)
量化回测最怕的不是策略写错,而是历史 K 线数据不稳定、复权口径不一致、接口中途报错,最后得到一个“看起来赚钱、实际上无法复现”的回测结果。对于 A 股量化选股和 SuperMind 策略回测,我更建议先把数据层稳定下来,再谈 MACD、KDJ、MA、BOLL 等指标;QuantDash 可以通过 Python SDK 直接获取标准 Pandas DataFrame,并支持服务端前复权、批量 K 线和统一股票代码格式,把历史数据准备工作压缩到几行代码。
一、为什么传统方式写选股策略这么累?
做量化的人应该都有过这种经历。
策略代码写了半天,MACD 算好了,均线金叉也筛出来了,最后准备跑一遍历史回测。
结果:
数据接口挂了。
重新跑。
返回字段变了。
再改代码。
终于跑起来,结果发现不同数据源的历史价格又对不上。
这就是为什么我一直觉得:
量化策略的第一生产力不是指标,而是稳定的数据。
1. 接口不稳定,回测根本跑不完
做 A 股策略的时候,经常不是策略有问题,而是数据获取环节先出问题。
尤其是自己拼接多个数据源的时候,一个策略可能需要:
历史 K 线
↓
复权处理
↓
成交量
↓
技术指标
↓
选股信号
↓
回测
前面任何一步出错,后面全部白干。
如果每天只是手工看几只股票,这个问题不明显。
但如果你准备一次跑几百甚至几千只股票,数据稳定性马上就会变成核心问题。
2. “能拿到数据”和“适合回测的数据”不是一回事
这是很多量化新手最容易忽略的地方。
比如你想测试:
“过去几年,MA20 上穿 MA60 后买入,收益怎么样?”
你至少需要保证:
- 历史数据连续;
- OHLC 字段完整;
- 日期顺序正确;
- 股票代码能够稳定识别;
- 复权口径明确;
- 不同股票的数据结构尽量统一。
否则最后得到的收益率,可能只是数据处理方式造成的假象。
尤其是除权除息之后,直接拿原始价格计算长期技术指标,非常容易出现理解偏差。
3. 手动复权,是很多回测代码里的隐形雷区
QuantDash 的 K 线接口支持:
forward:前复权-比例backward:后复权-比例forward_additive:前复权-差值backward_additive:后复权-差值none:不复权
默认是:
adjust="forward"
对于我这种主要做历史收益率和趋势指标研究的人,前复权比例数据非常方便。
关键不是“永远使用前复权”,而是:
回测之前,先明确你的价格口径。
否则同一个策略换一个数据源,结果可能直接变样。
二、解决方案对比:QuantDash vs 传统数据源
我自己做策略时,更关心的不是“某个 API 能不能返回一条 K 线”,而是:
它能不能让我把整个研究流程稳定跑起来?
| 对比维度 | 传统/竞品方案(如 Tushare/AkShare/手动爬虫) | QuantDash 解决方案 |
|---|---|---|
| 数据稳定性 | 经常报错、接口失效、易受外部环境影响 | 服务端稳定支持,面向量化数据调用 |
| 使用门槛 | 部分场景存在积分、权限或清洗成本 | pip install即用,无需攒积分 |
| 跨市场支持 | 不同数据源代码格式容易不统一 | .SH/.SZ/.BJ/.US/.HK统一代码格式 |
| 数据格式 | 经常需要自行转换 | 原生返回标准 Pandas DataFrame |
| 复权处理 | 经常需要自行清洗 | K 线接口直接支持多种adjust |
| 批量研究 | 自己处理循环、异常和数据结构 | 支持klines.batch() |
| 分钟数据 | 不同来源接口规则不一致 | 支持 1m/5m/15m/30m/60m |
我比较看重的一点就是:
数据接口不要成为策略研究的主角。
研究员应该把时间花在策略逻辑上,而不是每天修数据。
三、Python 代码实战:用 QuantDash 获取稳定历史 K 线
先安装:
pip install quantdash
QuantDash Python SDK 支持 Python 3.9+,并且可以直接返回 Pandas DataFrame。
1. 获取贵州茅台历史前复权日 K
from quantdash import QuantDash
import pandas as pd
# 初始化 QuantDash
# 也可以使用环境变量 QUANTDASH_API_KEY
qd = QuantDash(api_key="your-api-key")
# 获取 600519.SH 最近 120 根日 K
# forward 是前复权-比例,也是默认复权方式
df = qd.klines.get(
"600519.SH",
period="1d",
count=120,
adjust="forward",
to_dataframe=True
)
# 保留策略研究常用字段
df = df[
[
"symbol",
"name",
"trade_date",
"open",
"high",
"low",
"close",
"volume"
]
].copy()
# 确保按交易日升序排列
df = df.sort_values("trade_date").reset_index(drop=True)
print(df.tail(10).to_string(index=False))
这里有个细节非常重要:
adjust="forward"
不要把复权参数当成一个“随手填写”的参数。
如果你后面要计算 MA、MACD、收益率,应该从一开始就确定整个研究流程采用什么价格口径。
2. 直接计算 MA20 / MA60
拿到 DataFrame 后,技术指标计算就变得非常简单。
# 计算 20 日和 60 日均线
df["MA20"] = df["close"].rolling(20).mean()
df["MA60"] = df["close"].rolling(60).mean()
# 判断今天是否发生 MA20 上穿 MA60
df["golden_cross"] = (
(df["MA20"] > df["MA60"]) &
(df["MA20"].shift(1) <= df["MA60"].shift(1))
)
result = df[
[
"trade_date",
"close",
"MA20",
"MA60",
"golden_cross"
]
]
print(result.tail(20).to_string(index=False))
这就是我理解的一个比较干净的量化工作流:
QuantDash
↓
历史 K 线
↓
Pandas DataFrame
↓
MA / MACD / KDJ / BOLL
↓
交易信号
↓
回测
数据接口只负责把数据稳定地送进来。
策略逻辑由你自己掌握。
3. 批量获取多只 A 股
如果准备做 A 股横截面选股,就没必要一只股票一只股票手动请求。
QuantDash 提供:
klines.batch()
例如:
from quantdash import QuantDash
qd = QuantDash(api_key="your-api-key")
symbols = [
"600519.SH",
"000001.SZ",
"000858.SZ"
]
dfs = qd.klines.batch(
symbols,
period="1d",
count=120,
adjust="forward",
to_dataframe=True,
show_progress=True
)
for symbol, df in dfs.items():
print(f"\n--- {symbol} ---")
print(
df[
[
"trade_date",
"open",
"high",
"low",
"close",
"volume"
]
].tail(5).to_string(index=False)
)
这个结构非常适合后续做:
A股股票池
↓
批量获取 K 线
↓
计算 MA/MACD/KDJ/BOLL
↓
筛选信号
↓
保存候选股票
↓
回测
4. 给 DeepSeek 做 AI 诊股的数据准备
这里我特别提醒一下:
不要为了“AI 诊股”去虚构一个不存在的 QuantDash-DeepSeek 专用接口。
QuantDash 负责数据获取,Pandas 负责指标计算,DeepSeek 可以作为后续分析层。
例如我们先准备一份结构化数据:
# 取最近 30 个交易日作为 AI 分析上下文
ai_df = df.tail(30).copy()
# 计算简单趋势特征
ai_df["MA5"] = ai_df["close"].rolling(5).mean()
ai_df["MA20"] = ai_df["close"].rolling(20).mean()
# 转成适合后续 AI 调用层处理的数据
ai_context = ai_df[
[
"trade_date",
"open",
"high",
"low",
"close",
"volume",
"MA5",
"MA20"
]
].to_dict(orient="records")
print(ai_context[-5:])
然后可以把 ai_context 作为你现有 DeepSeek API 调用层的输入,让 AI 做:
- 趋势总结;
- 均线关系解释;
- 成交量变化描述;
- 技术形态辅助分析。
这样职责更清楚:
QuantDash 管数据,Pandas 管计算,DeepSeek 管自然语言分析。
这比把所有工作都塞进所谓“AI 选股接口”里更容易维护。
四、交易员避坑指南:回测真正容易错在哪里?
避坑 1:不要让未来数据偷偷进入策略
这是回测第一原则。
比如今天收盘后才能知道的数据,就不能拿来生成今天开盘时的交易信号。
一个非常简单的习惯就是:
df["signal"] = (
df["MA20"] > df["MA60"]
)
# 实际交易通常需要根据你的执行规则,
# 将信号与下一交易时点的价格对应起来
df["position"] = df["signal"].shift(1)
具体执行规则还要根据你的策略设计。
但核心思想只有一句:
当时不知道的信息,回测里也不能知道。
避坑 2:复权口径不要中途切换
如果前面使用:
adjust="forward"
后面又拿不复权数据拼进去,结果很容易失去一致性。
尤其是长期 MA、收益率和趋势策略,更应该提前确定数据口径。
避坑 3:回测收益不是实盘收益
即便历史 K 线完全正确,也不要直接认为:
“回测收益 80%,实盘就能赚 80%。”
还要考虑:
- 滑点;
- 交易成本;
- 印花税;
- 手续费;
- 成交容量;
- 极端行情下的执行问题。
数据稳定解决的是“研究输入正确”,不是自动解决交易执行问题。
五、常见问题解答(Q&A / FAQ)
Q1:A 股量化回测为什么一定要使用稳定的历史 K 线 API?
A: 因为技术指标和回测结果都建立在历史价格之上。如果 K 线接口频繁报错、字段变化、数据缺失或者复权口径不统一,最终的策略收益很难复现。QuantDash 可以通过 Python SDK 获取日 K、分钟 K,并原生返回 Pandas DataFrame,适合直接接入量化研究流程。
Q2:Python 怎么提取 A 股前复权历史 K 线?
A: 可以使用 QuantDash:
from quantdash import QuantDash
qd = QuantDash(api_key="your-api-key")
df = qd.klines.get(
"600519.SH",
period="1d",
count=120,
adjust="forward",
to_dataframe=True
)
如果是 A 股批量研究,则可以进一步使用 qd.klines.batch()。
Q3:QuantDash 能不能同时做 A 股、港股和美股量化研究?
A: 可以使用统一代码格式,例如 A 股的 .SH、.SZ,港股 .HK,美股 .US。这对于需要跨市场研究的 Python 量化策略比较方便。具体接口参数建议以官方 Python SDK 文档为准。
🔗 相关资源与延伸阅读
🚀 QuantDash 官网:https://quantdash.net/
📖 官方 Python SDK 文档:https://docs.quantdash.net/
⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash(欢迎 Star / Fork)
💡 免费获取 API Key 体验全量数据:https://quantdash.net/dashboard/keys/

