A股实时数据API:请求成功,不等于名单里每只票都有数据

举报
Walter_老白量化 发表于 2026/10/20 09:54:39 2026/10/20
【摘要】 本文写给负责自选股看板的产品经理,以及参与投研数据源选型的负责人。接入A股实时数据API之后,怎么确认名单里每只股票这一轮都拿到了数据?怎么避免把没返回的行、或者旧价格,当成正常更新?文章用批量行情快照的真实结果,加上国内外机构资料和反例,把名单核对、数据时间和交易窗口拆开讲,并提供页面检查清单、Python脚本和五项边界自测材料,可以直接转给技术同事验证。

摘要:本文写给负责自选股看板的产品经理,以及参与投研数据源选型的负责人。接入A股实时数据API之后,怎么确认名单里每只股票这一轮都拿到了数据?怎么避免把没返回的行、或者旧价格,当成正常更新?文章用批量行情快照的真实结果,加上国内外机构资料和反例,把名单核对、数据时间和交易窗口拆开讲,并提供页面检查清单、Python脚本和五项边界自测材料,可以直接转给技术同事验证。


本文回答三个问题:

  1. 批次成功,为什么名单可能不全?(第一章)
  2. 一条记录拿到了,怎样判断它是否可用?(第二章)
  3. 少一行数据,会影响哪些后续工作?(第六章)

接入A股实时数据API时,最容易忽略的问题不是请求失败,而是请求成功之后名单不全。10月19日15:52,收盘后我做了一次受控测试:输入三个代码——两只正常股票,加一个受控的无效代码。请求返回成功,两只正常股票都有记录,第三个代码没有出现。

如果页面只显示一个“更新成功”,使用者根本不知道:这一轮到底谁拿到了数据,谁还需要处理。请求成功了,名单里却有一行没有行情。

解决办法不复杂:从原始名单逐只核对,再结合每条记录的时间和交易窗口,给每一行一个说明。TickDB为行情应用提供市场数据,本例用的是它的REST批量行情快照,一次按需查询;交易日历和交易时段也参与检查。最终,名单里的每一行都要有交代。


一、A股实时数据API批次成功,为什么名单可能不全

本节结论:批次成功与名单齐全,要分别检查。

这次输入的是 600519.SH、000001.SZ、999999.SH。接口返回 HTTP 200、业务码 code=0,结果列表里只有前两只;受控代码 999999.SH 缺席。

输入代码 是否返回 说明
600519.SH 返回 正常股票
000001.SZ 返回 正常股票
999999.SH 未返回 受控无效代码,不计入正常样本

读法:本表按2026年10月19日15:52的独立受控测试整理;核对后的应用提示不是接口返回的一条记录。

这个结果直接说明了一件事:批次成功与名单齐全,要分别检查。

HTTP标准里,200只表示请求到了服务器、被受理了。返回内容到底对不对,要按具体请求去看。它不会替你核对“输入的代码是不是都在结果里”。RFC 9110,第15.3.1节。

同组还独立查了两个受控代码,并测了 symbols 参数为空和缺失的情况。前两项成功返回空列表;空参数、缺参数两项返回 HTTP 400、业务码 2001。五项原始响应都保留在附件里。

这些结果只对本次输入、这个账户、收盘后这个时段有效。它们没有验证退市、代码变更或权限不足时会发生什么,也不能推出“只有参数错误才会整批失败”。收盘后测试,看的是返回结构;盘中数据是不是按要求更新,要另外查。

如果你是产品经理,这句话可以直接写进需求:原名单里的每一行,这一轮要么有结果,要么有待处理说明。只遍历返回列表,你看到的是“谁回来了”;只有对照原名单,才能发现“谁还没回来”。

如果选择暂留上次价格,记得把上次的数据时间和“本轮未收到”一起带上。缺席的行不能悄悄删掉,也不能填成0,更不能直接标成停牌。

批次层与行级层,是两个检查对象

批次层:  HTTP 200 / code=0  ──►  批次受理成功
                │
                ▼
行级层:  返回列表 [600519.SH ✓, 000001.SZ ✓]
                │
                ▼
        应用层逐行对照原名单
                │
        ┌───────┼───────┐
        ▼       ▼       ▼
    received received  missing
                     (999999.SH)

读法:批次受理成功,不等于行级逐条返回;missing 只有在应用层逐行对照时才会出现。

所以下一章要把“行有没有回来”推进到“回来的行能不能用”。


二、A股实时数据API的两个时间:数据时间与本机接收时间

本节结论:产品团队需要同时知道——数据源标注了什么时间,你的系统什么时候收到它。

回看同日上午的正常查询。北京时间10:07:40.949,脚本收到三只股票的行情快照:

股票代码 返回价格 数据时间(北京) 本次应用结果
600519.SH 1343.99 10:07:36.000 已收到,符合示例时间要求
000001.SZ 11.57 10:07:36.000 已收到,符合示例时间要求
300750.SZ 272.38 10:07:36.000 已收到,符合示例时间要求

读法:输入三行,报告也保留三行;本表是上午正常样本,和下午混入无效代码的控制测试分开看。

行情、日历和时段查询都成功,日历包含当天,时段和沪深常规连续竞价窗口一致。

拿11.57这条记录来说,产品团队需要同时知道两件事:数据源标注的是什么时间,你的系统是什么时候收到它的。这条记录的数据时间是10:07:36.000,本机接收时间是10:07:40.949,两者差了大约4.9秒。

两个时间,一条时间轴

10:07:36.000                          10:07:40.949
    ●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━●
    │◄────────── 约 4.9 秒 ──────────►│
    │                                  │
数据时间                            本机接收时间
(这条记录标注的时刻)              (你拿到它的时刻)

     ├──── 距今 ≤ 120 秒 ────► received
     └──── 距今 > 120 秒 ────► stale(应用层阈值)

读法:120秒是可调整的应用演示参数,不是TickDB的时效承诺;4.9秒是源时间与本机接收时间的差值,不是端到端延迟测量。

脚本把连续竞价时段的数据时间要求设成120秒,所以三行都通过了这次检查。

向供应商确认时,还要问清一件事:这个时间戳到底是哪个环节的时间?成交发生、行情记录生成、服务更新、本机接收,可能是四个不同的时刻。接口的快照字段说明中,timestamp 为毫秒Unix时间戳,本篇按返回的数据时间使用,不自行解释为每笔成交的精确发生时间。

三只股票这次时间值相同,也只能说明这一次观察。它不能证明数据源始终同步,也不能证明所有记录都来自同一个严格一致的源快照。

时间有了,下一章要问:价格没变,是不是就一定有问题?


三、价格没变,先别急着判成数据停更

本节结论:数字有没有跳动,不能单独说明数据连接是否正常。

价格一直没动,就一定是接口卡住了吗?

Nasdaq的投资者教育材料提醒:最近成交价来自最近一笔成交;成交少的证券,价格可能很久才变一次。所以,光看数字有没有跳动,判断不了数据连接是不是正常。Nasdaq:Why Real-Time Data Matters When Trading Stocks。

这个反例会改变检查方法:价格、数据时间、当前交易状态要放在一起看,还要理解时间字段的含义。只看价格不够,只看一个时间戳也诊断不了故障。

如果记录超过团队设置的时间要求,页面可以显示“截至某时,待核对”,再查原始响应、交易状态、权限和本机时钟。不要直接把它写成“股票停牌”或“供应商故障”。

这次还没有做连续快照推进和同批时间戳分布的盘中观察,也没有真实的过期报价案例。文章没有把“价格未变、时间未推进”包装成亲历故障——这些问题得靠新的盘中记录来回答。

价格不动要看时间,时间还要放回交易窗口里看。下一章处理午间这个典型窗口。


四、午间休市:旧价格可以保留,时间和状态要一起保留

本节结论:旧价格可以保留,时间与状态也应一起保留。

同一条上午的数据,放在12:10和连续竞价时段,页面该怎样说明?

沪深交易规则都把股票常规竞价分成开盘集合竞价、连续竞价和收盘集合竞价。连续竞价为9:30—11:30、13:00—14:57,收盘集合竞价为14:57—15:00。午间没有连续竞价,不宜照搬盘中的时间要求。上交所2026年修订规则第2.4.2条 · 深交所2026年修订规则第2.3.2条。

时段 时间 本例处理方式
开盘集合竞价 9:15—9:25 单独处理,不套连续竞价阈值
连续竞价(上午) 9:30—11:30 适用示例120秒检查
午间间隔 11:30—13:00 保留最近数据和截至时间
连续竞价(下午) 13:00—14:57 适用示例120秒检查
收盘集合竞价 14:57—15:00 单独处理
盘后固定价格交易 15:05—15:30 另做处理

读法:区段宽度不按时长比例;示例时间阈值适用于上午和下午两段连续竞价,集合竞价单独处理。

一个可行的页面方案是:午间保留最近数据和它的截至时间,提示“当前处于午间间隔”;进入连续竞价后,再按团队约定检查。临时停市、个股停复牌、盘后固定价格交易,另做处理。

国外专业机构也提供了“旧记录可以有明确用途”的反例。IBKR的TWS API区分Live、Frozen、Delayed和Delayed Frozen;Frozen用于取得收盘时最后记录的数据。记录较旧,可能来自明确的数据类型和使用安排。IBKR:Delayed Market Data。

这里借鉴的是“把数据类型和用途讲清楚”这个做法;IBKR的分类不等于TickDB返回的字段。对采购团队来说,更值得确认的是:账号拿到的是什么类型的数据、哪些时段提供什么记录、页面怎么告诉使用者。

旧价格可以保留,时间与状态也应一起保留。午间有截至时间的上午价格,和盘中没有说明的旧价格,带给使用者的信息并不相同。

时间检查过了,价格也解释了,下一章要问:这个价格能拿来做什么?


五、最近成交价已取得,仍要明确它用来做什么

本节结论:用最新成交价观察自选股列表和研究名单是一类任务;判断买卖能否成交、多少数量能成交,则需要进一步核对买卖报价、数量和交易规则。

通过了这次时间检查,能不能直接把这条价格用作下单依据?

快照字段说明把 last_price 定义为最新成交价。深交所规则把最近成交价与买卖申报价格、数量分别列入即时行情,它们表达的是不同的信息。快照字段定义 · 深交所规则第5.2.2条。

美国SEC的Investor.gov也提醒:最近成交价,不一定是市价单最终成交的价格。这里引用的是这个概念区别,不套用美国交易制度。

用最新成交价观察自选股列表和研究名单,是一类任务;判断买卖能不能成交、多少数量能成交,要另外核对买卖报价、数量和交易规则。

所以,本例里的 received 只表示这一行通过了本次应用检查,不代表交易许可,也不保证成交价格。需求里要写清“这格价格用来做什么”,别让下游把列表展示的结果直接拿去做交易判断。

单行可用性讲完了,下一章看单行缺失会怎样传导到下游。


六、少一行数据,会影响哪些后续工作?

本节结论:产品与选型讨论因此不能只问更新速度,还应分别检查完整性、时间含义和异常处理。

设想一个团队用自选股名单来驱动页面和价格提醒。如果某一行这一轮缺席,页面继续显示旧值、又没有任何提示,使用者就分不清:是价格没变,还是这一轮根本没拿到数据。

如果后面的提醒又直接用这个旧值,影响还会传到提醒判断上。这是产品设计里要处理的条件场景;本次测试没有测量客户损失、返工成本或实际策略影响。

一行 missing 的下游传导

某行本轮 missing
      │
      ▼
页面继续显示旧值,无提示
      │
      ▼
使用者无法判断:没变化 / 没拿到数据
      │
      ▼
提醒/下游判断使用旧值
      │
      ▼
判断失真,且难以回溯

读法:条件场景示意,非实测损失;本次测试没有测量客户损失、返工成本或实际策略影响。

所以,产品与选型讨论不能只问“更新速度”,还要分别检查完整性、时间含义和异常处理。巴塞尔委员会的风险数据原则,也是把准确性、完整性和时效性分开提的,并说明时效要求取决于风险性质和用途。这套原则面向银行风险数据,本篇借的是“分维度检查”这个思路,不把它当成行情看板的监管要求。BIS/巴塞尔委员会第36.18节。

下面这张检查单可以直接交给产品与技术同事:

页面或报告里看到什么 还不能直接得出什么结论 交付时怎样处理
请求成功 原名单全部有数据 从原名单逐行核对返回代码
本轮没有某行记录 停牌、退市或权限不足 留行、说明待核原因,再查原始返回
价格没有变化 数据连接停更 核对数据时间、字段含义及交易状态
午间停在上午价格 必须清空或报故障 保留截至时间,说明午间间隔
最近成交价已取得 下一笔可按该价成交 按用途另查买卖报价与交易条件

读法:左列是页面现象,中列是不能直接下的结论,右列是交付时的处理动作。

验收单上再加三个问题:缺席的时候,保留什么、暂停什么?出了问题,能不能定位到原始响应、用同一份名单重跑?账号范围、调用额度、展示和再分发权限,确认了吗?一次成功查询,证明不了这些许可。

问题讲清了,下一章给两份可以直接跑的工具。


七、A股实时数据API名单核对:正常名单与边界输入

文章附件有两份Python脚本,需要Python 3.9及以上版本,只用标准库;本机要有可用的受信任HTTPS证书库。密钥通过环境变量传入,放在服务端使用。

正常名单:生成逐行报告

export TICKDB_API_KEY='你的密钥'
python3 batch_watchlist.py \
  --symbols 600519.SH,000001.SZ,300750.SZ \
  --freshness-seconds 120 \
  --output watchlist_run_01

快照接口规定单次最多50个代码。脚本先去重分批,最后按原名单回填,重复输入行仍保留。批量查询的 symbols 参数支持多个代码。

输出包括逐行CSV、各批次和日历/时段的原始响应、运行汇总。CSV里保存代码、数据时间、接收时间、窗口、状态、原因和下一步;价格按代码到原始响应里核对。

received 表示这一行通过了本次连续竞价时间检查;missing 表示成功批次里没有所查的代码;stale 表示超过了应用阈值;请求、字段或交易窗口不足以判断时,记为 unknown。全部行都是 received,退出码为0;有待处理行,退出码为1;参数或密钥缺失,退出码为2。午间这类窗口也可能得到 FAIL,要看行级原因,别直接当成数据源故障。

边界输入:记录接口怎样响应

python3 boundary_probe.py boundary --output boundary_run_01

边界采集器先查CN目录,再发出五组受控输入,保存 boundary_cases.csv、原始响应和请求元数据。和正常名单脚本不同,它会真的向服务端发空参数和缺参数请求。复跑时,“目录未见代码”这一项要按当次目录重新选;结果怎么解释,要看目标接口自己的约定。

自测内容 本次观察 复跑时检查什么
指定受控代码 成功返回空列表 是否有记录,错误或空结果如何表达
本次目录未见代码 成功返回空列表 目录范围与返回结果能否对应
正常代码加受控代码 正常两只返回,控制代码缺席 逐行核对能否指出缺席代码
参数显式为空 HTTP400/业务码2001 与文档约定是否一致
参数缺失 HTTP400/业务码2001 与文档约定是否一致

读法:本表记录本次观察,不代表所有数据API都用同一种错误策略;采集器的 PASS 只表示五项都拿到了HTTP响应。

每次跑都另建输出目录,保留旧记录。上午三只股票的正常结果、下午五项边界结果和完整代码都随文提供;连续时间戳分布、推进观察、真实过期报价,以及超过50只代码的盘中运行,尚未完成。正常名单脚本只接六位代码加 .SH 或 .SZ,不能拿它推断TickDB全部市场范围。


常见问题

Q1:第一次接入A股实时数据API,先做什么?

先确定页面用途和需要的数据对象,再选两三只有查询权限的股票,跑一遍正常名单检查。产品经理可以先读样本CSV和检查单,把自己的名单和展示要求交给技术同事。

Q2:缺失或超过时间要求,怎样定位和重跑?

先看行级原因,再查对应原始响应里的HTTP状态、业务码、代码和时间。复核权限、交易窗口和本机时钟之后,另建目录重跑。证书校验失败,就修信任配置,别关掉HTTPS校验。

Q3:后续怎样用于持续看板?

本例完成的是REST按需快照检查。持续更新,可以按需求设计重复查询,也可以另外验证WebSocket推送;两种方式都要安排异常复查和监控。本文没有验证持续推送、断线恢复或消息完整性。


请求成功之后,原名单里的每一行仍应有交代:有没有拿到数据、来自什么时间、现在怎样展示、异常下一步查什么。

今天就可以打开自己的自选股页面,挑一行问:如果下一轮没有拿到它的数据,使用者看得出来吗?把这份名单与检查单交给技术同事,对照页面和报告是否给出了相同答案。


本文用于行情研究和产品检查,不构成投资建议。实测及资料核验日期:2026年10月19日。

参考资料与实测附件

  1. IETF:RFC 9110,第15.3.1节,200 OK,2022年6月;区分请求成功与名单核对。
  2. Nasdaq:Why Real-Time Data Matters When Trading Stocks,2024年3月25日;解释最近成交价与成交频率的差异。
  3. 上交所:《交易规则(2026年修订)》及发布通知,2026年4月24日发布;常规竞价时段见第2.4.2条。
  4. 深交所:《交易规则(2026年修订)》,2026年4月24日修订;时段及即时行情内容见第2.3.2、5.2.2条。
  5. Interactive Brokers:Delayed Market Data,官方TWS API文档;提供有明确用途的冻结记录这一反例。
  6. 美国SEC:Types of Orders,官方投资者教育资料;说明最近成交价与执行价格的区别。
  7. 巴塞尔委员会:《Principles for effective risk data aggregation and risk reporting》,2013年1月9日发布;现行框架第36.18节核对准确、完整、时效原则及银行适用范围。
  8. TickDB:行情快照说明;核对字段、时间单位与批量查询上限。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。