3. 数据源接入
在Tick数据工程流水线中,数据源接入是决定后续所有环节质量的上游关口。Tick数据具有频率高、来源杂、格式差异大、时序敏感等特点,如果接入层设计不当,后续的清洗、存储与因子计算都会被迫承担额外成本。本节围绕四类主流数据源——行情API、历史数据文件、实时推送协议以及多源采集策略,梳理其核心原理、接入方法与工程要点。
一、四类数据源的核心原理与特征
不同数据源在获取方式、时效性、数据粒度和稳定性上存在本质差异。理解这些差异,是选择接入方案的前提。
| 数据源类型 | 典型形式 | 时效性 | 主要优势 | 主要风险 |
|---|---|---|---|---|
| 行情API | REST/HTTP 接口 | 秒级至分钟级 | 接入简单、文档规范 | 限频、快照非逐笔 |
| 历史数据文件 | CSV/Parquet/二进制 | 离线批量 | 完整、可回溯、成本低 | 格式不统一、需解析 |
| 实时推送协议 | WebSocket/FIX/TCP | 毫秒级 | 低延迟、逐笔推送 | 断线重连、乱序、丢包 |
| 多源采集 | 组合上述多种 | 混合 | 冗余、互补、可校验 | 时钟对齐、去重复杂 |
行情API通常以请求-响应模式工作,适合拉取快照、K线和部分逐笔成交;历史数据文件适合回测与批量补数;实时推送协议是生产环境获取逐笔Tick的主力;多源采集则通过组合手段提升数据完整性与可靠性。
二、行情API接入方法与流程
行情API接入的关键在于认证、限频控制与数据解析。以常见的REST行情接口为例,接入流程通常包括:申请密钥、构造请求、处理响应、落盘缓存。下面是一个典型的Python接入片段:
import requests, time, json
API_URL = "https://api.example.com/v1/tick"
HEADERS = {"Authorization": "Bearer YOUR_"}
def fetch_tick(symbol):
params = {"symbol": symbol, "limit": 100}
resp = requests.get(API_URL, headers=HEADERS, params=params, timeout=5)
if resp.status_code == 429:
time.sleep(1.5) # 触发限频,退避重试
return fetch_tick(symbol)
return resp.json()
data = fetch_tick("BTCUSDT")
print(json.dumps(data[0], ensure_ascii=False))
工程上需要重点关注三点:一是限频策略,建议采用令牌桶或指数退避;二是响应校验,检查字段完整性与时间戳单调性;三是缓存落盘,避免重复请求造成浪费。
三、历史数据文件与实时推送协议
历史数据文件接入的核心是格式解析与批量导入。常见格式包括CSV、Parquet和交易所私有二进制格式。CSV可读性好但体积大,Parquet列式存储压缩率高、读取快,适合大规模Tick回测。接入时应统一时间戳单位(毫秒或微秒)、统一价格与数量精度,并保留原始字段映射关系。
实时推送协议以WebSocket最为常见,其接入要点包括:连接建立、订阅消息、心跳保活、断线重连与消息去重。下面是一个WebSocket订阅的简化示例:
import websocket, json
def on_message(ws, message):
tick = json.loads(message)
# 校验时间戳与序列号,防止乱序
print(tick["symbol"], tick["price"], tick["qty"], tick["ts"])
def on_open(ws):
ws.send(json.dumps({"op": "subscribe", "args": ["tick.BTCUSDT"]}))
ws = websocket.WebSocketApp(
"wss://stream.example.com/ws",
on_open=on_open,
on_message=on_message
)
ws.run_forever(ping_interval=20, ping_timeout=10)
实时推送必须处理三类异常:网络断连、消息乱序和重复推送。建议在接入层维护序列号窗口,对乱序消息进行缓冲排序,对重复消息按唯一键去重。
四、多源数据采集策略与复盘
单一数据源难以同时满足完整性、实时性和可靠性要求,因此生产级Tick流水线通常采用多源采集策略。常见组合是:实时WebSocket作为主通道,行情API作为快照补充,历史文件用于盘后补数与校验。
- 主备切换:主通道断线时自动切换备用通道,保证数据不中断。
- 交叉校验:用历史文件与实时流对比同一时间窗口的成交量,发现异常。
- 时钟对齐:统一使用UTC时间戳,记录采集端本地时间用于延迟分析。
- 去重合并:以交易所序列号或(时间戳, 价格, 数量)组合键去重。
从工程实践看,多源采集的价值不仅在于冗余,更在于可验证性。当实时流与历史文件在同一时间窗口出现显著偏差时,往往意味着某一通道存在丢包或解析错误,这正是数据质量监控的重要信号。接入层应记录每个数据源的采集延迟、消息量和异常次数,为后续排障提供依据。
综上,数据源接入不是简单的“连上就行”,而是需要在协议理解、异常处理、多源协同三个层面做扎实设计。只有接入层稳定可靠,Tick数据流水线的后续环节才能建立在可信的数据基础之上。