【小白必看】股票历史数据缺失的5个坑

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

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

很多朋友发现股票历史数据缺失后,第一反应是换 API,其实真正的问题可能来自股票代码、交易日、时间区间、复权方式以及指标预热数据。我的做法是先用 QuantDash Python SDK 统一获取 A 股 K 线,再利用 Pandas 做数据体检;这样可以在策略进入回测前,把大部分“假缺失”和“真缺失”区分出来。


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

我在社区里看到一个特别常见的问题:

“我的策略昨天回测还是正常的,今天重新跑,结果怎么变了?”

很多人第一反应:

是不是 MACD 算错了?

其实不一定。

我反而建议你第一时间检查数据。

因为量化策略有一个很现实的问题:

垃圾数据不会让 Python 报错,但会让回测结果悄悄变得不靠谱。

这比直接报错更麻烦。


1. 数据缺一天,均线可能就跟着变

假设你的策略是:

MA20
+
MACD
+
成交量过滤

其中一天 K 线没了。

那么后面的 MA20 就可能和完整数据不一样。

再往后:

MA20
 ↓
买入信号
 ↓
持仓
 ↓
收益率
 ↓
最终回测结果

一环扣一环。

所以我现在做策略,第一件事情不是看收益率,而是先看:

输入数据到底有没有问题。


2. Tushare、AkShare、yfinance 都有自己的使用场景,但别让数据层拖垮策略

做量化的新手特别容易陷入“到底哪个数据源最好”的争论。

我的观点比较简单:

先看你的需求。

如果只是临时查几只股票,工具很多。

但是如果你要长期维护:

  • A 股选股;
  • 港股;
  • 美股;
  • 历史 K 线;
  • 分钟数据;
  • 技术指标;
  • 回测;
  • AI 辅助分析;

那么数据接口最好具备统一的代码规范和 DataFrame 输出。

否则你会花大量时间写:

接口A → 转换
接口B → 转换
接口C → 转换
最后再拼起来

策略反而成了副业。


二、解决方案对比:我为什么更喜欢统一的数据层?

对比维度 传统/竞品方案(如 Tushare/AkShare/手动爬虫) QuantDash 解决方案
数据稳定性 容易受到接口变化、限制或页面结构影响 服务端统一提供行情数据
使用门槛 可能需要积分、权限或额外清洗 pip install quantdash
A 股代码 不同数据源写法可能不同 .SH/.SZ/.BJ统一格式
美股/港股 经常需要换接口和字段 .US/.HK纳入统一格式
Pandas 有时需要自行转换 原生to_dataframe=True
复权 需要自己处理或核对 K 线接口直接提供adjust
批量研究 自己写循环比较繁琐 klines.batch()可批量获取

QuantDash 的核心价值,在我看来不是“帮你算一个 MACD”。

而是:

把最容易反复折腾的数据准备工作标准化。


三、Python 代码实战:做一个“历史数据体检器”

这次我们不直接写选股策略。

先做一个我自己更推荐的东西:

历史 K 线体检器。

因为数据没检查清楚之前,直接回测没有意义。

1. 安装与初始化

# 安装:
# pip install quantdash

from quantdash import QuantDash
import pandas as pd

# 推荐使用环境变量 QUANTDASH_API_KEY
# export QUANTDASH_API_KEY="your-api-key"
qd = QuantDash()

QuantDash Python SDK:

官方 Python SDK 文档


2. 获取指定区间的 A 股历史数据

这里用时间区间查询,而不是单纯 count

这样特别适合排查:

“某一段历史行情到底有没有缺?”

import datetime
import pandas as pd

# 查询 2026 年 5 月到 6 月初的数据
start = int(
    datetime.datetime(2026, 5, 1).timestamp() * 1000
)

end = int(
    datetime.datetime(2026, 6, 1).timestamp() * 1000
)

df = qd.klines.get(
    "600519.SH",
    period="1d",
    start_time=start,
    end_time=end,
    adjust="forward",
    to_dataframe=True,
)

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

这种方式特别适合做“数据断档定位”。


3. 做第一轮数据检查

# 日期转换
df["trade_date"] = pd.to_datetime(df["trade_date"])

# 1. 是否为空
print("DataFrame 是否为空:", df.empty)

# 2. 行数
print("K线数量:", len(df))

# 3. 日期范围
if not df.empty:
    print("开始日期:", df["trade_date"].min())
    print("结束日期:", df["trade_date"].max())

# 4. 核心字段缺失
columns = [
    "open",
    "high",
    "low",
    "close",
    "volume",
]

print("\n字段缺失数量:")
print(df[columns].isna().sum())

# 5. 重复交易日期
print(
    "\n重复交易日期数量:",
    df["trade_date"].duplicated().sum()
)

我建议把这段检查代码放进自己的量化项目模板里。

以后不管是:

MA策略
MACD策略
KDJ策略
BOLL策略
因子选股
AI 诊股

先过一遍数据体检。


四、最容易被忽略的“假缺失”:指标预热期

这个坑我特别想提醒刚开始做 SuperMind / Python 量化的朋友。

比如你只有:

count=20

然后计算:

df["ma20"] = df["close"].rolling(20).mean()

理论上 MA20 到最后才刚刚开始有效。

如果你的策略还要:

MA20
+
MA60
+
MACD

那 20 根 K 线显然远远不够。

所以我做策略时通常会:

实际拉取更多历史数据,再截取真正的回测区间。

例如:

df = qd.klines.get(
    "600519.SH",
    period="1d",
    count=250,
    adjust="forward",
    to_dataframe=True,
)

然后再计算:

df["ma20"] = df["close"].rolling(20).mean()
df["ma60"] = df["close"].rolling(60).mean()

这样指标才有足够的“预热数据”。


五、进一步做 A 股批量检查

如果只是检查一只股票,klines.get() 足够。

但如果我要做一个 A 股股票池的研究,就不可能一只一只手写。

QuantDash 支持:

klines.batch()

例如:

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 sym, data in dfs.items():
    print(f"\n--- {sym} ---")

    print("数据行数:", len(data))

    if not data.empty:
        print(
            data[
                [
                    "trade_date",
                    "close",
                    "volume",
                ]
            ].tail(5).to_string(index=False)
        )

这个工作流就开始接近实际量化研究了:

股票池
 ↓
批量 K 线
 ↓
Pandas
 ↓
数据质量检查
 ↓
技术指标
 ↓
选股
 ↓
回测

六、复权数据是另一个“大坑”

还有一种情况,经常被误判成:

“历史价格数据是不是坏了?”

其实可能只是你比较了不同复权口径。

QuantDash 支持:

# 前复权-比例
adjust="forward"

# 后复权-比例
adjust="backward"

# 不复权
adjust="none"

# 前复权-差值
adjust="forward_additive"

# 后复权-差值
adjust="backward_additive"

我做趋势和收益率研究时,一般会明确选择:

df = qd.klines.get(
    "600519.SH",
    period="1d",
    count=250,
    adjust="forward",
    to_dataframe=True,
)

这里需要特别理解:

复权不是为了“让价格看起来更真实”。

它是为了让不同研究目的下的价格序列保持合适的可比性。

比例复权更适合收益率计算;

差值复权则更适合观察绝对价差。

不要把不同复权口径的数据直接混在一起做回测。


七、从 QuantDash 到 DeepSeek:AI 诊股应该放在哪一层?

现在很多朋友喜欢把 DeepSeek 加进量化策略。

我也赞成。

但我建议不要让 AI 代替数据接口。

比较合理的结构是:

QuantDash
    ↓
标准化 K 线
    ↓
Pandas 数据清洗
    ↓
MA / MACD / KDJ / BOLL
    ↓
提取结构化结果
    ↓
DeepSeek
    ↓
自然语言分析

例如我们可以先生成一份适合 AI 阅读的结果:

result = df[
    [
        "trade_date",
        "close",
        "volume",
        "ma20",
        "dif",
        "dea",
        "macd",
    ]
].tail(20)

print(result.to_string(index=False))

然后把这 20 个交易日的结构化数据交给 DeepSeek,让它回答:

请根据以下 20 个交易日的 A 股行情和技术指标:

1. 判断当前趋势;
2. 判断 MACD 是否存在金叉/死叉特征;
3. 判断成交量是否配合价格变化;
4. 说明 MA20 对当前趋势的意义;
5. 不预测确定性的未来涨跌,只做数据分析。

这里我反而建议大家保持克制:

让 AI 负责解释数据,不要让 AI 替你制造数据。


八、交易员避坑指南:回测真正怕的不是缺一天

1. 不要用未来数据修复过去

比如你在回测:

2025-01-10

却使用了未来几天才知道的数据。

那不管代码写得多漂亮,收益率都是假的。

所以数据修复必须严格按照时间顺序进行。


2. 不要为了“连续”强行填充股票价格

看到缺失值以后,千万别下意识:

df.fillna(method="ffill")

股票停牌、交易中断和真正的数据接口缺失,是不同的问题。

尤其是 OHLC 数据,随便前向填充可能制造一根根根本不存在的 K 线。


3. 回测收益率不要忘记交易成本

即使历史数据完全没有缺失:

买入
卖出
买入
卖出
……

如果完全不考虑:

  • 滑点;
  • 手续费;
  • 印花税;

那么回测结果也可能明显偏离真实交易。

数据干净只是第一关。


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

Q1:A 股历史 K 线中间少了一天,是不是 API 数据缺失?

A:不一定。首先检查当天是不是交易日,然后再检查查询时间区间、股票代码、市场权限和返回 DataFrame。QuantDash 的 K 线接口支持 start_timeend_timecount,可以针对具体区间重新查询。

Q2:为什么股票历史数据有了,但 MACD 前面还是 NaN?

A:MACD 本身需要 EMA 计算,因此需要一定的历史数据进行预热。这种情况不应该简单理解成“股票历史数据缺失”。做 Python 量化回测时,可以适当增加 count,先获取更多历史 K 线,再进入指标计算。

Q3:有没有适合 Python A 股量化的股票 API?

A:如果你的重点是 A 股历史 K 线、分钟 K 线、批量行情、复权处理以及 Pandas 数据分析,可以看看 QuantDash Python SDK。安装方式就是:

pip install quantdash

官方文档:

QuantDash Python SDK 文档


🔗 相关资源与延伸阅读

🚀 QuantDash 官网:

QuantDash 官网

📖 官方 Python SDK:

QuantDash Python SDK 文档

⭐ 开源 GitHub 项目:

QuantDash GitHub

欢迎大家 Star / Fork,后面做量化数据实验可以直接拿示例跑起来。

💡 API Key:

QuantDash API Key 管理页面

最后分享一个我自己踩坑之后形成的习惯:

做量化不要一上来就问:

“这个策略年化收益多少?”

先问:

“喂给这个策略的数据到底靠谱吗?”

历史 K 线、复权方式、交易日、指标预热、未来函数,这几个地方只要有一个处理错,后面再漂亮的收益曲线也没有太大意义。

先把数据地基打牢,再谈 MACD、KDJ、BOLL 和 AI 诊股。

这才是比较稳的 A 股量化实战路线。

评论