You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Binance期货Websocket获取Tick数据时重复数据问题及解决需求

解决Binance期货Tick数据重复接收的问题

我之前也碰到过Binance WebSocket推送重复Tick的情况,结合你的代码来看,主要有两个可以优化的点来避免重复数据:

1. 修复Socket上下文管理器的错误使用

你的代码在while True循环里每次都调用await socket.__aenter__(),这相当于每次循环都重新初始化Socket连接上下文,很可能导致重复订阅或者接收重复的推送消息。正确的做法是只在循环外进入一次上下文管理器。

2. 添加重复数据过滤逻辑

即使修复了Socket的问题,Binance偶尔还是会推送重复的Tick数据,我们可以通过记录最后处理过的消息标识(比如时间戳Time+价格Price,或者直接用毫秒级的时间戳,因为正常情况下同一毫秒不会有重复的Tick)来过滤掉重复项。

修正后的完整代码

import pandas as pd
from binance.client import Client
from binance import BinanceSocketManager
import asyncio

api_key = '***'
api_secret = '***'

# 初始化客户端和Socket
client1 = Client(api_key=api_key, api_secret=api_secret)
bsm = BinanceSocketManager(client1)
socket = bsm.individual_symbol_ticker_futures_socket(symbol='ETHUSDT')

# 转换为DataFrame的函数不变
def createframe(msg):
    df = pd.DataFrame([msg['data']])
    df = df.loc[:, ['s', 'E', 'c']]
    df.columns = ['symbol', 'Time', 'Price']
    df.Price = df.Price.astype(float)
    df.Time = pd.to_datetime(df.Time, unit='ms')
    return df

async def main():
    # 只进入一次Socket上下文,避免重复初始化
    async with socket:
        # 记录最后处理过的时间戳和价格,用于过滤重复
        last_time = None
        last_price = None
        while True:
            msg = await socket.recv()
            frame = createframe(msg)
            # 获取当前Tick的时间和价格
            current_time = frame.iloc[0]['Time']
            current_price = frame.iloc[0]['Price']
            # 对比是否和上一条重复,不重复才处理
            if current_time != last_time or current_price != last_price:
                print(frame)
                # 更新最后处理的记录
                last_time = current_time
                last_price = current_price
                # 这里可以添加写入SQLite的代码,确保只写入非重复数据

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

额外的数据库层面保障

如果担心还是有漏网的重复数据,你可以在SQLite的表中给symbol、Time和Price(或者单独给Time,因为毫秒级时间戳理论上唯一)添加唯一约束,这样即使有重复数据尝试写入,数据库也会自动拒绝,避免脏数据。

比如创建表的时候可以这样写:

CREATE TABLE IF NOT EXISTS futures_ticks (
    symbol TEXT,
    Time TIMESTAMP UNIQUE,
    Price REAL,
    PRIMARY KEY (symbol, Time)
);

这样既从代码层面过滤了大部分重复,又从数据库层面做了最后一道防线。

内容的提问来源于stack exchange,提问作者Ksharp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 04:27:36