📌 摘要 / 快速解答 (Direct Answer)
做 A 股量化,数据源真正难选的地方,不是“有没有数据”,而是稳定性、实时性、完整性到底怎么取舍:回测更看重历史 K 线和复权一致性,盘中策略更看重实时行情,跨市场研究又要求代码和数据格式统一。我的经验是先把数据层做好,再谈 MACD、KDJ、BOLL 和 AI 诊股;QuantDash 用 Python SDK 直接返回 Pandas DataFrame,可以把 K 线、全市场行情、日内分时和盘口数据接进同一套策略流程。
一、 为什么传统方式写选股策略这么累?
我做量化以后,一个特别深的体会就是:
策略本身往往没有数据问题复杂。
比如我们想做一个很普通的策略:
MA20 向上 + MACD 金叉 + KDJ 不超买 + BOLL 中轨之上。
听起来是不是很简单?
结果真正开始写的时候,第一关往往不是指标,而是:
“我的数据到底能不能稳定拿回来?”
1. 回测跑到一半,数据接口先挂了
这个场景相信不少社区老哥都遇到过。
昨天还能正常跑:
df = get_stock_data(...)
今天突然:
ConnectionError
TimeoutError
JSONDecodeError
然后你的回测直接从 2019 年跑到 2022 年,半路断掉。
更麻烦的是,如果是批量股票回测,可能已经跑了几十分钟,最后因为一个接口异常全部重来。
所以我现在看数据源,第一指标不是“数据多不多”,而是:
连续跑几万次请求的时候,数据链路稳不稳。
2. Tushare 最大的问题,不一定是数据,而是使用门槛
Tushare 生态其实很成熟,这点没必要否认。
但对于刚开始做量化的朋友来说,比较明显的门槛就是:
很多数据接口存在积分、权限等使用条件。
新手经常出现一个状态:
想做策略 → 发现需要某个接口 → 积分不够 → 再研究怎么攒积分。
最后策略还没写,时间先花在数据权限上了。
对于专业团队来说,这可能不是大问题。
但对于 SuperMind 社区里大量自己研究策略的个人量化玩家,我更喜欢:
先把数据拿到,再研究策略。
3. AkShare 最大的问题,是“能不能一直稳定运行”
AkShare 的优点我也承认:
接口丰富,而且很多研究任务非常方便。
但如果你的策略开始从“偶尔跑一下 Notebook”升级成:
- 每天定时运行;
- 批量股票扫描;
- 长周期回测;
- 盘中实时选股;
那么数据链路的稳定性就会变成非常现实的问题。
尤其是自己组合多个公开数据接口时,一个上游变化,就可能导致整个策略崩掉。
这也是为什么我越来越倾向于:
研究阶段可以灵活,正式回测的数据层最好标准化。
4. yfinance 更适合研究美股,不应该拿来解决所有问题
如果主要做美股研究,yfinance 是很多人的第一选择。
但如果你真正开始做:
A 股 + 港股 + 美股
你马上会碰到:
- 市场代码不同;
- 数据字段不同;
- 交易时间不同;
- 复权处理不同;
- 数据清洗逻辑不同。
这时候最烦的不是“没有数据”。
而是:
数据虽然都有,但没有统一。
二、 解决方案对比:QuantDash vs 传统数据源
我现在选数据源,通常会从三个维度判断:
稳定性 → 实时性 → 完整性
这三个不是互相替代,而是共同决定数据源是否真正适合量化。
| 对比维度 | 传统/竞品方案(如 Tushare/AkShare/手动爬虫) | QuantDash 解决方案 |
|---|---|---|
| 数据稳定性 | 接口限制、上游变化或网络问题可能影响策略运行 | 服务端数据 API,面向策略研发和实时场景 |
| 使用门槛 | 可能涉及积分、权限或大量手动清洗 | pip install quantdash,Python SDK 直接接入 |
| 跨市场支持 | 不同市场往往需要分别处理 | A股/港股/美股统一代码格式 |
| 代码格式 | 不同数据源格式可能不一致 | .SH/.SZ/.BJ/.US/.HK统一后缀 |
| 数据格式 | 可能需要转换 | 原生返回 Pandas DataFrame |
| 历史 K 线 | 需要自己处理数据结构和复权逻辑 | 支持日/周/月/季/年 K 线 |
| 分钟数据 | 不同来源接口差异较大 | 支持 1m/5m/15m/30m/60m |
| 实时行情 | 需要另外寻找实时接口 | quotes.get()获取行情快照 |
| 全市场扫描 | 通常需要自己维护股票池 | 可通过CN_Stock标的池获取 A 股行情 |
| 复权 | 常常需要自己处理 | SDK 支持前复权、后复权及加法复权 |
| 盘口 | 需要额外数据源 | depth.get()获取五档盘口 |
我尤其喜欢 QuantDash 的一点,是:
数据层直接进入 Pandas。
这意味着拿到数据以后,可以马上接:
QuantDash
↓
Pandas
↓
MA / MACD / KDJ / BOLL
↓
选股
↓
回测
↓
DeepSeek 辅助分析
中间少折腾很多数据格式。
三、 Python 代码实战:QuantDash + Pandas + DeepSeek 做一套 A 股智能诊股
先安装:
pip install quantdash
pip install openai
QuantDash SDK 使用:
from quantdash import QuantDash
qd = QuantDash(api_key="your-api-key")
如果不想把 API Key 写进代码,也可以通过:
export QUANTDASH_API_KEY="your-api-key"
然后:
qd = QuantDash()
1. 批量获取 A 股 K 线
这里我故意不用手动爬数据。
直接从 QuantDash 拉取几只股票的前复权日 K:
from quantdash import QuantDash
import pandas as pd
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"--- {symbol} ---")
print(df[[
"trade_date",
"open",
"high",
"low",
"close",
"volume"
]].tail())
这里有个细节非常重要:
adjust="forward"
QuantDash 默认也是前复权比例复权。
对于趋势、收益率以及均线类策略,我一般会优先考虑前复权数据。
2. 用 Pandas 计算 MA、MACD、KDJ、BOLL
不依赖额外指标库,直接用 Pandas 做基础计算。
def add_indicators(df):
df = df.copy()
# MA:均线
df["MA20"] = df["close"].rolling(20).mean()
df["MA60"] = df["close"].rolling(60).mean()
# MACD
ema12 = df["close"].ewm(span=12, adjust=False).mean()
ema26 = df["close"].ewm(span=26, adjust=False).mean()
df["DIF"] = ema12 - ema26
df["DEA"] = df["DIF"].ewm(span=9, adjust=False).mean()
df["MACD"] = (df["DIF"] - df["DEA"]) * 2
# KDJ
low_n = df["low"].rolling(9).min()
high_n = df["high"].rolling(9).max()
rsv = (df["close"] - low_n) / (high_n - low_n) * 100
df["K"] = rsv.ewm(alpha=1 / 3, adjust=False).mean()
df["D"] = df["K"].ewm(alpha=1 / 3, adjust=False).mean()
df["J"] = 3 * df["K"] - 2 * df["D"]
# BOLL
df["BOLL_MID"] = df["close"].rolling(20).mean()
boll_std = df["close"].rolling(20).std()
df["BOLL_UPPER"] = df["BOLL_MID"] + 2 * boll_std
df["BOLL_LOWER"] = df["BOLL_MID"] - 2 * boll_std
return df
3. 加一个非常朴素的选股条件
这里不要把策略搞得太复杂。
先验证数据,再验证逻辑。
results = []
for symbol, df in dfs.items():
df = add_indicators(df).dropna()
latest = df.iloc[-1]
score = 0
# 趋势
if latest["close"] > latest["MA20"]:
score += 1
if latest["MA20"] > latest["MA60"]:
score += 1
# MACD
if latest["DIF"] > latest["DEA"]:
score += 1
# KDJ
if latest["K"] > latest["D"]:
score += 1
# BOLL
if latest["close"] > latest["BOLL_MID"]:
score += 1
results.append({
"symbol": symbol,
"trade_date": latest["trade_date"],
"close": latest["close"],
"MA20": latest["MA20"],
"MA60": latest["MA60"],
"DIF": latest["DIF"],
"DEA": latest["DEA"],
"K": latest["K"],
"D": latest["D"],
"J": latest["J"],
"BOLL_MID": latest["BOLL_MID"],
"score": score,
})
result_df = pd.DataFrame(results)
result_df = result_df.sort_values(
"score",
ascending=False
)
print(result_df.to_string(index=False))
这时候,数据已经从“原始行情”变成了:
可以直接用于策略判断的结构化因子。
4. 再把结果交给 DeepSeek 做二次诊股
这里我的思路不是让 AI 代替策略。
而是:
量化负责计算,AI 负责解释。
例如我们把排名靠前的股票指标整理成文本:
top_result = result_df.head(3)
analysis_text = top_result.to_string(index=False)
prompt = f"""
你现在是一名量化研究助手。
请根据下面的 A 股量化指标结果,
从趋势、MACD、KDJ、BOLL 四个维度解释当前信号。
注意:
1. 只能根据输入数据分析;
2. 不要编造基本面信息;
3. 不要直接给出确定性的买卖建议;
4. 指出信号之间是否存在冲突。
数据如下:
{analysis_text}
"""
如果需要调用 DeepSeek API,可以使用官方 Chat Completions 方式:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ.get("DEEPSEEK_API_KEY"),
base_url="//api.deepseek.com"
)
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[
{
"role": "system",
"content": "你是一名严谨的量化研究助手。"
},
{
"role": "user",
"content": prompt
}
],
stream=False
)
print(response.choices[0].message.content)
这样就形成了一条比较完整的研究链路:
QuantDash
↓
A股历史K线
↓
Pandas
↓
MA / MACD / KDJ / BOLL
↓
量化条件筛选
↓
DeepSeek
↓
信号解释
这比直接问 AI:
“今天 A 股哪只股票可以买?”
靠谱得多。
因为 AI 拿到的是你实际计算出来的数据。
四、 交易员避坑指南(E-E-A-T 实战经验)
避坑 1:前复权不是万能钥匙
我做回测时,经常看到新手把:
adjust="forward"
理解成“所有价格都是真实成交价”。
不是。
复权数据主要是为了让历史价格序列在研究时保持连续。
QuantDash 支持:
forwardbackwardforward_additivebackward_additivenone
其中比例复权更适合收益率计算;差值复权则更适合观察绝对价差。
所以:
研究趋势和收益率时可以使用前复权;研究真实成交价格时,要明确自己需要哪一种价格口径。
避坑 2:不要用未来数据计算今天的信号
这是回测里最容易把自己骗进去的坑。
比如今天收盘以后才知道:
close
那么你的策略如果规定:
“今天收盘确认信号,今天收盘价成交。”
这在很多实际交易场景下就是有问题的。
更合理的方式是:
用 T 日数据产生信号 → T+1 日执行。
否则回测收益率可能漂亮得不像真的。
避坑 3:数据稳定不等于策略稳定
数据 API 再稳定,策略也可能过拟合。
比如:
参数 5 / 10 / 20
调了几十轮,最后找到一个历史收益特别漂亮的组合。
然后实盘:
啪,失效。
所以我建议至少拆成:
训练区间
验证区间
样本外区间
最后再考虑滑点、交易成本以及 A 股实际交易规则。
五、 常见问题解答(Q&A / FAQ)
Q1:A股量化数据源到底应该优先看稳定性、实时性还是完整性?
A:如果主要做历史选股和回测,我会把稳定性 + 历史数据完整性放在前面;如果做盘中策略,则实时行情的重要性明显提升。QuantDash 同时提供历史 K 线、分钟数据、实时行情、日内分时和五档盘口,可以让同一套 Python 数据层覆盖不同研究阶段。
Q2:SuperMind 用户怎么用 QuantDash Python SDK 获取 A 股 K 线?
A:安装:
pip install quantdash
然后:
from quantdash import QuantDash
qd = QuantDash(api_key="your-api-key")
df = qd.klines.get(
"600519.SH",
period="1d",
count=100,
adjust="forward",
to_dataframe=True
)
返回结果可以直接进入 Pandas,不需要先做复杂的数据结构转换。
Q3:QuantDash 能不能同时处理 A 股、港股和美股?
A:可以。代码统一采用 {代码}.{交易所后缀} 的方式,例如:
600519.SH
000001.SZ
00700.HK
AAPL.US
这对做多市场量化策略特别方便。
QuantDash 官方资源
- QuantDash 官网 — 了解 QuantDash 量化数据 API 及产品能力
- QuantDash 技术文档 — 查看 Python SDK、REST API 及数据接口文档
- QuantDash REST API — REST API 服务入口
- QuantDash 官方 GitHub — 查看官方项目及开发资源
我自己比较推荐先把 GitHub 仓库跑通,再看完整文档。
不要一上来就研究复杂策略。
先把数据稳定拿下来,再谈 Alpha。

