本文档基于当前目录下的两份调研文档和已完成的实际验证结果整理,目标是给一个“零注册、零 token”的 A 股分析 / 研究应用提供可直接落地的数据源选型、分层和 failover 参考方案。
本方案面向第一版可落地产品,原则如下:
- 不依赖注册、积分、token
- 优先选择当前网络环境下已经实测可用的数据源
- 按数据类型拆分链路,不强行用单一数据源覆盖全部能力
- 主链路优先稳定,其次才考虑字段丰富度
- 允许不同能力使用不同主源
主链路:
BaoStockpytdx
兜底:
TickFlow免费层yfinance
主链路:
腾讯直连 HTTP新浪直连 HTTP
主链路:
TickFlow免费层
补充:
BaoStockpytdx
AKShareefinanceTushare Pro- 强依赖 Eastmoney API 的链路
原因:
- 当前网络环境下 Eastmoney API 实测不稳定
- 新浪 HTTPS 证书链在当前机器上存在问题
- Tushare Pro 需要注册和 token,不符合第一版目标
| 能力 | 主推荐 | 原因 |
|---|---|---|
| 历史日线 | BaoStock |
免费、稳定、无需 token、适合做历史主链路 |
| 历史补充 / 次主源 | pytdx |
TCP 直连,不依赖网页接口,适合作为强兜底 |
| 实时行情 | 腾讯直连 HTTP + 新浪直连 HTTP |
当前环境下最快、最轻、无需注册 |
| 标的信息 | TickFlow 免费层 |
结构较清晰,直接支持标的信息查询 |
| 海外兜底 | yfinance |
适合最后一层历史兜底,不建议前置 |
建议不要做一个“大一统数据源类”直接覆盖所有接口,而是按能力拆成 3 层:
职责:
- 日线 / 周线 / 月线查询
- 批量历史拉取
- 历史回测 / 技术指标输入
推荐实现:
HistoricalDataProvider- 每个数据源单独实现一个 adapter
建议适配器:
BaoStockHistoricalAdapterPytdxHistoricalAdapterTickFlowHistoricalAdapterYFinanceHistoricalAdapter
职责:
- 单只股票实时行情
- 小批量股票实时行情
- 盘中快照
推荐实现:
RealtimeQuoteProvider
建议适配器:
TencentQuoteAdapterSinaQuoteAdapter
职责:
- 股票代码、名称、交易所
- 上市日期
- 基本静态元数据
推荐实现:
InstrumentProvider
建议适配器:
TickFlowInstrumentAdapterBaoStockInstrumentAdapterPytdxInstrumentAdapter
推荐顺序:
BaoStock -> pytdx -> TickFlow -> yfinance
BaoStock最稳定,适合优先承担历史主链路pytdx同样稳定,但更适合做高可用备份TickFlow免费层可做补充,但不建议单独承担全部历史能力yfinance适合最后兜底,避免国内源全部失败时无数据
遇到以下情况切换到下一个源:
- 请求超时
- 返回空数据
- 返回错误码或解析失败
- 返回数据条数明显不够
- 返回最新交易日落后过多
对历史数据建议做最小一致性校验:
- 检查是否包含
date/open/high/low/close/volume - 检查价格字段是否可转数值
- 检查时间序列是否升序或可排序
- 检查最近一条记录日期是否合理
推荐顺序:
腾讯直连 HTTP -> 新浪直连 HTTP
- 两者都无需注册
- 接口简单,响应快
- 当前环境下已实测可拿到 A 股实时数据
遇到以下情况切换:
- HTTP 非 200
- 返回内容为空
- 返回格式不符合预期
- 指定股票未出现在返回结果中
- 响应时间超过阈值
- 单只查询优先用主源
- 小批量查询支持拆分请求
- 给主源设置较短超时,例如
2-3 秒 - 主源失败立刻切到次源,不重试过多次
推荐顺序:
TickFlow -> BaoStock -> pytdx
TickFlow免费层的标的信息结构更适合直接消费BaoStock可补基础静态信息pytdx可在最后兜底股票列表或证券基础信息
遇到以下情况切换:
- 查询结果为空
- 代码格式不匹配
- 缺失关键字段,如代码、名称、交易所
为了减少后续维护成本,建议每类能力只暴露“统一标准模型”,不要把底层返回结构直接暴露给业务层。
[
"symbol",
"trade_date",
"open",
"high",
"low",
"close",
"volume",
"amount",
"source",
][
"symbol",
"name",
"price",
"open",
"high",
"low",
"pre_close",
"volume",
"amount",
"quote_time",
"source",
][
"symbol",
"code",
"exchange",
"name",
"market",
"list_date",
"instrument_type",
"source",
]内部统一建议使用:
600519.SH
000001.SZ
430001.BJ
原因:
- 比纯六位代码更清晰
- 比
sh.600519更通用 TickFlow、yfinance映射也更容易做
| 内部格式 | 数据源格式 |
|---|---|
600519.SH |
BaoStock: sh.600519 |
600519.SH |
pytdx: market=1, code=600519 |
600519.SH |
腾讯/新浪: sh600519 |
600519.SH |
TickFlow: 600519.SH |
600519.SH |
yfinance: 600519.SS |
- 先查本地缓存
- 未命中时优先请求
BaoStock - 若失败则切到
pytdx - 若
pytdx也失败,则尝试TickFlow - 最后才用
yfinance - 成功后统一标准化并写入缓存
- 不建议强缓存过久
- 可做短缓存,例如
3-10 秒 - 主源腾讯失败时立即切新浪
- 对同一股票短时间内避免重复请求
- 适合长缓存
- 每日或每周做一次刷新即可
- 首次查询未命中时走
TickFlow - 若
TickFlow失败,再查BaoStock/pytdx
| 数据类型 | 建议 TTL |
|---|---|
| 标的信息 | 1 天 - 7 天 |
| 历史日线 | 交易日内可视为稳定,收盘后刷新 |
| 实时行情 | 3 秒 - 10 秒 |
| 股票列表 | 1 天 |
- 实时接口:短超时
- 历史接口:中等超时
- TCP 数据源:允许比 HTTP 更长的超时
参考值:
实时 HTTP: 2-3 秒
历史 HTTP: 5-8 秒
pytdx TCP: 5-10 秒
- 实时行情:最多重试 1 次
- 历史数据:最多重试 2 次
- 切源优先于无意义重试
建议按“能力降级”而不是“服务整体失败”处理:
- 实时失败时,页面可降级显示上一笔缓存
- 历史失败时,提示当前数据源不可用并尝试次源
- 标的信息失败时,允许仅展示代码、不阻塞主流程
可参考下面的目录设计:
datasources/
base/
models.py
exceptions.py
normalizers.py
historical/
baostock_adapter.py
pytdx_adapter.py
tickflow_adapter.py
yfinance_adapter.py
manager.py
realtime/
tencent_adapter.py
sina_adapter.py
manager.py
instruments/
tickflow_adapter.py
baostock_adapter.py
pytdx_adapter.py
manager.py
职责:
- 统一入口
- 顺序尝试数据源
- 标准化输出
- 记录命中源
- 写缓存
伪代码:
for adapter in [baostock, pytdx, tickflow, yfinance]:
try:
data = adapter.get_history(symbol, start, end, interval="1d")
if validate_history(data):
return normalize_history(data, source=adapter.name)
except Exception as e:
log_warning(adapter.name, e)伪代码:
for adapter in [tencent, sina]:
try:
data = adapter.get_quote(symbol)
if validate_quote(data):
return normalize_quote(data, source=adapter.name)
except Exception as e:
log_warning(adapter.name, e)伪代码:
for adapter in [tickflow, baostock, pytdx]:
try:
data = adapter.get_instrument(symbol)
if validate_instrument(data):
return normalize_instrument(data, source=adapter.name)
except Exception as e:
log_warning(adapter.name, e)- 不要把实时、历史、标的信息混在一个 failover 链里
- 不要依赖单一的“大而全”免费数据源
- 不要在第一版就把 Eastmoney 体系当核心
- 不要把 legacy 接口能力误当成长期稳定承诺
- 不要把底层源的原始字段直接返回给业务层
如果目标是“先稳定跑起来”,建议按下面方案实现:
主源: BaoStock
备源: pytdx
补充: TickFlow
最终兜底: yfinance
主源: 腾讯直连 HTTP
备源: 新浪直连 HTTP
主源: TickFlow
备源: BaoStock
兜底: pytdx
对于一个零注册的 A 股研究应用,当前最现实、最稳的方案不是选择单一“万能数据源”,而是:
- 用
BaoStock + pytdx解决历史数据稳定性 - 用
腾讯/新浪直连 HTTP解决实时行情 - 用
TickFlow免费层解决标的信息和补充日线 - 用
yfinance做最后一层海外兜底
这个组合的核心优势是:
- 不需要注册
- 不需要 token
- 不强依赖当前环境下不稳定的 Eastmoney 链路
- 可以按能力拆分,后续逐步替换和增强
如果后续要做第二版,再考虑把 Tushare Pro 或更专业的数据服务接入进来会更合理。
附录(验证报告):
验证时间:2026-03-26(Asia/Shanghai)
- 仅做“当前网络环境下”的基础验证
- 明确跳过“必须注册 / 必须 token”前提的主流程验证
- 重点看:是否能直接拉到 A 股实际数据,而不是只看官网能否打开
- 新建临时 Python 环境并安装相关库
- 对每个候选源执行 1-2 个最小可用调用
- 优先验证:
- 实时行情
- 历史日线
- 标的信息 / 股票列表
- 补充验证了底层网络特征:
- Eastmoney API
- 新浪 / 腾讯直连 HTTP
- TickFlow 免费层限制
| 数据源 | 实测可用能力 | 结论 |
|---|---|---|
| 新浪直连 HTTP | 实时行情 | 可直接用 |
| 腾讯直连 HTTP | 实时行情 | 可直接用 |
| BaoStock | 历史日线 | 可直接用 |
| pytdx | 历史日线 / TCP 行情直连 | 可直接用 |
| yfinance | A 股历史日线 | 可直接用 |
| TickFlow(免费层) | 标的信息、历史日线 | 可直接用 |
| 数据源 | 实测情况 | 结论 |
|---|---|---|
| efinance | 单票实时行情可用;历史日线失败;全市场实时批量失败 | 部分可用 |
| Tushare(旧接口) | get_realtime_quotes 可用 |
部分可用,且应视为 legacy 路线 |
| AKShare | 股票列表可用;东财历史 / 实时失败;新浪历史 SSL 失败;新浪实时超时 | 部分可用,但当前环境下不适合作主数据源 |
| 数据源 | 原因 |
|---|---|
| Tushare Pro | 主流程依赖注册和 token,本次按要求跳过 |
- 测试接口:
http://hq.sinajs.cn/list=sh600519 - 结果:成功返回
var hq_str_sh600519=... - 判断:当前环境下可直接作为轻量实时行情源
- 测试接口:
http://qt.gtimg.cn/q=sh600519 - 结果:成功返回
v_sh600519=... - 判断:当前环境下可直接作为轻量实时行情源
- 成功:
stock_info_a_code_name()可返回约 5493 条 A 股代码
- 失败:
stock_zh_a_hist(...)走 Eastmoney,失败stock_zh_a_spot_em()走 Eastmoney,失败stock_zh_a_daily(...)走新浪 HTTPS,证书校验失败stock_zh_a_spot()在本环境中 25 秒超时
- 判断:
- 不是“完全不可用”
- 但当前环境下历史 / 实时核心链路都不稳定,不建议作为主源
- 成功:
get_latest_quote('600519')可用
- 失败:
get_quote_history('600519', ...)走 Eastmoney 历史接口,失败get_realtime_quotes()全市场批量接口返回 JSON 解析失败
- 判断:
- 可做单票实时补充
- 不适合当前环境下承担历史数据或全市场批量主链路
- 成功:
login()query_history_k_data_plus(...)
- 返回:成功取到 2024-01-02 至 2024-01-10 的 7 条日线
- 判断:当前环境下是可靠的免费历史数据源
- 成功:
- TCP 直连通达信服务器
- 从
218.75.126.9:7709成功取到600519最近 10 条日线
- 特征:
- 前几个预置服务器不一定成功,实际落到 failover 后的服务器
- 单次验证耗时约 20.63 秒
- 判断:可用,适合历史行情 / K 线兜底
- 成功:
yf.download('600519.SS', start='2024-01-02', end='2024-01-10')
- 返回:6 条历史记录
- 判断:可作为 A 股历史数据的海外兜底源,但不建议做主源
- 成功:
tushare.get_realtime_quotes('600519')
- 说明:
- 这是无需 token 的旧接口,不等同于 Tushare Pro
- 判断:
- 现在能用,但更适合当兼容补充,不建议把产品主架构压在 legacy 接口上
- 成功:
- 免费层可查询标的信息:
600519.SH - 免费层可查询历史日线:最近 5 条
- 免费层可查询标的信息:
- 失败:
- 免费层实时行情会明确报
PermissionError
- 免费层实时行情会明确报
- 判断:
- 免费层适合“标的信息 + 日线”
- 不适合实时行情
curl -I https://push2his.eastmoney.com可返回404- 但请求实际 JSON API 时:
curl返回Empty reply from server- Python 库侧表现为
ProxyError/ 连接被远端关闭
这说明当前环境下,Eastmoney 的 API 根链路存在实际可用性问题。
curl -I https://stock.finance.sina.com.cn返回:SSL certificate problem: unable to get local issuer certificate
- 这与
AKShare stock_zh_a_daily(...)的失败现象一致
- 直接
pip install首次失败 - 追加
--trusted-host后安装成功
这说明当前机器存在一定的证书信任链 / 网络代理环境问题,后续凡是依赖 HTTPS 校验严格的网站,都可能再踩一次。
如果你现在就开始做一个“零注册 / 零 token 可落地”的 A 股研究应用,建议当前环境下先按下面的组合来:
- 历史日线主链路:
BaoStock + pytdx - 实时行情主链路:
腾讯直连 HTTP + 新浪直连 HTTP - 标的信息 / 免费补充:
TickFlow 免费层 - 海外兜底:
yfinance - 谨慎使用:
AKShare、efinance
不建议当前环境直接把下面两类放到主链路:
- 强依赖 Eastmoney API 的链路
- 强依赖新浪 HTTPS 证书链正常的 AKShare 子接口
如果目标是“先快速做出能跑的 A 股研究应用”,当前环境下最现实的可用数据组合是:
- 历史:BaoStock、pytdx、yfinance
- 实时:腾讯直连 HTTP、新浪直连 HTTP
- 标的信息 / 免费日线补充:TickFlow 免费层
AKShare 和 efinance 在这台机器当前网络环境里都不够稳,不建议作为第一版核心依赖。