Level2 数据获取与接口:主流数据供应商与调用方式
在量化交易中,Level2 行情数据的获取是策略模拟与收益评估的基础。不同数据供应商在接口协议、数据频率、延迟特征及费用结构上存在显著差异。本章系统梳理国内主流 Level2 数据供应商(万得、聚宽、通联等)的 API 调用方式、数据频率与延迟指标,以及权限与费用模型,帮助学员建立数据获取层的完整认知。
3.1 主流数据供应商对比
国内 Level2 行情数据供应商主要分为三类:传统金融终端型(万得)、量化平台型(聚宽、优矿)、专业数据服务型(通联数据、恒生聚源)。下表从接口协议、数据覆盖、更新频率、适用场景四个维度进行对比:
| 供应商 | 接口协议 | 数据覆盖 | 更新频率 | 适用场景 |
|---|---|---|---|---|
| 万得 (Wind) | COM / .NET / Python API | 沪深 Level2、期货、期权、港股 | 3 秒快照 / 逐笔推送 | 机构投研、回测、实时监控 |
| 聚宽 (JoinQuant) | RESTful API / WebSocket | 沪深 Level2、指数、ETF | 3 秒快照 / Tick 级推送 | 量化策略开发、模拟交易 |
| 通联数据 (DataAPI) | HTTP / Python SDK | 沪深 Level2、期货、期权 | 3 秒快照 / 逐笔成交 | 学术研究、因子挖掘 |
| 优矿 (UQER) | RESTful API / WebSocket | 沪深 Level2、指数 | 3 秒快照 / Tick 级 | 策略回测、在线研究 |
| 恒生聚源 | JAVA / C++ SDK | 沪深 Level2、期货、债券 | 逐笔推送 / 实时快照 | 高频交易、机构系统 |
选型建议: 对于个人量化研究者,聚宽和通联数据的 Python SDK 上手成本最低;机构用户若需深度数据清洗与历史快照,万得 WindPy 是行业标准。高频策略建议优先选择支持 WebSocket 逐笔推送的供应商。
3.2 API 接口调用方式
Level2 数据接口主要分为两类:RESTful HTTP 轮询 和 WebSocket 实时推送。前者适合定时获取快照数据,后者适合逐笔成交与订单簿实时更新。以下以聚宽和通联为例展示典型调用方式。
3.2.1 聚宽 WebSocket 订阅示例
import websocket
import json
def on_message(ws, message):
data = json.loads(message)
# 处理 Level2 逐笔成交数据
print(f"股票代码: {data['code']}, 成交价: {data['price']}, 成交量: {data['volume']}")
def on_error(ws, error):
print(f"WebSocket 错误: {error}")
def on_close(ws, close_status_code, close_msg):
print("连接关闭")
def on_open(ws):
# 订阅深交所 Level2 逐笔成交
subscribe_msg = {
"cmd": "subscribe",
"channels": ["szse.level2.trade"]
}
ws.send(json.dumps(subscribe_msg))
ws = websocket.WebSocketApp("wss://data.joinquant.com/ws",
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.run_forever()
3.2.2 通联数据 RESTful 快照获取示例
import requests
import json
# 通联数据 API 端点
url = "https://api.tonglian.com/v1/level2/snapshot"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
params = {
"symbol": "000001.SZ",
"type": "snapshot",
"date": "2025-03-21"
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
snapshot = response.json()
print(f"最新价: {snapshot['last_price']}")
print(f"委买一档: {snapshot['bid1_price']} x {snapshot['bid1_volume']}")
print(f"委卖一档: {snapshot['ask1_price']} x {snapshot['ask1_volume']}")
else:
print(f"请求失败: {response.status_code}")
接口调用要点:
- 所有供应商均要求 API Key 或 Token 鉴权,请勿硬编码在公开代码中。
- WebSocket 连接需实现心跳机制(通常每 30 秒发送 ping),防止连接超时断开。
- RESTful 接口有频率限制(如万得限制每秒 5 次请求),超限会被封禁。
3.3 数据频率与延迟特征
Level2 行情数据频率分为三个层级:快照频率(3 秒/次)、逐笔频率(每笔成交/委托)、Tick 频率(交易所最小推送间隔)。延迟则受网络路径、供应商处理链路、本地解码速度三重影响。
典型延迟数据如下(以深交所 Level2 为例,网络环境为 BGP 多线机房):
| 数据层级 | 交易所推送间隔 | 供应商处理延迟 | 用户端接收延迟 | 总端到端延迟 |
|---|---|---|---|---|
| 快照数据 | 3 秒 | 200-500 ms | 50-100 ms | ~3.3 秒 |
| 逐笔成交 | 实时(微秒级) | 50-200 ms | 10-50 ms | ~200 ms |
| 逐笔委托 | 实时(微秒级) | 100-300 ms | 20-80 ms | ~350 ms |
延迟陷阱: 部分供应商在行情峰值时段(如开盘前 15 分钟)会主动降级推送频率,导致快照间隔从 3 秒延长至 6 秒甚至更长。高频策略必须设计超时重连与数据补全机制,避免因数据缺失产生虚假信号。
3.4 数据权限与费用模型
Level2 行情数据并非免费开放,交易所向数据供应商收取授权费,供应商再向终端用户转嫁成本。费用结构通常包含:基础订阅费(按年/月)、数据品种费(沪深/期货/期权)、接口调用费(按请求次数或并发连接数)。
| 供应商 | 基础订阅费(年) | 沪深 Level2 附加费 | 期货 Level2 附加费 | 接口调用限制 |
|---|---|---|---|---|
| 万得 | ¥30,000 - ¥80,000 | ¥10,000 / 年 | ¥15,000 / 年 | 5 次/秒,无并发限制 |
| 聚宽 | 免费(个人版) | ¥6,000 / 年 | ¥8,000 / 年 | 100 次/分钟,10 并发 |
| 通联数据 | ¥20,000 / 年 | ¥8,000 / 年 | ¥12,000 / 年 | 200 次/分钟,20 并发 |
| 优矿 | 免费(社区版) | ¥4,800 / 年 | ¥6,000 / 年 | 60 次/分钟,5 并发 |
费用优化策略:
- 个人研究优先使用聚宽或优矿的免费版 + Level2 附加包,年费控制在 ¥5,000 以内。
- 机构用户可考虑万得机构版 + 自建缓存层,减少重复请求,降低接口调用费。
- 期货 Level2 数据授权费通常高于股票,且需要单独向交易所申请(如中金所、大商所)。
3.5 数据获取架构设计建议
在实际量化系统中,Level2 数据获取层通常采用“推拉结合”架构:实时行情通过 WebSocket 推送进入内存队列,历史快照通过 RESTful 接口定时拉取并存入本地数据库。以下架构图展示典型实现:
架构要点:
- 实时推送数据直接进入内存队列,保证低延迟;历史拉取数据写入时序数据库,用于回测与复盘。
- 建议对 WebSocket 连接设置自动重连机制(指数退避),并记录断连期间的数据缺口,后续通过 RESTful 补拉。
- 数据落地时按“日期 + 股票代码”分区存储,便于后续批量读取与因子计算。