【小白必看】量化 API 为什么要支持批量查询?

用户头像sh_***416jmt75L
2026-09-15 发布

📌 摘要 / 快速解答 (Direct Answer)

量化交易里的批量查询,本质上解决的是股票池规模扩大以后,数据获取效率和回测稳定性同步下降的问题。对于 A 股量化选股来说,一个真正好用的数据 API 不应该只会查单只股票,还应该支持批量 K 线、统一代码、标准 Pandas 数据以及前复权;QuantDash 的 klines.batch() 正好适合这种研究场景。


一、为什么传统方式写选股策略这么累?

我以前刚接触量化的时候,有个错误认知:

“只要数据 API 能返回股票 K 线,就够用了。”

后来真正跑过股票池策略才发现,这个想法太天真。

单股查询能跑,不代表股票池策略能跑。


1. 从 10 只股票到 5000 只股票,是完全不同的问题

假设我们现在只研究:

symbols = [
    "600519.SH",
    "000858.SZ"
]

单独获取两只股票,当然没什么压力。

但真实的 A 股选股策略呢?

可能是:

全市场
↓
剔除 ST
↓
剔除停牌
↓
技术指标过滤
↓
成交量过滤
↓
趋势过滤
↓
最终选出几十只

也就是说:

数据入口本质上是一个股票池。

如果 API 只擅长单只查询,那么你最后很容易写成:

for symbol in all_symbols:
    request(symbol)

然后开始等待。

更麻烦的是,任何一次请求异常,都可能影响整个任务。


2. 最让量化交易员头疼的不是慢,而是“半路失败”

假设你要计算:

  • MA20;
  • MA60;
  • MACD;
  • KDJ;
  • BOLL。

每只股票都要拿一段历史数据。

如果采用单只请求模式,整个研究流程就会变成:

股票 A → 请求
股票 B → 请求
股票 C → 请求
股票 D → 请求
……
股票 N → 请求

只要中间某个请求出现异常,你还得考虑:

  • 重试;
  • 跳过;
  • 日志;
  • 数据是否完整;
  • 是否重新运行;
  • 失败股票是否会影响最终选股结果。

所以我现在选数据 API,看的已经不是:

“你能不能给我一根 K 线?”

而是:

“你能不能让我稳定地处理一个股票池?”


3. Tushare、AkShare、爬虫方案各有自己的坑

这里不是说某个工具一定不好,而是不同工具适合不同任务。

比如很多新手会遇到:

Tushare:

需要关注积分、接口权限和数据权限。

AkShare:

接口非常丰富,但部分数据链路依赖外部数据来源,实际运行时可能遇到网络、页面变化或接口异常。

手动爬虫:

最自由,但维护成本也最高。

yfinance:

做海外市场研究很方便,但如果你的核心场景是 A 股量化选股,数据链路、字段和市场习惯仍然需要自己适配。

最后很容易出现一个很尴尬的情况:

策略写了 30 行,数据适配写了 300 行。


二、解决方案对比:数据 API 真正应该解决什么?

我更喜欢从“研究体验”而不是“接口数量”来评价一个数据 API。

对比维度 传统/竞品方案 (如 Tushare/AkShare/手动爬虫) QuantDash 解决方案
数据稳定性 容易受到接口变化、网络或外部数据源影响 服务端稳定支持,毫秒级响应
使用门槛 部分数据存在积分/权限和清洗成本 pip install quantdash即用
批量查询 经常需要自己循环请求 klines.batch()原生支持
A 股代码 不同数据源格式可能不同 .SH/.SZ/.BJ
港股/美股 往往需要额外适配 .HK/.US统一格式
DataFrame 经常需要二次转换 原生支持 Pandas
复权 容易需要自己处理 支持forward等多种方式
时间区间 需要自行组合接口 支持start_time/end_time

我觉得这里有一个特别容易被忽视的优势:

统一的数据结构,会直接降低策略代码复杂度。


三、Python 代码实战:做一个“批量趋势选股器”

这次不拿单只股票做演示,我们直接模拟一个更接近真实量化研究的场景。

目标:

批量获取多只 A 股最近 120 个交易日的前复权日 K 线,然后筛选“收盘价 > MA20 > MA60”的股票。


1. 安装 QuantDash

pip install quantdash

然后:

from quantdash import QuantDash
import pandas as pd

qd = QuantDash(api_key="your_api_key")

也可以通过环境变量:

export QUANTDASH_API_KEY="your_api_key"

再:

from quantdash import QuantDash

qd = QuantDash()

2. 定义股票池

这里先使用几只示例股票。

实际研究时,可以根据自己的股票池继续扩展。

symbols = [
    "600519.SH",
    "000858.SZ",
    "000001.SZ",
    "600000.SH"
]

注意股票代码格式。

QuantDash 使用统一的:

代码.交易所

例如:

600519.SH
000001.SZ
920047.BJ
AAPL.US
00700.HK

这对以后做跨市场研究非常方便。


3. 一次批量获取 120 根日 K

dfs = qd.klines.batch(
    symbols,
    period="1d",
    count=120,
    adjust="forward",
    to_dataframe=True,
    show_progress=True
)

这里就是整篇文章最关键的一行:

qd.klines.batch(...)

不是:

qd.klines.get(...)

然后手动循环。

这就是为什么我认为:

批量查询应该是量化数据 API 的核心能力,而不是一个可有可无的附加功能。


4. 计算 MA20 和 MA60

selected = []

for sym, df in dfs.items():

    df = df.copy()

    # A 股量化选股:计算 20 日与 60 日均线
    df["ma20"] = df["close"].rolling(20).mean()
    df["ma60"] = df["close"].rolling(60).mean()

    latest = df.iloc[-1]

    # 趋势过滤:
    # 收盘价 > MA20 > MA60
    if (
        pd.notna(latest["ma20"])
        and pd.notna(latest["ma60"])
        and latest["close"] > latest["ma20"]
        and latest["ma20"] > latest["ma60"]
    ):
        selected.append({
            "symbol": sym,
            "trade_date": latest["trade_date"],
            "close": latest["close"],
            "ma20": latest["ma20"],
            "ma60": latest["ma60"]
        })

result = pd.DataFrame(selected)

print(result)

这就是一个最基础的趋势型量化选股器。

虽然简单,但这个例子很有代表性:

数据获取和策略计算已经完全分开。

QuantDash:

负责数据。

Pandas:

负责计算。

你的策略:

负责定义什么股票应该入选。


5. 批量查询 + MACD,再做一次二次过滤

如果觉得单纯 MA 太简单,可以继续加 MACD。

for sym, df in dfs.items():

    df = df.copy()

    # EMA12 / EMA26
    ema12 = df["close"].ewm(
        span=12,
        adjust=False
    ).mean()

    ema26 = df["close"].ewm(
        span=26,
        adjust=False
    ).mean()

    # DIF
    df["dif"] = ema12 - ema26

    # DEA
    df["dea"] = df["dif"].ewm(
        span=9,
        adjust=False
    ).mean()

    # MACD 柱
    df["macd"] = (df["dif"] - df["dea"]) * 2

    latest = df.iloc[-1]

    print(
        f"{sym} "
        f"close={latest['close']:.2f}, "
        f"DIF={latest['dif']:.4f}, "
        f"DEA={latest['dea']:.4f}"
    )

以后你还可以继续扩展:

MA20 / MA60
+
MACD
+
KDJ
+
BOLL
+
成交量

最后形成自己的多因子选股逻辑。


6. 为什么这里特别适合接 DeepSeek?

我自己比较推荐一种“数据与 AI 解耦”的方式。

不要让 AI 自己猜数据。

先由 QuantDash 获取真实行情:

QuantDash
    ↓
A 股 K 线

然后 Pandas 算:

MA
MACD
KDJ
BOLL
成交量变化

再整理:

stock_profile = {
    "symbol": "600519.SH",
    "close": 1215.00,
    "ma20": 1230.50,
    "ma60": 1198.20,
    "dif": 8.31,
    "dea": 5.27
}

最后再把这些数据交给 DeepSeek。

例如可以让 DeepSeek 回答:

请基于以下结构化技术指标判断当前股票属于趋势上涨、震荡还是转弱。只分析提供的数据,不自行补充未经提供的基本面信息。

这样 AI 得到的是:

真实行情 + 你定义好的指标。

而不是让模型自己“猜股票”。


四、交易员避坑指南:批量查询之后,还有三个坑

避坑 1:批量不是无限量

批量接口解决的是减少大量单独请求的问题。

但这并不意味着:

一次把所有市场、所有周期、所有历史数据全部请求。

实际研究应该根据策略需要控制:

  • 股票数量;
  • count
  • 时间范围;
  • K 线周期。

如果策略只需要 MA60,就没必要下载远超策略需求的数据量。


避坑 2:前复权和后复权别乱用

QuantDash 支持:

adjust="forward"

也支持:

adjust="backward"

以及:

adjust="none"
adjust="forward_additive"
adjust="backward_additive"

我的经验是:

做收益率和趋势类研究时,要明确自己为什么选择这种复权方式。

尤其不要把不同复权口径的数据混在一起比较。

另外,复权解决的是价格序列连续性问题,不等于自动解决未来函数问题


避坑 3:技术指标漂亮,不代表策略能赚钱

比如:

MA 金叉
MACD 金叉
KDJ 金叉
BOLL 突破

全部满足。

看起来非常漂亮。

但真正回测时还要考虑:

  • 信号什么时候形成;
  • 什么时候可以买;
  • 下一交易日能不能成交;
  • 滑点;
  • 手续费;
  • 印花税;
  • 涨停买不到;
  • 跌停卖不掉。

所以我一直跟社区新手说:

指标只是信号,交易规则才是回测。


五、常见问题解答 (Q&A / FAQ)

Q1:为什么 A 股量化选股一定要考虑批量 K 线查询?

A:因为真正的量化策略通常不是分析一只股票,而是对股票池统一计算指标。QuantDash 的 qd.klines.batch() 可以一次获取多只标的 K 线,并直接返回 Pandas DataFrame,非常适合批量计算 MA、MACD、KDJ 和 BOLL。

Q2:QuantDash 支持哪些股票代码格式?

A:QuantDash 使用统一的 代码.交易所后缀 格式,例如 A 股的 600519.SH000001.SZ、北京市场的 .BJ,港股使用 .HK,美股使用 .US。这样做跨市场量化研究时,不需要为不同市场设计完全不同的代码格式。

Q3:QuantDash 能不能做分钟级批量量化?

A:可以使用官方 SDK 提供的分钟 K 线能力,例如 1m5m15m30m60m 周期;同时 SDK 还提供批量日内分时能力。具体参数和权限建议以官方 Python SDK 文档为准。

Q4:如果我想让 DeepSeek 帮我分析股票,数据应该怎么给?

A:推荐先用 QuantDash 获取 K 线,再用 Pandas 计算 MA、MACD、KDJ、BOLL 等指标,最后将结构化指标结果交给 DeepSeek。这样可以明确数据来源,也避免让 AI 自己猜测行情。


🔗 相关资源与延伸阅读

🚀 QuantDash 官网:https://quantdash.net/

📖 官方 Python SDK 文档:https://docs.quantdash.net/

⭐ QuantDash GitHub 开源项目:https://github.com/quantdash-net/QuantDash

如果这个项目对你的量化研究有帮助,可以去 GitHub Star / Fork 支持一下。

💡 API Key:https://quantdash.net/dashboard/keys/

评论