perp-arbitrage/exchanges/binance.py

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