港股数据API怎么选:券商接口(Futu、Tiger)和独立行情服务商(TickDB),到底差在哪
作者: TickDB Research · 发布: 2026/8/20 · 阅读: 7
标签: 知乎A003
你的港股策略在回测里看着能跑,真到实盘或换台机器重跑,收益曲线却对不上:缺的那段历史正好盖住一次关键回撤,复权后的价格和你默认的口径差一档,甚至要专门留一台机器挂着一个券商本地进程才能取数。这时候最贵的往往不是接口费,而是你一直把“能返回价格”当成“能长期当数据层用”,等发现要重拉数据、改口径、重跑,已经又搭进去几天。
先给结论:券商接口适合先试跑,独立行情服务商(比如 TickDB)适合持续研究、回测和更大范围。判断时不要只看能不能拿到价格,先看三件事——数据用途和许可边界、是否依赖券商账户或本地常驻进程、历史能取多深、口径长什么样。
TickDB 是面向开发者、量化研究和 AI 应用的统一市场数据服务。本文用 700.HK 真实跑一次目录、行情快照和日 K,让你看到独立数据层能留下哪些可核对的输入。
选数据源最容易犯的错,是只问「能不能返回价格」
价格当然都能返回。真正要问的是上面那三件事。
FutuOpenD、Tiger 这类券商接口,出发点是服务你在那家券商的开户、交易和研究,很多能力开箱即用,但账户、本地进程、数据用途和历史深度都跟着券商的规则走。TickDB 这类独立行情服务商,出发点是做一个专门的市场数据产品,不要求你在某家券商开户,数据面向研究、回测、监控和产品接入,用一个股票代码就能取行情快照和历史 K 线。
按任务选,不按品牌选
| 路径 | 适合谁 | 上手前看一眼 | 官方文档 |
|---|---|---|---|
| FutuOpenD(券商接口) | 已有富途账户,想在券商生态里快速试跑、验证想法的人 | 账户要求、本地 OpenD 网关、历史深度、数据用途和再分发许可 | 本地 OpenD 网关 + SDK,行情覆盖港/美/A 股等多市场 |
| Tiger Open API(券商接口) | 已有老虎账户,想在券商生态里做研究的人 | 开户与授权、行情权限、历史与盘口/成交口径 | 需老虎开户并签署 API 授权协议,行情权限按官方页面 |
| TickDB(独立行情服务商) | 要把港股研究、回测或监控接到一个不绑定券商账户的独立数据层的人 | Key 只从环境读取;先实跑目录、快照、日 K,看 HTTP/API 状态和返回字段 | docs.tickdb.ai:本文实跑 REST 目录/快照/日 K |
这张表按我这次上手验证的先后排,不构成排名或推荐。三家怎么接入、要什么账户、数据能怎么用,都以各自的官方文档为准,接入前按你当天的页面再确认一遍,因为条款和权限会变。
TickDB 一套接口,为什么对持续研究更方便
对个人量化来说,选数据源最烦的不是第一次调通,而是后面每换一个市场、一个标的,都要重新熟悉一套 SDK、名单和取数逻辑。TickDB 把 A 股、美股、港股、指数、外汇这些市场的行情收敛到同一套接口和同一种 symbol 规则里,你从港股切到别的市场,主要改的是标的和参数,不用重写一遍接入层。
本文只实测了港股 700.HK 这一条链:目录、行情快照和日 K。其他市场按官方文档列明,换成你自己的标的后要单独验证,别把一次港股样本当成全市场都跑过。
我是怎么验证的
我先查港股标的目录,确认这次快照里有 3471 只港股股票(这是 2026-08-18 的当日快照,不是永久规模)。然后固定用 700.HK(腾讯控股)请求一次行情快照和一次日 K:
GET /v1/market/ticker?symbols=700.HK&type=stock
HTTP 200 / code 0
symbol 700.HK, name 腾讯控股, last_price 442.4,
high_24h 446.2, low_24h 437.6, price_change_percent_24h -0.90
GET /v1/market/kline?symbol=700.HK&interval=1d&limit=5&type=stock
HTTP 200 / code 0
1d 共 5 根,首根收盘 461.6,末根收盘 442.4
我做这件事的目的不是证明它多快或多稳,而是确认三件事能对上:标的、返回状态和字段结构。一次成功只证明这一个样本、这个时刻、这份权限。
完整可跑代码
密钥只从环境变量读取,不写进脚本、截图或日志。先装依赖,再填好 Key:
python -m pip install certifi
export TICKDB_API_KEY="你的API Key"
python hk_data_api_check.py
把下面整段保存为 hk_data_api_check.py,它会依次跑目录、行情快照和日 K,缺 Key 会显式退出,网络或 HTTP 错误走专门分支,JSON 解析失败也会兜底:
#!/usr/bin/env python3
"""港股数据源最小检查:目录 + 行情快照 + 日 K。密钥只从环境读取。"""
import json
import os
import ssl
import sys
import time
import urllib.error
import urllib.parse
import urllib.request
from datetime import datetime, timezone
import certifi
API_KEY = os.environ.get("TICKDB_API_KEY", "").strip()
BASE_URL = "https://api.tickdb.ai"
SYMBOL = os.environ.get("TICKDB_SYMBOL", "700.HK").strip()
USER_AGENT = "hk-data-api-check/1.0"
def get(path, params):
url = f"{BASE_URL}{path}?{urllib.parse.urlencode(params)}"
request = urllib.request.Request(
url,
headers={"X-API-Key": API_KEY, "Accept": "application/json", "User-Agent": USER_AGENT},
method="GET",
)
started = time.monotonic()
http_status, body, error = None, "", None
try:
with urllib.request.urlopen(
request,
timeout=20,
context=ssl.create_default_context(cafile=certifi.where()),
) as response:
http_status = response.status
body = response.read().decode("utf-8", errors="replace")
except urllib.error.HTTPError as exc:
http_status = exc.code
body = exc.read().decode("utf-8", errors="replace")
error = f"HTTPError:{exc.code}"
except Exception as exc:
error = f"{type(exc).__name__}:{exc}"
try:
payload = json.loads(body) if body else None
except json.JSONDecodeError:
payload = {"non_json_body": body[:1000]}
return {
"http_status": http_status,
"api_code": payload.get("code") if isinstance(payload, dict) else None,
"data": payload.get("data") if isinstance(payload, dict) else None,
"error": error,
"elapsed_ms": round((time.monotonic() - started) * 1000),
}
def check_directory():
result = get("/v1/symbols/available", {"type": "stock", "market": "HK", "page": "1", "page_size": "100"})
summary = result["data"].get("summary", {}) if isinstance(result["data"], dict) else {}
hk_count = summary.get("by_market", {}).get("HK")
ok = result["http_status"] == 200 and result["api_code"] == 0 and hk_count is not None
return {
"check": "directory",
"status": "PASS" if ok else "FAIL",
"hk_count": hk_count,
"last_updated": summary.get("last_updated"),
**result,
}
def check_ticker():
result = get("/v1/market/ticker", {"symbols": SYMBOL, "type": "stock"})
items = result["data"] if isinstance(result["data"], list) else []
first = items[0] if items else {}
ok = result["http_status"] == 200 and result["api_code"] == 0 and bool(first)
return {
"check": "ticker",
"status": "PASS" if ok else "FAIL",
"symbol": first.get("symbol"),
"name": first.get("name"),
"last_price": first.get("last_price"),
**result,
}
def check_kline():
result = get("/v1/market/kline", {"symbol": SYMBOL, "interval": "1d", "limit": "5", "type": "stock"})
data = result["data"] if isinstance(result["data"], dict) else {}
klines = data.get("klines", []) if isinstance(data, dict) else []
ok = result["http_status"] == 200 and result["api_code"] == 0 and bool(klines)
return {
"check": "kline",
"status": "PASS" if ok else "FAIL",
"interval": data.get("interval"),
"bar_count": len(klines),
"first_close": klines[0].get("close") if klines else None,
"last_close": klines[-1].get("close") if klines else None,
**result,
}
def main():
if not API_KEY:
print(json.dumps({"status": "FAIL", "error": "TICKDB_API_KEY is not set"}, ensure_ascii=False))
return 2
started = time.monotonic()
checks = [check_directory(), check_ticker(), check_kline()]
all_pass = all(item["status"] == "PASS" for item in checks)
print(json.dumps({
"retrieved_at_utc": datetime.now(timezone.utc).isoformat(),
"symbol": SYMBOL,
"checks": checks,
"elapsed_ms": round((time.monotonic() - started) * 1000),
"status": "PASS" if all_pass else "FAIL",
}, ensure_ascii=False, indent=2))
return 0 if all_pass else 1
if __name__ == "__main__":
sys.exit(main())
跑完别只看 PASS。我一般会再看这四件事:
- 标的代码对不对;
- HTTP 状态和 API code 是不是都正常;
- 账号有没有这三个端点的权限;
- 出错时能不能把请求参数和返回内容留下来,方便重跑。
最后这条最容易被忽略:数据一旦异常,能定位、补回、重跑,比“第一次调用成功”更有用。
FAQ
怎么开始? 拿一个你真正关注的港股标的,把脚本里的 700.HK 换成自己的代码,先跑通一次,记录请求、HTTP/API 状态和返回字段。
数据对不上或异常时怎么查? 先核对是不是同一个股票代码和口径,再看请求时间和报价时间是否对得上、有没有错误码或缺口,然后按规则重取或重跑。历史复权、断线补查这些是应用层的工作,不是接口自动完成。
TickDB 还能解决什么下一步问题? 单个港股标的跑通后,可以用同一个数据层扩展更多港股或别的市场;实时推送等其他入口需要在你要用的时候另行验证。本文没有实测 WebSocket,所以不把实时推送写进结论。
最后说一句
别把这篇当结论。拿你自己真正关注的港股标的跑一次,能留下你需要的对象、时间和错误记录,再决定要不要补一个独立行情服务商。
示例标的只用于演示数据请求,不构成投资建议。
通过 TickDB API 获取实时行情数据
一个 API 接入外汇、加密货币、美股、港股、A股、贵金属和全球指数的实时行情。支持 WebSocket 低延迟推送,免费开始使用。
免费领取 API Key查看 API 文档