import threading import time import json from exchanges.binance import BinancePerpStream from exchanges.okx import OKXPerpStream from exchanges.bybit import BybitPerpStream FEE = 0.0005 # taker fee FUNDING_WEIGHT = 1 # pondera funding rate (ex: por 8h) MIN_SPREAD = 0.4 # mínimo spread líquido para registrar # Lista de exchanges que você quer considerar na arbitragem ENABLED_EXCHANGES = {"bybit", "okx", "binance"} # Carrega funding de arquivo externo salvo periodicamente with open("funding_cache.json", "r") as f: funding_cache = json.load(f) def check_arbitrage_opportunities(new_tick, all_ticks): opportunities = [] symbol = new_tick['symbol'] if new_tick['exchange'].lower() not in ENABLED_EXCHANGES: return opportunities for (ex_name, ex_symbol), tick in all_ticks.items(): if ex_symbol != symbol or ex_name == new_tick['exchange']: continue for buyer, seller in [(new_tick, tick), (tick, new_tick)]: if buyer['exchange'].lower() not in ENABLED_EXCHANGES or seller['exchange'].lower() not in ENABLED_EXCHANGES: continue buy_price = buyer['ask'] * (1 + FEE) sell_price = seller['bid'] * (1 - FEE) if sell_price <= buy_price: continue spread = sell_price - buy_price spread_percent = (spread / buy_price) * 100 size = min(buyer['ask_size'], seller['bid_size']) buy_funding = funding_cache.get(symbol, {}).get(buyer['exchange'], 0.0) * 100 sell_funding = funding_cache.get(symbol, {}).get(seller['exchange'], 0.0) * 100 funding_carry = sell_funding - buy_funding net_spread_percent = spread_percent + FUNDING_WEIGHT * funding_carry if net_spread_percent > MIN_SPREAD: opportunities.append({ 'symbol': symbol, 'buy_exchange': buyer['exchange'], 'buy_price': buyer['ask'], 'sell_exchange': seller['exchange'], 'sell_price': seller['bid'], 'spread_percent': net_spread_percent, 'raw_spread_percent': spread_percent, 'buy_funding': buy_funding, 'sell_funding': sell_funding, 'size': size }) return opportunities