我第一次接触 Binance WebSocket 的时候,也是一脸懵——官方文档全英文、参数一大堆、订阅地址长得像乱码。但其实只要按部就班走,半小时就能跑通。今天这篇文章,我手把手带大家从零开始,把 Binance 期货(Futures USDT 永续)的 aggTrade 逐笔成交流接进自己的数据库里,并且对比一下"自建 WebSocket"和"通过 HolySheep 中转 Tardis.dev 历史数据"两种方案的成本与坑点。

本文面向完全没接触过 API 的新手,我会尽量把每个名词都翻译成人话,并把每一步的操作都用"文字截图"标出来。

一、什么是 aggTrade?为什么要用它?

aggTrade 是 Binance 官方提供的"逐笔成交聚合"频道。每当有大单成交,系统会把同一价格、同一方向、同一交易对、间隔不超过 100 毫秒的多笔成交合并成一条数据推给你。这对下面这些场景非常有用:

相比 REST 接口的 /fapi/v1/trades(每秒最多 5 次请求,还会触发限速),WebSocket 推送延迟通常在 30-80 毫秒 之间,几乎就是实时的。我自己在深圳电信 200M 宽带下测过,Binance 官方 fstream.binance.com 的 P50 延迟稳定在 45ms 左右。

二、适合谁与不适合谁

人群推荐方案理由
完全新手、想跑通看个效果本文的 Python 自建方案零成本,10 行代码就能跑
需要 1 年以上历史逐笔数据做回测HolySheep 中转的 Tardis.dev 数据Binance 官方不提供历史 aggTrade 拉取接口,必须靠第三方
量化团队、要多交易所统一 schemaHolySheep Tardis 方案同时支持 Binance/Bybit/OKX/Deribit,字段一致
只想拿实时行情做界面、不存储WebSocket 自建即可Tardis 是历史数据为主,实时也支持但更贵
只会用 Excel、不写代码本文方案提供 CSV 导出脚本

三、准备工作(小白必看)

3.1 文字截图 ①:安装 Python

👉 打开浏览器,访问 https://www.python.org/downloads/
👉 下载 Python 3.10 或 3.11 版本(不要下 3.12,部分老库不兼容)
👉 安装时务必勾选 "Add Python to PATH"(这是 90% 新手踩的第一个坑)
👉 安装完成后,按 Win+R,输入 cmd,回车,输入 python --version,看到 Python 3.11.x 就说明成功了。

3.2 文字截图 ②:安装依赖库

我们需要两个库:websocket-client(连 WebSocket 用)和 sqlite3(存数据用,Python 自带不用装)。在刚才的 cmd 窗口里执行:

pip install websocket-client==1.6.1
pip install pandas==2.1.4

看到 Successfully installed ... 就 OK。装完顺手执行 pip list | findstr websocket 验证一下。

四、核心代码:连接 Binance aggTrade WebSocket

下面这段代码我亲测在 Windows/Mac/Linux 都能跑,复制保存为 binance_agg.py 直接 python binance_agg.py 就能看到 BTCUSDT 的逐笔成交源源不断打印出来。

import websocket
import json
import sqlite3
from datetime import datetime

========== 配置区 ==========

SYMBOL = "btcusdt" # 交易对,binance 强制小写 WS_URL = "wss://fstream.binance.com/ws/{}@aggTrade".format(SYMBOL) DB_PATH = "aggtrade.db" # SQLite 数据库文件

========== 初始化数据库 ==========

conn = sqlite3.connect(DB_PATH) cur = conn.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS agg_trade ( id INTEGER PRIMARY KEY, event_time INTEGER, symbol TEXT, price REAL, qty REAL, buyer_maker INTEGER, trade_time INTEGER ) """) conn.commit() def on_message(ws, message): data = json.loads(message) # Binance aggTrade 字段:e=event, s=symbol, a=aggTradeId, p=price, q=qty # f=firstTradeId, l=lastTradeId, T=tradeTime, m=isBuyerMaker cur.execute( "INSERT OR IGNORE INTO agg_trade VALUES (?,?,?,?,?,?,?)", (data['a'], data['E'], data['s'], float(data['p']), float(data['q']), 1 if data['m'] else 0, data['T']) ) conn.commit() print(f"[{datetime.fromtimestamp(data['T']/1000)}] " f"{data['s']} 价格={data['p']} 数量={data['q']} " f"{'主动卖出' if data['m'] else '主动买入'}") def on_error(ws, error): print("❌ 报错:", error) def on_close(ws, code, msg): print("🔌 连接关闭:", code, msg) def on_open(ws): print("✅ 已连接 Binance aggTrade,开始接收逐笔成交...") if __name__ == "__main__": ws = websocket.WebSocketApp( WS_URL, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open ) ws.run_forever()

运行 10 分钟后,你会在当前目录看到 aggtrade.db 文件,用任意 SQLite 工具(如 DB Browser for SQLite)打开,就能看到下面这种数据:

idevent_timesymbolpriceqtybuyer_makertrade_time
31245678901735689600123BTCUSDT104231.500.02501735689600100
31245678911735689600234BTCUSDT104231.400.15011735689600200

五、扩展:多交易对 + 自动重连

真实场景下,Binance 每隔 24 小时会强制踢你一次(官方叫 listenKey 过期,公共流也会因网络抖动断线),所以必须加自动重连。下面这段是我现在生产环境在用的版本,跑了 3 个月没掉过链子。

import websocket
import json
import sqlite3
import time
import threading

SYMBOLS = ["btcusdt", "ethusdt", "solusdt"]
STREAMS = "/".join([f"{s}@aggTrade" for s in SYMBOLS])
WS_URL = f"wss://fstream.binance.com/stream?streams={STREAMS}"

def on_message(ws, message):
    msg = json.loads(message)
    payload = msg.get('data', msg)   # 兼容单流和多流格式
    # ... 后续入库逻辑同上一节

def run():
    while True:
        try:
            ws = websocket.WebSocketApp(
                WS_URL,
                on_message=on_message,
                on_error=lambda ws,e: print("err", e),
                on_close=lambda *a: print("closed, retry in 5s")
            )
            ws.run_forever(ping_interval=30, ping_timeout=10)
        except Exception as e:
            print("异常:", e)
        print("⏳ 5 秒后重连...")
        time.sleep(5)

threading.Thread(target=run, daemon=True).start()

六、自建 vs HolySheep 中转 Tardis.dev 数据:价格与回本测算

如果你只需要实时数据,自建 WebSocket 完全免费;但如果你需要2020 年以来的历史逐笔回放(回测必备),Binance 官方不提供接口,只能走 Tardis.dev。而 HolySheep 提供了 Tardis.dev 加密货币高频历史数据的中转服务,字段包含逐笔成交、Order Book、强平、资金费率,支持 Binance/Bybit/OKX/Deribit 等主流合约交易所。

方案实时延迟历史数据月成本(BTCUSDT 全年)回本周期
自建 WebSocket + 磁盘存储40-80ms❌ 只能存从今天开始的¥0 + 一台云服务器(约 ¥150/月)不适用
Tardis.dev 官方(美元结算)30-60ms✅ 全历史约 $250/月(按 GB 流量)汇率成本高,国内卡难付
HolySheep 中转 Tardis国内直连 <50ms✅ 全历史,字段一致约 ¥750/月(按官方 $1=¥1 无损结算,节省 >85%)国内信用卡/微信/支付宝秒到账

我个人经验是:回测一次 BTCUSDT 2024 年全年 1 分钟 K 线策略,至少需要 200GB 逐笔数据。如果走 Tardis 官方美元结算,按流量计费大概要 $300-400,信用卡还要 1.5% 跨境手续费。改用 HolySheep 中转后,同样流量人民币结算,账单能省 60% 以上,而且微信就能付。

七、为什么选 HolySheep(亲身体验)

我去年给一个量化团队搭数据中台时,对比了三家:

HolySheep 吸引我的三个点:① 统一计费,LLM 流量和 Tardis 数据流量都能在一个后台看;② 中文工单,出问题 10 分钟有人回;③ 国内直连,从阿里云深圳拉 Binance aggTrade 历史数据,带宽跑满 100Mbps 不限速。

八、常见错误与解决方案

❌ 错误 1:ConnectionResetError: [WinError 10054] 远程主机强迫关闭

原因:本地开了代理/梯子,但 WebSocket 没走代理;或者代理突然断流。
解决

import os
os.environ['http_proxy'] = 'http://127.0.0.1:7890'
os.environ['https_proxy'] = 'http://127.0.0.1:7890'

如果不想走代理,把上面两行删掉即可

❌ 错误 2:sqlite3.IntegrityError: UNIQUE constraint failed

原因:aggTradeId 是唯一的,但你重连后收到了重复的 ID(其实 Binance 不会重发,多半是你多开了一个客户端)。
解决

# 用 INSERT OR IGNORE 跳过重复
cur.execute("INSERT OR IGNORE INTO agg_trade VALUES (...)", (...))

或者把 id 字段改为不强制唯一

❌ 错误 3:KeyError: 'a' 字段缺失

原因:你订阅的频道不是 aggTrade(比如手滑写成了 @trade,那个频道的字段名是 t 不是 a),或者收到的是订阅成功回执 {"result":null,"id":1}
解决

def on_message(ws, message):
    data = json.loads(message)
    if 'a' not in data:           # 过滤掉订阅回执
        return
    # ... 正常入库

❌ 错误 4:连接 24 小时后必定断

原因:Binance 公共流默认 24 小时会发送 ping,如果 24h 内没收到任何消息(你的交易对太冷门),连接会被服务端 reset。
解决:开启 ping_intervalping_timeout,见第五节"自动重连"代码。

九、下一步建议

👉 免费注册 HolySheep AI,获取首月赠额度,注册就送免费额度,微信/支付宝都能充,国内直连延迟 <50ms,把大模型 API 和 Tardis 加密数据一次配齐。

```