52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
import asyncio
|
|
import json
|
|
import websockets
|
|
import requests
|
|
|
|
class BinancePerpStream:
|
|
def __init__(self, quote_filters, chunk_size=50):
|
|
self.base_url = "wss://fstream.binance.com/stream"
|
|
self.quote_filters = quote_filters
|
|
self.chunk_size = chunk_size
|
|
self.symbol_chunks = self.get_symbol_chunks()
|
|
|
|
def get_symbol_chunks(self):
|
|
try:
|
|
url = "https://fapi.binance.com/fapi/v1/exchangeInfo"
|
|
data = requests.get(url).json()
|
|
symbols = [s["symbol"] for s in data["symbols"] if s["quoteAsset"] in self.quote_filters]
|
|
print("[BINANCE] Starting stream with", len(symbols), "symbols")
|
|
return [symbols[i:i+self.chunk_size] for i in range(0, len(symbols), self.chunk_size)]
|
|
except Exception as e:
|
|
print("[BINANCE REST ERROR]", e)
|
|
return []
|
|
|
|
def normalize_symbol(self, symbol):
|
|
return symbol.replace("USDT", "/USDT")
|
|
|
|
def parse_tick(self, msg):
|
|
data = msg.get("data")
|
|
if not data:
|
|
return None
|
|
symbol = data["s"]
|
|
return {
|
|
"exchange": "binance",
|
|
"symbol": self.normalize_symbol(symbol),
|
|
"bid": float(data["b"]),
|
|
"ask": float(data["a"]),
|
|
"bid_size": float(data["B"]),
|
|
"ask_size": float(data["A"])
|
|
}
|
|
|
|
async def stream_chunk(self, symbols):
|
|
streams = "/".join([f"{s.lower()}@bookTicker" for s in symbols])
|
|
url = f"{self.base_url}?streams={streams}"
|
|
async with websockets.connect(url) as ws:
|
|
async for msg in ws:
|
|
try:
|
|
data = json.loads(msg)
|
|
tick = self.parse_tick(data)
|
|
if tick:
|
|
yield tick
|
|
except Exception as e:
|
|
print("[BINANCE PAR |