摘要:面向参与股票报价看板交付的产品与开发人员,本文把“接入实时行情”拆成页面功能、数据口径和验收条件,说明报价、K线、盘口与成交明细各自何时需要。结合一份TickDB美股实际返回,给出数据需求表、样本获取步骤、完整Python检查程序和运行结果,帮助团队在开发界面之前确认数据是否支持已承诺的功能。
做一个股票报价看板,最先接通的往往是价格:请求成功,页面也出现了数字。
继续开发时,问题会逐渐变具体:涨跌幅相对哪个价格?休市后保留什么状态?盘口和成交记录的时间为什么与主报价不同?历史K线、逐笔成交和扩展交易时段,是否都要放进首版?
这些问题需要产品和技术共同确定。接口清单只告诉我们能请求什么;交付还要明确页面展示什么、采用什么口径,以及数据不足时怎样回应。
一个实用的顺序是:先定页面功能,再选数据,最后写验收条件。下面以美股自选报价看板为例,完成一份数据需求表,再用保存的真实返回做一次本地结构检查。
一、先给首版划定范围
本文的产品需求是构造案例:首版展示自选股票身份、所选交易时段的价格与涨跌,支持持续更新和数据过期提示;示例先选择常规交易时段,暂不提供盘口分析、成交明细、扩展时段切换和历史研究。
如果你的产品以历史走势或买卖价差为主要功能,相应数据就应进入首版。优先级取决于用户要完成的任务。
把“实时行情”拆成下面四项,开发任务会更明确:
| 需求 | 需要写清的内容 |
|---|---|
| 对象 | 目标市场、完整自选清单、代码和名称的对应关系 |
| 口径 | 价格属于哪个时段,涨跌相对哪个参考值 |
| 更新 | 目标时段内,什么条件下认定数据过期 |
| 异常 | 证券不存在、没有权限、字段缺失或连接中断时的页面行为 |
例如,“接上WebSocket”是一项实现任务;“目标时段内持续更新,更新停止后显示过期状态”是一项产品验收要求。两者需要通过应用逻辑连接起来。

图1:AI方法示意图。不同功能需要不同数据,历史、盘口或成交是否进入首版,由本次需求决定。
二、报价、K线、盘口与成交分别支持什么功能
1. 报价展示:身份、时间和参考值一起处理
首版报价列表至少需要建立证券身份、市场、币种与价格之间的明确关系。名称和币种可以来自目录或参考资料,报价响应则按自己的字段契约核对。
涨跌幅也需要有参考值。TickDB报价文档说明,除核心报价字段外,其他字段会根据产品、时段及可用性按条件返回。某条样本返回参考昨收和涨跌幅,不代表每只股票、每个时段都必然返回。
字段缺失时,界面应显示未提供或暂不可用。填成零涨跌会改变信息含义。如果自己计算涨跌幅,还要确认价格和参考值的时段与统计口径匹配。
时间至少保留两类:行情时间和接收时间。前者属于市场记录,后者属于程序获取过程。过期判断还需要交易时段规则:休市后保留最后一条目标时段报价,可以是正常状态;目标时段内停止更新,则需要明确提示。
2. 历史走势:先确定区间和周期
要展示历史曲线,就需要相应周期与范围的K线,并约定复权方式、缺失记录和未结束周期的处理。
当前报价功能不必因为接口提供多年历史而提前建设回测模块。即使曲线已经画出,是否适合回测仍涉及历史证券样本、数据版本和研究设计,需要另行判断。
3. 盘口:用于观察可见买卖报价
最新成交价描述已经发生的交易;盘口描述返回时可见的买卖报价及数量。观察价差需要对应买卖报价,观察价格层级时才进一步需要相应深度。
页面应按实际返回档数展示,处理单侧为空和档数不足。可见挂单可能变化,不能把静态盘口显示为保证可成交的价格和数量。
4. 成交明细:先约定记录范围
最近成交接口提供的是一个记录窗口。返回三条或一百条,不代表已经取得整天成交历史。
如果功能承诺连续记录,就需要进一步设计持续接收、断线处理、去重和缺口检查。反复刷新最近记录,不能直接作为完整归档的验收依据。
三、把功能选择写成数据需求表
下面是本文假设看板的填写示例。它用于需求与开发交接,尚不是已上线系统的验收报告。
| 功能与优先级 | 必要数据 | 可后加能力 | 验收方法 |
|---|---|---|---|
| 证券识别:首版 | 代码、名称、市场、币种及映射 | 跨市场搜索 | 逐项核对完整自选清单,检查代码与单位 |
| 价格展示:首版 | 目标时段价格和行情时间 | 扩展时段切换 | 价格、时间和时段标签采用同一对象 |
| 涨跌展示:首版 | 匹配口径的涨跌字段或计算基准 | 更多统计指标 | 核对参考值;缺失不填零 |
| 更新与异常状态:首版 | 更新记录、行情时间、接收时间和错误状态 | 增强恢复机制 | 测试目标时段更新及中断后的过期提示 |
| 历史走势:本示例后加 | 目标周期的K线 | 更多周期与研究工具 | 核对范围、复权、缺失及周期完成状态 |
| 盘口或成交:本示例后加 | 与选定功能匹配的买卖报价或成交记录 | 深度分析或连续归档 | 检查实际档数、记录范围、时间、数量单位与空态 |
这张表还应附上目标账户、预期负载和使用对象。内部研究、内部看板和客户展示的使用条件分别确认。目录里能找到证券,也不代表当前账户已经拥有所有相关数据权限。
后加功能如果进入首版,它的数据与异常处理也要一起进入验收范围。
四、先取真实样本,再开始写字段映射
本文使用TickDB提供的股票数据,通过已经连接的MCP取得一份美股样本。MCP适合这里的按需查询;本文没有用它验证持续推送,也没有在本例重新运行REST或WebSocket。
2026年11月10日,先从US股票目录核对Apple身份,再对AAPL.US分别查询报价、盘口与最近三条成交。目录中的代码为AAPL,报价工具使用AAPL.US;关联时同时核对市场与工具的代码规范。
实际返回摘要如下,未展示行情价格值:
| 模块 | 返回结构 | 数据时间,UTC |
|---|---|---|
| 主报价 | 包含证券代码、价格、参考昨收、涨跌幅及时间字段 | 2026-11-09 21:00:01 |
| 盘口 | 买侧1档、卖侧1档 | 2026-11-10 04:01:56.484 |
| 最近成交 | 请求3条,返回3条,记录标签为overnight | 2026-11-10 04:00:42至04:01:51 |
取数记录位于2026年11月10日UTC 04:01这一分钟。这是几次独立查询,不是同一时刻的原子快照,也不用于计算端到端延迟。
报价响应还包含扩展时段对象。页面若选择常规时段,就需要核对所选字段与时段要求是否一致;以后增加夜盘,必须同时处理夜盘价格、时间和标签。不能只选一个更晚的时间,配上另一个对象的价格。
在自己的MCP客户端取得输入文件
前提是客户端已经连接TickDB MCP,并配置了自己的有效凭证。密钥留在本地配置中,不放进下面的任务文本。
先调用get_available_symbols,在US股票目录中确认Apple。
可使用market="US"、type="stock"、limit=1000、offset=0;
如果目标不在这一页,按实际分页继续查找,不能视作不支持。
随后查询AAPL.US:
1. get_ticker:symbols="AAPL.US",type="stock";
2. get_order_book:symbol="AAPL.US",type="stock";
3. get_recent_trades:symbol="AAPL.US",type="stock",limit=3。
将工具返回的完整业务JSON(包含code、message、data),分别保存为
ticker_raw.json、depth_raw.json、trades_raw.json,并另记取数时间。
不要保存客户端界面截图或带text/content包装的展示文本来替代业务JSON。
失败时保留实际错误,不补造成功文件。
样本结构可用于检查字段映射。完整标的清单、持续更新、页面过期状态、账户等级和客户展示条件,本例没有验证,需要按需求表继续完成。
五、用完整Python程序检查保存的JSON
环境与文件布局
需要Python 3.10或以上版本,只使用标准库。程序不联网,不需要API Key,也不会输出行情价格。它读取三个保存文件,检查业务状态、证券一致性和必需报价字段,再整理各模块的结构与时间。
文件放在同一目录:
quote-api-check/
├── check_sample.py
├── ticker_raw.json
├── depth_raw.json
└── trades_raw.json
将下面代码保存为check_sample.py:
"""Python 3.10+; inspect saved TickDB MCP payloads, without network calls."""
import csv
import json
from datetime import datetime, timezone
from pathlib import Path
def read_payload(filename):
payload = json.loads(Path(filename).read_text(encoding="utf-8-sig"))
if payload.get("code") != 0:
raise ValueError(f"Unsuccessful API response: {filename}")
return payload["data"]
def utc(value):
if type(value) is not int or value < 0:
raise ValueError("Expected a nonnegative millisecond timestamp")
return datetime.fromtimestamp(value / 1000, timezone.utc).isoformat()
def main():
symbol = "AAPL.US"
quotes = read_payload("ticker_raw.json")
matching = [row for row in quotes if row.get("symbol") == symbol]
if len(matching) != 1:
raise ValueError("Expected exactly one matching quote")
quote = matching[0]
book = read_payload("depth_raw.json")
tape = read_payload("trades_raw.json")
if book.get("symbol") != symbol or tape.get("symbol") != symbol:
raise ValueError("The payloads refer to different symbols")
required = ("last_price", "timestamp")
if any(quote.get(key) is None for key in required):
raise ValueError("Missing a required quote field")
bids, asks, trades = book["bids"], book["asks"], tape["trades"]
times = [row["timestamp"] for row in trades]
rows = [
["quote", symbol, "required_fields_present", utc(quote["timestamp"])],
["depth", symbol, f"bids={len(bids)};asks={len(asks)}", utc(book["timestamp"])],
["trades", symbol, f"rows={len(trades)}",
f"{utc(min(times))} to {utc(max(times))}" if times else "empty"],
]
with Path("sample_check.csv").open("w", newline="", encoding="utf-8-sig") as file:
writer = csv.writer(file)
writer.writerow(["module", "symbol", "observed_structure", "data_time_utc"])
writer.writerows(rows)
for row in rows:
print(" | ".join(row))
print("Saved sample_check.csv; structure check only, not release approval")
if __name__ == "__main__":
try:
main()
except (OSError, ValueError, TypeError, KeyError) as error:
raise SystemExit(f"STOP: {error}")
运行方式与实际输出
在上述目录运行:
python3 check_sample.py
使用本文2026年11月10日保存的样本,本地运行输出为:
quote | AAPL.US | required_fields_present | 2026-11-09T21:00:01+00:00
depth | AAPL.US | bids=1;asks=1 | 2026-11-10T04:01:56.484000+00:00
trades | AAPL.US | rows=3 | 2026-11-10T04:00:42+00:00 to 2026-11-10T04:01:51+00:00
Saved sample_check.csv; structure check only, not release approval
sample_check.csv使用UTF-8 BOM编码保存,便于Excel或WPS打开。使用自己的新样本时,数量和时间应以实际返回为准,不要求复现上面的数值。
程序还有两个停止条件:业务响应失败时输出STOP: Unsuccessful API response...;盘口或成交指向另一只证券时输出STOP: The payloads refer to different symbols。这两个错误分支已用单独的负向测试输入检查,未修改原始行情文件。
怎样理解检查结果
required_fields_present表示程序要求的字段在样本中存在。它不判断市场数据是否正确,不校验参考昨收的业务口径,也不会自动认定数据属于页面要求的交易时段。
同样,盘口每侧1档、成交3条,仅是本次观察。程序没有检查连续运行、成交完整性或页面异常状态,不能把CSV生成成功当成上线验收完成。

图2:AI方法示意图。样本结构检查之后,还要按目标时段、正常与异常状态继续验收。
六、开始开发前,留下一个可共同核对的交付依据
完成这一步,应能交出三份材料:填好的功能与数据需求表、保留时间及条件的真实样本、可逐项执行的验收清单。
需求表解释为什么要这类数据;样本帮助开发者看到实际字段与返回范围;验收清单说明更新正常、停止或缺失时应发生什么。首版是否完成,由这三份材料共同判断。
可以先挑一个已经承诺的功能,把它的数据、时段、缺失行为和验收方法写完整。接口、权限及后续数据模块,就能围绕具体任务来选择。
代码与接入参考
TickDB的公开工具仓库包含MCP服务端实现与Skill接入资料,适合在复现查询或检查客户端配置时参考:
https://github.com/TickDB/tickdb-unified-realtime-marketdata-api
仓库中的mcp/用于MCP服务端与接入参考,SKILL/包含对应的工具说明。本文的check_sample.py完整代码见第五节;仓库链接用于接入资料,不表示本文程序或样本已收录到仓库。公开工具代码的许可与行情数据使用权限应分别确认,实际数据调用仍需相应凭证和权限。
资料日期:2026年11月10日。行情样本来自当日TickDB MCP调用;GitHub仅作工具与接入参考。产品需求为构造案例,使用条件按目标市场、账户和用途确认。

