【小白必看】A股回测如何选稳定K线API?

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

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

如果你的 A 股量化策略需要同时计算 MA、MACD、KDJ、BOLL,再交给 AI 做辅助诊股,那么历史 K 线 API 就不能只追求“能返回数据”,更要关注稳定性、复权方式、字段结构和批量能力。我的做法是让 QuantDash 负责统一获取 K 线,让 Pandas 完成指标计算,再把结构化结果交给 DeepSeek 等 AI 工具分析,这样策略研究链路更清晰,也更容易复现。

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

我以前刚开始折腾量化的时候,有一个很大的误区:

“策略最重要,所以先把选股逻辑写出来。”

后来才发现,很多时间根本不是花在策略上的。

而是花在:

接口
↓
数据格式
↓
复权
↓
缺失值
↓
指标
↓
异常数据
↓
最后才轮到策略

特别是现在很多人开始把 DeepSeek 之类的大模型加入量化研究之后,这个问题反而更加明显。

因为:

垃圾数据进入 AI,AI 也只能在垃圾数据上做分析。


1. MACD 算错一次,AI 也救不了你

假设我们让 AI 判断:

“这只股票目前是不是处于趋势转强阶段?”

AI 看到的是:

  • 收盘价;
  • MA5;
  • MA20;
  • MACD;
  • 成交量;
  • 最近若干交易日。

如果最底层 K 线有问题,后面的 MACD 和均线就可能全部跟着偏。

所以 AI 量化真正应该遵循:

数据 → 指标 → 信号 → AI 分析

而不是:

AI → 猜股票 → 再找数据证明 AI 是对的。


2. AkShare、Tushare 等传统方案的问题,不只是“能不能用”

这里我并不是说某一个数据源完全不能用。

实际使用中,大家都会有自己的工具组合。

问题在于:

当你准备把策略从“个人脚本”升级成“长期自动运行的研究流程”时,数据层的维护成本会越来越明显。

例如:

  • Tushare 部分数据存在积分、权限等使用门槛;
  • AkShare 某些接口依赖外部网页结构,稳定性可能受到影响;
  • yfinance 更适合某些海外市场研究,但做 A 股策略时不一定是最顺手的选择;
  • 手动爬数据则需要自己处理解析、清洗、异常和复权。

如果只是临时研究一次,问题可能不大。

但如果你每天都要跑策略,就完全是另一回事了。


二、解决方案对比:QuantDash vs 传统数据源

对比维度 传统/竞品方案(如 Tushare/AkShare/手动爬虫) QuantDash 解决方案
数据稳定性 容易遇到接口限制、报错或数据清洗问题 服务端提供标准化行情数据
使用门槛 部分方案需要积分、权限或自行维护 pip install quantdash即可开始
A 股代码 不同数据源格式可能不同 .SH/.SZ/.BJ
港股/美股 往往需要单独适配 .HK/.US统一格式
Pandas 经常需要自行转换 原生支持 DataFrame
复权 可能需要自行处理 adjust参数直接选择
批量数据 经常自己写循环 klines.batch()
分钟 K 不同来源使用方式不同 支持1m/5m/15m/30m/60m

我比较喜欢这种设计的一点是:

数据拿回来以后,就是 DataFrame。

这意味着后面的工作基本就是熟悉的 Pandas。


三、Python 代码实战:QuantDash + Pandas 做技术指标研究

先安装:

pip install quantdash

然后初始化:

from quantdash import QuantDash
import pandas as pd

qd = QuantDash(api_key="your-api-key")

如果不希望把 API Key 直接写在代码里,也可以通过:

QUANTDASH_API_KEY

环境变量配置,然后:

qd = QuantDash()

1. 获取 A 股历史 K 线

这里用平安银行举例:

from quantdash import QuantDash
import pandas as pd

qd = QuantDash(api_key="your-api-key")

# 获取最近 250 根前复权日 K
df = qd.klines.get(
    "000001.SZ",
    period="1d",
    count=250,
    adjust="forward",
    to_dataframe=True
)

# 按交易日期排序
df = df.sort_values("trade_date").reset_index(drop=True)

print(
    df[
        [
            "symbol",
            "name",
            "trade_date",
            "open",
            "high",
            "low",
            "close",
            "volume"
        ]
    ].tail(10).to_string(index=False)
)

这里的 250 只是研究窗口示例。

实际策略需要多长历史数据,要根据指标周期和回测区间决定。


2. 用 Pandas 计算 MA

先从最基础的均线开始:

# 计算短、中期均线
df["MA5"] = df["close"].rolling(5).mean()
df["MA20"] = df["close"].rolling(20).mean()
df["MA60"] = df["close"].rolling(60).mean()

# 判断短期趋势
df["trend_up"] = (
    (df["MA5"] > df["MA20"]) &
    (df["MA20"] > df["MA60"])
)

print(
    df[
        [
            "trade_date",
            "close",
            "MA5",
            "MA20",
            "MA60",
            "trend_up"
        ]
    ].tail(20).to_string(index=False)
)

这样就已经能做一个非常简单的趋势选股条件:

MA5 > MA20 > MA60

当然,这还远远称不上完整策略。


3. 再加入 MACD

MACD 的核心数据同样可以直接从 DataFrame 计算。

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

# DIF
df["DIF"] = df["EMA12"] - df["EMA26"]

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

# MACD 柱
df["MACD"] = (df["DIF"] - df["DEA"]) * 2

# 判断 DIF 是否向上穿越 DEA
df["macd_cross"] = (
    (df["DIF"] > df["DEA"]) &
    (df["DIF"].shift(1) <= df["DEA"].shift(1))
)

print(
    df[
        [
            "trade_date",
            "close",
            "DIF",
            "DEA",
            "MACD",
            "macd_cross"
        ]
    ].tail(20).to_string(index=False)
)

这时候我们已经拥有:

K线
+
MA
+
MACD

接下来就可以组合成自己的选股条件。


4. 一个更接近 SuperMind 实战的组合条件

例如我想找:

均线趋势向上,同时 MACD 出现金叉。

可以这样写:

df["signal"] = (
    df["trend_up"] &
    df["macd_cross"]
)

signals = df[df["signal"]].copy()

print(
    signals[
        [
            "trade_date",
            "close",
            "MA5",
            "MA20",
            "MA60",
            "DIF",
            "DEA"
        ]
    ].tail(20).to_string(index=False)
)

这就是非常典型的:

QuantDash → Pandas → 技术指标 → 选股信号


5. 批量跑股票池

如果只研究一只股票,单标的接口足够。

如果准备做 A 股横截面策略,我更推荐批量获取:

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

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

for symbol, stock_df in dfs.items():

    stock_df = stock_df.sort_values("trade_date").copy()

    stock_df["MA20"] = (
        stock_df["close"]
        .rolling(20)
        .mean()
    )

    stock_df["MA60"] = (
        stock_df["close"]
        .rolling(60)
        .mean()
    )

    latest = stock_df.iloc[-1]

    print(
        f"{symbol} | "
        f"收盘={latest['close']:.2f} | "
        f"MA20={latest['MA20']:.2f} | "
        f"MA60={latest['MA60']:.2f}"
    )

这种写法非常适合后续接入自己的 SuperMind 策略研究流程。


6. 为什么这时候再接 DeepSeek 更合理?

假设我们已经通过 QuantDash + Pandas 得到:

最近交易日
收盘价
MA5
MA20
MA60
DIF
DEA
MACD
成交量

那么可以把这些结构化数据整理成 AI 分析上下文。

例如:

ai_df = df[
    [
        "trade_date",
        "close",
        "volume",
        "MA5",
        "MA20",
        "MA60",
        "DIF",
        "DEA",
        "MACD"
    ]
].tail(20)

# 转换为 JSON 友好的 Python 对象
ai_context = ai_df.to_dict(orient="records")

print(ai_context)

然后再交给你现有的 DeepSeek API 调用层。

这里我建议把 AI 的任务限制在:

“根据已经计算好的数据总结当前技术状态。”

而不要直接让 AI 自己猜测历史行情。

例如可以让 AI 回答:

1. 当前均线属于多头还是空头排列?
2. MACD 是否出现近期金叉?
3. 成交量有没有明显变化?
4. 当前技术形态有哪些风险?
5. 哪些结论需要进一步回测验证?

这样 AI 更像一个“研究助手”,而不是一个凭感觉喊买卖点的机器人。


四、交易员避坑指南:AI 量化最容易忽略的 3 件事

避坑 1:AI 不能替代历史数据验证

如果 DeepSeek 告诉你:

“这个形态历史胜率很高。”

第一反应不要马上相信。

正确做法应该是:

AI 提出假设
↓
QuantDash 获取历史 K 线
↓
Pandas 生成信号
↓
历史回测
↓
统计胜率 / 收益 / 回撤
↓
再判断假设是否成立

AI 适合帮助你提出研究方向。

最终还是要靠数据验证。


避坑 2:技术指标越多,不代表策略越好

新手很容易这样写策略:

MA 金叉
+
MACD 金叉
+
KDJ 金叉
+
BOLL 突破
+
成交量放大

条件越堆越多,回测结果有时候反而越漂亮。

问题是:

很可能过拟合。

我的建议是先从一个核心逻辑开始:

趋势
+
一个确认指标

然后再通过历史数据验证是否真的有效。


避坑 3:不要把“回测正确”理解成“实盘一定赚钱”

历史数据稳定,只解决了第一层问题。

后面还有:

  • 滑点;
  • 手续费;
  • 印花税;
  • 成交价格;
  • 流动性;
  • 极端行情;
  • 策略容量。

所以我一般把量化研究分成三层:

第一层:数据正确
        ↓
第二层:策略有效
        ↓
第三层:交易可执行

稳定历史 K 线,是第一层的地基。


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

Q1:为什么 SuperMind 做 A 股技术指标策略时,需要稳定的历史 K 线 API?

A: 因为 MA、MACD、KDJ、BOLL 等指标全部建立在历史价格和成交量之上。QuantDash 可以通过 Python SDK 获取 A 股日 K 和分钟 K,并直接返回 Pandas DataFrame,减少数据转换和清洗工作。官方接口文档可参考:https://docs.quantdash.net/

Q2:QuantDash 获取 A 股 K 线时默认是什么复权方式?

A: K 线接口默认使用:

adjust="forward"

也就是前复权-比例。除此之外还支持 backwardnoneforward_additivebackward_additive。做收益率和技术指标研究时,应根据自己的策略口径选择复权方式。

Q3:QuantDash 能不能批量获取 A 股股票数据给 AI 分析?

A: 可以通过 qd.klines.batch() 批量获取多个标的的 K 线,再利用 Pandas 计算 MA、MACD 等指标,最后把结构化结果交给现有的 DeepSeek API 调用层。这样可以把“行情获取”和“AI 分析”分成两个独立模块,更容易维护和回测。


🔗 相关资源与延伸阅读

🚀 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/

评论