54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
import asyncio
|
|
import json
|
|
import websockets
|
|
import requests
|
|
|
|
class OKXPerpStream:
|
|
def __init__(self, quote_filters, chunk_size=50):
|
|
self.url = "wss://ws.okx.com:8443/ws/v5/public"
|
|
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://www.okx.com/api/v5/public/instruments"
|
|
params = {"instType": "SWAP"}
|
|
data = requests.get(url, params=params).json()
|
|
symbols = [item["instId"] for item in data["data"] if any(q in item["settleCcy"] for q in self.quote_filters)]
|
|
print("[OKX] 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("[OKX REST ERROR]", e)
|
|
return []
|
|
|
|
def normalize_symbol(self, symbol):
|
|
return symbol.replace("-SWAP", "").replace("-", "/")
|
|
|
|
def parse_tick(self, data):
|
|
symbol = data["instId"]
|
|
return {
|
|
"exchange": "okx",
|
|
"symbol": self.normalize_symbol(symbol),
|
|
"bid": float(data["bidPx"]),
|
|
"ask": float(data["askPx"]),
|
|
"bid_size": float(data["bidSz"]),
|
|
"ask_size": float(data["askSz"])
|
|
}
|
|
|
|
async def stream_chunk(self, symbols):
|
|
args = [{"channel": "tickers", "instId": s} for s in symbols]
|
|
async with websockets.connect(self.url) as ws:
|
|
await ws.send(json.dumps({"op": "subscribe", "args": args}))
|
|
async for msg in ws:
|
|
try:
|
|
data = json.loads(msg)
|
|
if "data" in data:
|
|
for item in data["data"]:
|
|
tick = self.parse_tick(item)
|
|
if tick:
|
|
yield tick
|
|
except Exception as e:
|
|
print("[OKX PARSE ERROR]", e)
|
|
|
|
async def stream(se |