A股数据源怎么选?用 Python 验收 AI 复盘的日期与明细

选股票数据源时,很多比较从"覆盖多少接口"开始。我更想先拿到一份实际结果,回答三个问题:它对应哪一天,是否完整,报告里的总数能不能回到明细。

我参与维护悟道数据。本文使用我们已经公开的 2026-09-04 历史复盘 JSON,写一个可以独立运行的校验脚本。数据复核时间为 2026-09-07;这次验证的是公开文件的内部一致性,没有重新查询实时行情。

先把选型变成一个小任务

如果自己写 Python 做研究,可以按目标字段比较 AKShare、Tushare 等数据方案;如果让 Agent 调用数据,也可以评估已有 MCP 或自己封装工具。Tushare 已有官方 MCP 文档,AKShare 官方文档提供财经数据接口及数据字典,具体范围仍应逐项核对。

无论选哪种接入方式,都可以先给候选方案同一个验收任务:指定一个已收盘交易日,取市场概况、涨停统计、包含首板的完整梯队和题材资金,并保留请求参数与返回日期。

这比直接比较 AI 写出的复盘文字更容易发现问题。下面只针对悟道公开样例的字段结构演示;其他数据源需要先编写字段映射,不应直接拿这段脚本测试后就给竞品打分。

样例中要检查的约束

五个查询分别是 trading_calendar、market_overview、limit_stats、limit_up_ladder 和 theme_intraday_capital。题材资金的请求日期字段是 tradeDate,其余四个是 date。

检查项 要验证的关系
查询记录 五个工具各有一条请求,日期等于任务指定日期
返回日期 市场、梯队、统计、题材实际日期一致
明细去重 股票代码非空,没有重复代码
数量一致 涨停统计 = 梯队总数 = 明细行数
分组一致 逐行统计的连板分布 = 返回的分组汇总

注意,目标日期由命令行单独传入。如果只拿文件里的日期和文件自身比较,即使整份文件都错了一天,也可能看起来"全部一致"。

可运行的 Python 脚本

先将公开历史样例保存为 market-replay-2026-09-04.json,将下面代码保存为 verify_replay.py。使用 Python 3 和标准库运行,不需要把 API Key 放进脚本。本文处理的是公开摘录 JSON;正式 MCP 的协议响应需要先提取对应业务字段。

python 复制代码
import json
import re
import sys
from collections import Counter
from datetime import datetime


def require(ok, message):
    if not ok:
        raise ValueError(message)


def day(value):
    require(isinstance(value, str), "日期必须是字符串")
    require(re.fullmatch(r"\d{4}-\d{2}-\d{2}|\d{8}", value), "日期格式错误")
    return datetime.strptime(value.replace("-", ""), "%Y%m%d").date().isoformat()


def verify(doc, target):
    target = day(target)
    require(day(doc["tradeDate"]) == target, "样例交易日不符")
    tools = ("trading_calendar", "market_overview", "limit_stats", "limit_up_ladder", "theme_intraday_capital")
    require(Counter(item["tool"] for item in doc["requests"]) == Counter(tools), "五个查询记录不完整或重复")
    for request in doc["requests"]:
        args = request["arguments"]
        key = "tradeDate" if request["tool"] == "theme_intraday_capital" else "date"
        require(day(args[key]) == target, "请求日期不符")

    data = doc["data"]
    for tool in ("trading_calendar", "market_overview", "limit_stats", "limit_up_ladder"):
        require(day(data[tool]["date"]) == target, tool + " 返回日期不符")
    require(data["trading_calendar"]["isTradingDay"] is True, "目标不是交易日")
    capital = data["theme_intraday_capital"]
    require(day(capital["tradeDate"]) == target, "题材请求日期不符")
    require(day(capital["actualTradeDate"]) == target, "题材实际日期不符")

    ladder = data["limit_up_ladder"]
    rows = ladder["rows"]
    codes = [row["code"] for row in rows]
    require(all(isinstance(code, str) and code for code in codes), "股票代码为空")
    require(len(codes) == len(set(codes)), "股票代码重复")
    require(all(day(row["date"]) == target for row in rows), "明细日期不符")

    count = data["limit_stats"]["sealedLimitUp"]
    require(type(count) is int and count >= 0, "涨停数不是有效计数")
    require(type(ladder["totalStocks"]) is int, "梯队总数不是整数")
    require(count == ladder["totalStocks"] == len(rows), "统计与明细数量不符")
    actual = Counter(row["level"] for row in rows)
    summary = ladder["boardSummary"]
    require(len({item["level"] for item in summary}) == len(summary), "梯队分组重复")
    expected = {item["level"]: item["count"] for item in summary}
    require(dict(actual) == expected, "各梯队分布不符")
    return f"通过:{target},{count} 只,日期、去重与梯队分布一致"


if __name__ == "__main__":
    try:
        with open(sys.argv[1], encoding="utf-8") as file:
            print(verify(json.load(file), sys.argv[2]))
    except (OSError, ValueError, KeyError, TypeError, IndexError) as error:
        raise SystemExit(f"验收未通过:{error}")

运行命令:

bash 复制代码
python3 verify_replay.py market-replay-2026-09-04.json 2026-09-04

对本次公开文件的实际输出是:

text 复制代码
通过:2026-09-04,39 只,日期、去重与梯队分布一致

脚本没有把"必须等于 39"写进判断。39 来自这份历史文件;数量关系一致,才是需要验证的条件。本例按连板数分组为 5 板 1 只、2 板 6 只、首板 32 只,覆盖沪深及北交所非 ST 股票。

代码也没有直接相信样例中的 validation 字段,而是读取请求记录、实际日期、股票明细和分组数据重新计算。

故意改坏数据,再检查它会不会拦住

只跑通正确样例还不够。这次在本地对文件副本做了七种模拟修改:

模拟修改 实际结果
改掉一个请求日期 被拦截
改掉市场概况的返回日期 被拦截
重复一条股票明细 被拦截
删掉一条股票明细,保留原总数 被拦截
修改某个梯队的汇总数量 被拦截
删除涨停计数字段 被拦截
删除全部查询记录 被拦截

这些是人为构造的校验用例,不是线上发生了七次故障,也不是对服务可用性的统计。目的很具体:确认脚本遇到常见错误时会停止,而不会继续输出一份看似正常的复盘。

真实计数为 0 与字段缺失也应分开处理。代码直接读取必需字段,缺失会报错;不使用 get("sealedLimitUp", 0) 把没查到的数字补成零。

通过校验后,才能把数据交给 AI 整理

在一个简单的复盘流程里,可以先保存原始返回,提取业务字段并校验,再让 AI 整理观察。校验失败时保留错误,不从模型记忆或网页摘要补齐缺失数字。

悟道数据在这里提供面向 AI 助手的 A股结构化研究数据,通过远程 MCP 接入,覆盖行情、涨停梯队、题材、资金、龙虎榜、事件和复盘。是否使用现成工具层,取决于字段覆盖、客户端支持和愿意承担的维护工作;MCP 本身不保证数据正确,也不会自动替用户设置每天的定时任务。

这段脚本只是一组最小约束。它没有核验行情与交易所原始记录是否一致,没有测量延迟、权限、连续可用性或使用许可,也没有覆盖所有字段的类型和业务规则。即使校验通过,研究结论仍需结合更多证据。

选择股票数据源时,我建议先比较相同任务的实际返回,再比较需要补多少清洗、映射和错误处理。一个能被程序检查、能回到明细的结果,比一段没有出处的流畅总结更有用。

参考资料:

相关推荐
miofly13 分钟前
GitHub 今日推荐|MOSS-Image:靠坐标框精确控制文字排版的图像生成模型
python·开源·github
Tiandaren14 分钟前
么是agent、为什么要做agent、怎么做agent、怎么工程化
人工智能·python·深度学习·大模型
张张123y41 分钟前
后端第十一课:RAG 落地实战(从 0 到 1 接上私有知识库,并设计一个好用的 RAG)
开发语言·人工智能·python·机器学习·fastapi·rag
golang学习记1 小时前
Python vs Go:2026年到底该怎么选
java·vscode·python·golang·pycharm·goland
江厌011 小时前
移动工作站还是塔式?用三个数判断工位形态,再谈配置
python·移动工作站·塔式工作站·工作站选型·isv认证
川石课堂软件测试1 小时前
涨薪技术|0到1学会性能测试第8课-Analysis分析图
服务器·数据库·python·sql·jmeter·mysql·容器
学编程的小程1 小时前
服务器日志太分散不好查?我用Promtail+Loki+Grafana把采集、查询和分析串起来了
服务器·python·grafana
云水初1 小时前
【项目篇】基于LanGraph的自动处理客服邮件的 Agent汇总
开发语言·笔记·python·学习·fastapi·langgraph
香吧香2 小时前
venv 详解
python