用 TickDB 做一个三地股票行情面板:从行情接口到可交互页面
TickDB Research ·
用 TickDB 做一个三地股票行情面板:从行情接口到可交互页面

把 A 股、美股、港股的几只自选股放在一张页面里,左边看报价,右边点开走势,再加上搜索和排序——这是接入行情 API 后,一个很适合动手做的小应用。
这次我们用 TickDB 搭了一个本地行情面板:Python 提供服务端接口,原生 JavaScript 渲染页面,不需要前端构建工具。它能展示六只样本股的行情快照,按市场筛选、按代码搜索、按涨跌幅排序,并在点击股票后显示历史日 K 的收盘价曲线。
先说明验证范围:本文页面已在本机运行,截图来自实际浏览器。截图使用 2026 年 9 月 28 日新采集并保存的 TickDB 真实响应,页面明确标为“真实采样回放 · 非实时”。同一份示例提供 REST 在线模式,但这次运行环境没有服务端 API Key,在线模式尚未完成真实 REST 直连验证。采样成功、页面运行成功和在线直连成功,是三件分别验证的事。
先看完成后的页面

图 1:本地应用实际截图。六只股票为开发样本,报价时间逐行保留;右侧曲线使用 Apple 返回的 39 根历史日 K,不代表实时推送画面。
这个面板只有两个主要区域。
左侧自选列表负责回答“我要看哪一只”:按 A 股、美股、港股切换范围,输入名称或代码缩小结果,再按涨幅排序。右侧详情负责回答“它现在返回了什么、历史是什么样”:最新价、涨跌幅、昨收、开盘,以及一条日 K 收盘价曲线。
本次样本是 600519.SH、000001.SZ、AAPL.US、MSFT.US、700.HK、9988.HK,每个市场两只。搜索只在这六个样本里进行,没有把它包装成全市场证券搜索;也没有加入交易、收益计算或选股信号。
这样做的价值,是先把一条完整的数据链跑清楚:取数、显示、交互、错误提示和时间标注都能在小范围内检查。
两个接口,分工就够清楚
列表用行情快照接口,点击详情后再取历史 K 线。对应关系如下:
| 页面功能 | TickDB 接口 | 本例使用方式 |
|---|---|---|
| 六股报价列表 | GET /v1/market/ticker | symbols 逗号分隔,一次请求六只股票 |
| 单股历史走势 | GET /v1/market/kline | 单个 symbol,日线 interval=1d,读取 close 绘图 |
官方行情快照文档规定,一次最多查询 50 个品种,时间戳单位为 UTC 毫秒。本例只取六只,不需要为每一行单独发送一次请求。行情快照文档
历史 K 线接口用于已结束周期;当前周期内仍在更新的 K 线有单独的接口。这里展示的是已返回日 K 的收盘走势,因此没有把快照里的最新价直接接到历史曲线末端。历史 K 线文档
先把这两个接口分开,后面的页面逻辑就很直接:筛选和排序在浏览器本地完成;切换股票才需要读取该股票的走势。
把 API Key 留在服务端
浏览器访问的是本地服务提供的 /api/ticker 和 /api/kline。本地服务再向 TickDB 发请求,加入鉴权头,最后把行情响应返回给页面。

图 2:本文示例的请求流程示意。API Key 由服务端环境变量提供;浏览器拿到行情响应,不接收密钥。这是示例应用的设计,不是 TickDB 官方内部架构。
TickDB 的 REST 快速开始文档使用 X-API-Key 请求头。不要把用于其他接入层的头名称直接照搬到 REST 请求。快速开始
服务端核心请求可以写成这样:
import json
import os
from urllib.parse import urlencode
from urllib.request import Request, urlopen
params = {
"symbols": "600519.SH,000001.SZ,AAPL.US,MSFT.US,700.HK,9988.HK",
"type": "stock",
}
request = Request(
"https://api.tickdb.ai/v1/market/ticker?" + urlencode(params),
headers={"X-API-Key": os.environ["TICKDB_API_KEY"]},
)
with urlopen(request, timeout=15) as response:
payload = json.load(response)
if payload.get("code") != 0:
raise RuntimeError(f"TickDB 业务错误:{payload.get('code')}")
完整示例还处理 HTTP 错误、连接失败和响应结构错误。HTTP 请求完成之后,仍要检查业务 code,不能仅凭收到了 JSON 就显示“刷新成功”。
为避免连续点击重复访问上游,本例的在线模式缓存快照 60 秒、日 K 15 分钟。两者都是这个示例自己选择的缓存策略,不是 TickDB 的官方刷新频率或套餐承诺。应用没有自动轮询;用户点刷新时,缓存未过期就继续使用原结果和原取数时间。
服务也只接受六个样本代码,不允许浏览器传入任意上游 URL。这样既方便检查,也避免把示例服务做成无边界代理。
前端先处理数据,再处理颜色
行情字段有些是数字字符串。直接转成数字很方便,但 Number(null) 和 Number("") 都会得到 0。若不提前判断,界面就可能把“没拿到”画成“确实为零”。
本例使用一个很小的转换函数:
const number = value => {
if (value === null || value === undefined || String(value).trim() === "") {
return null;
}
const result = Number(value);
return Number.isFinite(result) ? result : null;
};
缺失值显示 —;真实零值保留。涨跌幅采用接口的 price_change_percent_24h,红涨绿跌,同时带正负号,避免只靠颜色表达。
本次官方缓存页把这组字段写作“24 小时”变化,当前行情工具则区分了传统市场交易日/时段与加密资产滚动 24 小时的口径。面板使用中性的“涨跌幅”标签,保留原字段,不把三地股票一概解释成滚动 24 小时,也不自行改成涨跌金额除以最新价。
样本股票的报价币种在应用里显式配置为 CNY、USD、HKD,跟着代码一起显示。这只是这六只股票的配置,不是通用的“按交易所后缀推断所有证券币种”规则。三种币种的价格没有被相加,也没有画到同一个绝对价格纵轴上。
筛选、搜索、排序不会改写原始行情。详情面板保留当前选中的股票,即使它暂时被列表筛选隐藏;重新点击列表中的股票后,详情才切换。
图表里,时间比多画一条线更重要
本例在页面中保留了三类时间:
| 时间 | 告诉读者什么 | 显示方式 |
|---|---|---|
快照 timestamp | 这条报价对应的数据时刻 | 每行显示北京时间 |
| 服务端取数时间 | 这次请求何时完成 | 单独显示,不覆盖报价时间 |
日 K time | 这根历史 K 线对应的时间 | 按股票所属市场时区生成日期标签 |
这是一次实际运行后很容易看出来的区别。9 月 28 日早上取回的六股快照,数据时刻并不都落在 9 月 28 日:本次 A 股样本为 9 月 24 日,美股样本换算北京时间为 9 月 26 日 04:00,港股样本为 9 月 25 日 16:08:14。
这些时间来自原始响应。它们足以说明页面不能把“刚刚请求成功”写成“行情刚刚更新”,但不能仅凭这一组数据断定所有差异的原因。
曲线也按同样原则处理:先按 time 升序排列,再将 close 转成数值。横轴按实际返回记录等距排列,旁边注明实际首尾日期和记录数;未返回的日期不会由页面自动补齐。
const points = klines
.filter(k => number(k.time) !== null && number(k.close) !== null)
.sort((a, b) => a.time - b.time);
例如这次腾讯快照的最新价为 436.60 HKD,对应 9 月 25 日;同一轮历史请求返回的最后一根日 K 为 9 月 24 日,收盘价 438.40 HKD。面板会同时显示这两个事实,不会把 436.60 追加成一根不存在于响应里的日 K。
这个小例子比给图表增加更多指标更有意义:用户看得见当前页面到底收到了什么。
怎样运行与验证
完整本地示例包含四个主要文件:server.py 负责接口、鉴权与缓存,index.html 定义页面结构,app.js 实现交互和 SVG 曲线,style.css 处理桌面与窄屏布局。另外保留了本次采样响应,供回放模式读取。
使用 Python 3.10 或以上版本,在示例的 app 目录执行:
python3 server.py
打开 http://127.0.0.1:8765,即可查看真实采样回放。此模式不需要密钥,也不会再向 TickDB 请求行情,适合检查页面和复现截图。
如果要验证自己的在线数据,在服务端终端设置好 TICKDB_API_KEY 环境变量后执行:
python3 server.py --live --port 8766
然后打开 http://127.0.0.1:8766。没有密钥时,在线模式会直接拒绝启动,不会悄悄退回样本数据。密钥从 TickDB 官方快速开始 指引的入口获取,实际可访问市场与能力以自己的账号权益为准。
本次验证包括:
- 真实数据采集:7 次串行调用,1 次六股快照和 6 次历史日 K,全部返回
code=0。历史请求窗口为 2026-08-01 至 2026-09-27 UTC,limit=40、adjust=none,各返回 39 根日 K,共 234 根。请求参数、UTC/北京时间和原始响应均保留。 - 页面交互:港股筛选得到两个样本;搜索
700得到腾讯;无匹配时显示空态;本次样本按涨幅降序排列时 Microsoft 在前;点击个股会切换相应详情和曲线。 - 服务端逻辑:6 项自动化测试覆盖回放数据、鉴权头与缓存、连接失败、HTTP 错误、业务错误和 K 线请求范围。在线分支测试使用模拟上游,不等同于真实直连验证。
- 显示范围:检查了桌面和 390 像素窄屏。窄屏下列表与详情上下排列,表格放在自己的横向滚动区域。
REST 在线模式与回放样本使用的历史窗口不同:在线模式取最近 70 天、limit=100;回放保留本次固定采样窗口。界面始终显示实际返回区间,不保证请求了多少天就一定得到多少根 K 线。
继续扩展时,先决定真正需要什么
这个版本已经可以作为一个小型行情应用的起点:六股列表能看、个股详情能切、时间来源可追溯,接口失败也有明确提示。
如果要扩展到更多品种,下一步可以先接入可用品种列表,再设计用户自选的增删与保存;如果要公开部署,还要补用户鉴权、访问限制以及账号对应的数据展示权限核验。如果要做持续更新,则需要另行实现并验证推送或轮询链路,不能把当前的手动刷新写成已经完成的实时推送。
从这个小面板开始,TickDB 承担统一取数入口,应用承担数据展示、交互和状态解释。先用自己的 API Key 验证六股在线请求,再决定是否增加品种和更新方式,是一个容易检查、也便于继续迭代的接入起点。
本文股票仅用于软件开发示例,不构成个股买卖建议。