【量化实战】A股数据源怎么选?

用户头像mx_****zqklr
2026-09-13 发布

📌 摘要 / 快速解答 (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 支持:

  • forward
  • backward
  • forward_additive
  • backward_additive
  • none

其中比例复权更适合收益率计算;差值复权则更适合观察绝对价差。

所以:

研究趋势和收益率时可以使用前复权;研究真实成交价格时,要明确自己需要哪一种价格口径。


避坑 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 官方资源

我自己比较推荐先把 GitHub 仓库跑通,再看完整文档。

不要一上来就研究复杂策略。

先把数据稳定拿下来,再谈 Alpha。

评论