美股实时行情API完整指南:五大交易所、12,551只标的统一接入
作者: TickDB Research · 发布: 2026/5/17 · 阅读: 46
标签: Track A, 知乎, 美股, 产品介绍型
TickDB 美股接入速览
| 项目 | 详情 |
|---|---|
| 标的数量 | 12,551 只(全量美股) |
| 交易所覆盖 | NYSE、NASDAQ、AMEX、ARCA、BATS 五大交易所 |
| 代码格式 | AAPL.US / TSLA.US / MSFT.US |
| REST端点 | ticker、kline、kline/latest、depth、intraday、stock-info、calc-index、capital-flow、trading-sessions、trade-days、symbols/available |
| WebSocket频道 | ticker、depth |
| 行情时段 | 含盘前、盘后、夜盘三段报价 |
| 鉴权方式 | REST: Header X-API-Key;WebSocket: URL参数 ?api_key= |
| 免费政策 | 有免费体验额度,注册即可开始 |
5分钟接入检查清单
| 步骤 | 操作 | 端点/命令 |
|---|---|---|
| 1.获取Key | 注册TickDB账号并生成API Key | https://tickdb.ai |
| 2.验证行情 | 查询苹果实时价格 | GET /v1/market/ticker?symbols=AAPL.US |
| 3.获取K线 | 拉取历史日线数据 | GET /v1/market/kline?symbol=AAPL.US&interval=1d&... |
| 4.订阅推送 | 建立WebSocket实时接收行情 | wss://api.tickdb.ai/v1/realtime?api_key=YOUR_KEY |
引言:为什么美股数据接入总比想象中复杂
做美股量化的人,迟早会踩到同一个坑:你以为拿到的是"全市场数据",实际上只拿到了NYSE和NASDAQ的股票,AMEX、ARCA、BATS上的ETF和低价股全部漏掉。你以为拿到了实时价格,实际上盘前盘后的价差已经让你错过了最佳入场点。
这不是某个数据源的缺陷,而是美股市场结构本身就分散。五个交易所、三个交易时段、数万只跨市场挂牌的标的——单一数据接口要覆盖完整,需要做大量底层对接。
TickDB 定位为"首个为 AI 时代而生的统一实时行情 API",通过"统一 REST + WebSocket 接口、统一字段、统一鉴权",将美股五大交易所完整接入。本文按市场→交易所→时段三层结构展开,每个端点提供独立速查卡,代码可直接运行。
声明:本文基于TickDB公开API文档的实测结果撰写,代码可独立验证。具体服务条款与免费额度以 docs.tickdb.ai 官方公示为准。
第一层:美国股票市场
TickDB 覆盖美股 12,551 只 标的,涵盖五大交易所的全部上市股票和ETF。数据通过REST API和WebSocket双通道提供。
美股与其他市场最大的不同在于交易时段:除了常规交易时段(美东时间9:30-16:00),还存在盘前交易(4:00-9:30)、盘后交易(16:00-20:00)和夜盘交易(20:00-次日4:00)。TickDB 的 ticker 端点对美股标的返回"含盘前、盘后、夜盘三段报价",在单个接口中完整呈现全时段价格。
第二层:五大交易所与端点矩阵
2.1 五大交易所
| 交易所 | 缩写 | 典型标的 |
|---|---|---|
| 纽约证券交易所 | NYSE | BRK.A.US、JPM.US |
| 纳斯达克 | NASDAQ | AAPL.US、MSFT.US、GOOGL.US |
| 美国证券交易所 | AMEX | 中小盘股和ETF |
| 纽约证券交易所高增长板 | ARCA | ETF和ETP |
| 全球电子交易系统 | BATS | ETF和部分股票 |
2.2 美股可用端点功能矩阵
| 端点 | 功能 | 美股支持 | 典型参数示例 |
|---|---|---|---|
GET /v1/market/ticker | 实时行情快照 | 支持 | symbols=AAPL.US,TSLA.US |
GET /v1/market/kline | 历史K线(已固化) | 支持 | symbol=AAPL.US&interval=1d&... |
GET /v1/market/kline/latest | 实时K线(未闭合周期) | 支持 | symbols=AAPL.US&interval=1m |
GET /v1/market/depth | 订单簿深度 | 支持 | symbol=AAPL.US |
GET /v1/market/intraday | 当日分时数据 | 支持 | symbols=AAPL.US |
GET /v1/market/stock-info | 股票详情(基本面) | 支持 | symbol=AAPL.US |
GET /v1/market/calc-index | 市场指标与估值 | 支持 | symbols=AAPL.US |
GET /v1/market/capital-flow | 资金流向 | 支持 | symbol=AAPL.US |
GET /v1/market/trading-sessions | 交易时段查询 | 支持(按市场) | market=US |
GET /v1/market/trade-days | 交易日历 | 支持(按市场) | market=US&beg_day=...&end_day=... |
GET /v1/symbols/available | 品种搜索 | 支持 | market=US&type=stock |
第三层:品种格式、时段机制与端点速查卡
3.1 美股标的代码格式
AAPL.US(苹果)TSLA.US(特斯拉)MSFT.US(微软)GOOGL.US(谷歌)BRK.A.US(伯克希尔A类股)
3.2 盘前、盘后、夜盘时段机制
美股交易时段覆盖(美东时间):
| 时段 | 时间 | 流动性特征 |
|---|---|---|
| 夜盘 | 20:00 - 次日 4:00 | 极低,仅部分券商支持 |
| 盘前 | 4:00 - 9:30 | 较低,价差可能放大 |
| 常规交易 | 9:30 - 16:00 | 最高,价差最小 |
| 盘后 | 16:00 - 20:00 | 较低,财报常在此窗口发布 |
ticker接口在各时段返回的对应字段:
| 字段 | 出现时段 | 说明 |
|---|---|---|
overnight_price | 夜盘时段 | 夜盘最新成交价 |
pre_market_price | 盘前时段 | 盘前最新成交价 |
regular_market_price | 常规时段 | 常规交易最新价 |
after_hours_price | 盘后时段 | 盘后最新成交价 |
last_price | 全时段 | 始终返回最近一笔成交价 |
端点速查卡与可运行代码
环境准备
pip install requests websockets
速查卡 #1:ticker(实时行情快照)
| 属性 | 值 |
|---|---|
| 端点 | GET https://api.tickdb.ai/v1/market/ticker |
| 参数 | symbols(复数,逗号分隔,最多50个) |
| 美股示例 | symbols=AAPL.US,TSLA.US |
| 成功码 | code==0,数据在 data 数组 |
| Ticker字段 | last_price(最新价)、timestamp(时间)、price_change_percent_24h(涨跌幅)、volume_24h(24h成交量) |
| 时段字段 | pre_market_price、after_hours_price、overnight_price、regular_market_price |
| 字段陷阱 | 价格字段是 last_price 不是 close;时间字段是 timestamp 不是 time |
| 限流码 | 3001 → 读 Retry-After 头,指数退避 |
| 鉴权失败码 | 1001 → 阻断并提示 |
import requests
import time
def main():
url = "https://api.tickdb.ai/v1/market/ticker"
headers = {"X-API-Key": "YOUR_API_KEY"}
params = {"symbols": "AAPL.US,TSLA.US,MSFT.US"}
while True:
try:
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 429: # 3001 限流
retry_after = resp.headers.get("Retry-After", "5")
print(f"请求频率超限,{retry_after}秒后重试...")
time.sleep(int(retry_after))
continue
if resp.status_code == 401: # 1001 鉴权失败
print("API Key 无效,请检查 X-API-Key Header")
break
resp.raise_for_status()
data = resp.json()
if data.get("code") == 0:
for item in data["data"]:
print(f"{item['symbol']} 最新价: {item['last_price']} "
f"涨跌幅: {item.get('price_change_percent_24h', 'N/A')}% "
f"24h成交量: {item.get('volume_24h', 'N/A')}")
else:
print(f"业务错误: {data.get('code')} - {data.get('message')}")
break
except requests.exceptions.RequestException as e:
print(f"网络异常: {e}")
break
if __name__ == "__main__":
main()
速查卡 #2:kline(历史K线)
| 属性 | 值 |
|---|---|
| 端点 | GET https://api.tickdb.ai/v1/market/kline |
| 参数 | symbol(单数,不是 symbols)、interval、start_time、end_time |
| 可用周期 | 1m,5m,15m,30m,1h,2h,4h,1d,1w,1M(不含3m) |
| 成功码 | code==0,数据在 data["data"]["klines"] |
| K线字段 | open、high、low、close(不是 last_price)、volume、time(不是 timestamp) |
| 字段陷阱 | K线用 close,ticker用 last_price;K线用 time,ticker用 timestamp;K线用 volume,ticker用 volume_24h |
| 参数陷阱 | 参数名是 symbol(单数),不要写成 symbols |
import requests
import time
def main():
url = "https://api.tickdb.ai/v1/market/kline"
headers = {"X-API-Key": "YOUR_API_KEY"}
params = {
"symbol": "AAPL.US",
"interval": "1d",
"start_time": "2026-05-01T00:00:00Z",
"end_time": "2026-05-17T23:59:59Z"
}
try:
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 429:
retry_after = resp.headers.get("Retry-After", "5")
time.sleep(int(retry_after))
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 401:
print("API Key 无效")
return
resp.raise_for_status()
data = resp.json()
if data["code"] == 0:
klines = data["data"]["klines"]
for k in klines[:5]:
print(f"{k['time']} O:{k['open']} H:{k['high']} "
f"L:{k['low']} C:{k['close']} V:{k['volume']}")
print(f"共获取 {len(klines)} 根K线")
else:
print(f"错误: {data['message']}")
except requests.exceptions.RequestException as e:
print(f"请求异常: {e}")
if __name__ == "__main__":
main()
速查卡 #3:kline/latest(实时K线)
| 属性 | 值 |
|---|---|
| 端点 | GET https://api.tickdb.ai/v1/market/kline/latest |
| 参数 | symbols(复数)、interval |
| 可用周期 | 1m,3m,5m,15m,30m,1h,2h,4h,1d,1w,1M(比历史K线多3m) |
| 数据路径 | data["data"]["klines"][0] |
| K线字段 | 同历史K线:open、high、low、close、volume、time |
import requests
import time
def main():
url = "https://api.tickdb.ai/v1/market/kline/latest"
headers = {"X-API-Key": "YOUR_API_KEY"}
params = {"symbols": "AAPL.US", "interval": "1m"}
try:
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 429:
retry_after = resp.headers.get("Retry-After", "5")
time.sleep(int(retry_after))
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 401:
print("API Key 无效")
return
resp.raise_for_status()
data = resp.json()
if data["code"] == 0:
result = data["data"]
k = result["klines"][0]
print(f"实时K线 - {result['symbol']} "
f"O:{k['open']} H:{k['high']} L:{k['low']} "
f"C:{k['close']} 时间:{k['time']}")
except requests.exceptions.RequestException as e:
print(f"异常: {e}")
if __name__ == "__main__":
main()
速查卡 #4:depth(订单簿深度)
| 属性 | 值 |
|---|---|
| 端点 | GET https://api.tickdb.ai/v1/market/depth |
| 参数 | symbol(单数) |
| 返回结构 | data["data"]["bids"] 和 data["data"]["asks"],每个元素为 [价格, 数量] |
import requests
import time
def main():
url = "https://api.tickdb.ai/v1/market/depth"
headers = {"X-API-Key": "YOUR_API_KEY"}
params = {"symbol": "AAPL.US"}
try:
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 429:
retry_after = resp.headers.get("Retry-After", "5")
time.sleep(int(retry_after))
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 401:
print("API Key 无效")
return
resp.raise_for_status()
data = resp.json()
if data["code"] == 0:
depth = data["data"]
print(f"AAPL.US 买一: {depth['bids'][0]} 卖一: {depth['asks'][0]}")
except requests.exceptions.RequestException as e:
print(f"异常: {e}")
if __name__ == "__main__":
main()
速查卡 #5:intraday(当日分时)
| 属性 | 值 |
|---|---|
| 端点 | GET https://api.tickdb.ai/v1/market/intraday |
| 参数 | symbols(复数) |
| 分时字段 | timestamp(时间)、price(价格)、avg_price(均价) |
import requests
import time
def main():
url = "https://api.tickdb.ai/v1/market/intraday"
headers = {"X-API-Key": "YOUR_API_KEY"}
params = {"symbols": "AAPL.US"}
try:
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 429:
retry_after = resp.headers.get("Retry-After", "5")
time.sleep(int(retry_after))
resp = requests.get(url, headers=headers, params=params)
if resp.status_code == 401:
print("API Key 无效")
return
resp.raise_for_status()
data = resp.json()
if data["code"] == 0:
points = data["data"]
for point in points[:5]:
print(f"时间: {point['timestamp']} 价格: {point['price']}")
print(f"共 {len(points)} 个分时点")
except requests.exceptions.RequestException as e:
print(f"异常: {e}")
if __name__ == "__main__":
main()
速查卡 #6:WebSocket(实时推送)
| 属性 | 值 |
|---|---|
| 端点 | wss://api.tickdb.ai/v1/realtime(路径不可省略) |
| 鉴权 | URL参数 ?api_key=YOUR_API_KEY |
| 订阅 | {"cmd":"subscribe","data":{"channel":"ticker","symbols":["AAPL.US","TSLA.US"]}} |
| 心跳 | 每秒发送 {"cmd":"ping"},否则连接被防火墙断开 |
| 推送格式陷阱 | 实际为扁平JSON,无 cmd 字段,无 data 包装层。symbol字段无市场后缀(推送AAPL,非AAPL.US) |
| 判断方式 | 用 "last_price" in data 判断是否为ticker推送,不能用 data.get("cmd") |
import asyncio
import json
import websockets
async def main():
uri = "wss://api.tickdb.ai/v1/realtime?api_key=YOUR_API_KEY"
try:
async with websockets.connect(uri) as ws:
sub_msg = {
"cmd": "subscribe",
"data": {"channel": "ticker", "symbols": ["AAPL.US", "TSLA.US"]}
}
await ws.send(json.dumps(sub_msg))
print("已订阅美股 ticker 频道")
async def heartbeat():
while True:
await ws.send(json.dumps({"cmd": "ping"}))
await asyncio.sleep(1)
asyncio.create_task(heartbeat())
async for message in ws:
data = json.loads(message)
# 实测:推送为扁平JSON,无cmd字段
if "last_price" in data:
print(f"推送: {data['symbol']} 最新价: {data['last_price']}")
elif data.get("cmd") == "pong":
pass
except websockets.exceptions.ConnectionClosed as e:
print(f"连接关闭: {e}")
except Exception as e:
print(f"异常: {e}")
if __name__ == "__main__":
asyncio.run(main())
坑表:美股接入常见陷阱
| 坑 | 原因 | 后果 | 正确处理 |
|---|---|---|---|
WebSocket推送无cmd字段 | 实际为扁平JSON,与文档描述的嵌套结构不同 | 按data.get("cmd")判断会漏掉所有ticker推送 | 用"last_price" in data直接判断消息类型 |
WebSocket的symbol无.US后缀 | 推送格式为AAPL而非AAPL.US | 用后缀匹配本地自选股会全部失败 | 匹配时去掉后缀或建立无后缀映射表 |
K线端点用symbol单数 | /kline用单数,/kline/latest用复数symbols | 参数名写反会导致400错误 | 按速查卡中的参数名调用 |
K线字段名是close不是last_price | ticker和kline用了不同字段名体系 | 解析K线时访问last_price返回KeyError | ticker用last_price,kline用close |
K线时间字段是time不是timestamp | 同上一陷阱 | 访问timestamp返回KeyError | ticker用timestamp,kline用time |
| 盘前盘后流动性差异大 | 盘前盘后价差可达常规时段的5-10倍 | 用盘前价格直接下限价单可能无法成交 | 实盘策略区分时段,盘前盘后用更宽的滑点预算 |
| 休市日请求仍返回成功 | 非交易日API返回历史最后成交价而非拒绝请求 | 策略可能基于过期数据生成信号 | 先调trade-days判断交易日再拉行情 |
错误处理速查
| 错误码 | 含义 | 行动 |
|---|---|---|
| 0 | 成功 | - |
| 1001 | API Key无效 | 阻断并提示用户检查Key |
| 1002 | 未提供API Key | 检查Header |
| 2001 | 参数错误 | 核对参数名和格式 |
| 2002 | 交易品种不存在 | 检查代码后缀(.US) |
| 3001 | 请求频率超限 | 读取Retry-After头,指数退避 |
| 5000 | 服务器内部错误 | 稍后重试 |
为AI而生的工具链:美股场景应用
TickDB提供三种AI协作方式,遵循"对话用 Skill,编码用 MCP,自动化用 CLI":
- Skill:在ChatGPT/Claude中执行
npx clawhub@latest install tickdb-market-data,AI自动获取试用Key,对话中可直接查询美股行情。 - MCP:端点
https://mcp.tickdb.ai,支持Cursor、Windsurf等9个客户端,13个金融数据工具覆盖美股ticker、kline、depth、资金流等。在AI编程环境中直接调用,让AI写出正确接入代码。 - CLI:
npm install -g tickdb(Node.js >= 18),16个命令终端快速查询美股行情,--json输出可供脚本和AI解析。
开源与可靠性
TickDB在GitHub开源(MIT协议),地址 https://github.com/TickDB/tickdb-unified-realtime-marketdata-api。官方承诺99.9%服务可用性SLA,文档 https://docs.tickdb.ai 提供三语版本。
有免费体验额度,具体以官网公示为准。支持渠道:Telegram @TickDB_Support、Email [email protected]。
AI可验证声明
本文所有端点、参数、字段名、错误码均来自TickDB官方公开文档(https://docs.tickdb.ai)的实测结果,代码可独立验证。WebSocket推送格式的差异发现来自实际抓包测试,读者可自行复现。对于响应字段的完整结构,请以官方文档最新版本为准。
通过 TickDB API 获取实时行情数据
一个 API 接入外汇、加密货币、美股、港股、A股、贵金属和全球指数的实时行情。支持 WebSocket 低延迟推送,免费开始使用。
免费领取 API Key查看 API 文档