import asyncio
import websockets
import json

# Lista de monedas con contratos USDC en spot y futures
PAIRS = [
    ("DOGE", "dogeusdc", "dogeusdc"),
    ("1000PEPE", "1000pepeusdc", "1000pepeusdc"),
    ("SUI", "suiusdc", "suiusdc"),
    ("BNB", "bnbusdc", "bnbusdc"),
    ("ENA", "enausdc", "enausdc"),
    ("SOL", "solusdc", "solusdc"),
    ("XRP", "xrpusdc", "xrpusdc"),
    ("1000BONK", "1000bonkusdc", "1000bonkusdc"),
    ("NEAR", "nearusdc", "nearusdc"),
    ("BOME", "bomeusdc", "bomeusdc"),
    ("ORDI", "ordiusdc", "ordiusdc"),
    ("KAI", "kaiusdc", "kaiusdc"),
    ("1000SHIB", "1000shibusdc", "1000shibusdc"),
    ("LTC", "ltcusdc", "ltcusdc"),
    ("CRV", "crvusdc", "crvusdc"),
    ("UNI", "uniusdc", "uniusdc"),
    ("AVAX", "avaxusdc", "avaxusdc"),
    ("FIL", "filusdc", "filusdc"),
    ("TRUMP", "trumpusdc", "trumpusdc"),
    ("ARB", "arbusdc", "arbusdc"),
    ("ADA", "adausdc", "adausdc"),
    ("WIF", "wifusdc", "wifusdc"),
    ("LINK", "linkusdc", "linkusdc"),
    ("BCH", "bchusdc", "bchusdc"),
]

threshold_pct = 1.5
threshold_proximity = 0.5  # Consideramos cerca si estamos a 0.2% del threshold

# Memoria de precios
latest_prices = {name: {"spot": None, "futures": None} for name, _, _ in PAIRS}

# Memoria del último print
last_printed = {name: {"spot": None, "futures": None, "pct_diff": None} for name, _, _ in PAIRS}

async def listen_spot(name, symbol):
    uri = f"wss://stream.binance.com:9443/ws/{symbol}@bookTicker"
    async with websockets.connect(uri) as websocket:
        print(f"🔄 Conectado a Spot {name.upper()}")
        async for message in websocket:
            data = json.loads(message)
            bid = float(data["b"])
            latest_prices[name]["spot"] = bid

async def listen_futures(name, symbol):
    uri = f"wss://fstream.binance.com/ws/{symbol}@bookTicker"
    async with websockets.connect(uri) as websocket:
        print(f"🔄 Conectado a Futures {name.upper()}")
        async for message in websocket:
            data = json.loads(message)
            bid = float(data["b"])
            latest_prices[name]["futures"] = bid

async def monitor_diff(name):
    while True:
        spot = latest_prices[name]["spot"]
        futures = latest_prices[name]["futures"]

        if spot and futures:
            pct_diff = ((futures - spot) / spot) * 100
            abs_diff = abs(pct_diff)

            last = last_printed[name]

            # Cambios relevantes
            delta_diff = abs((last["pct_diff"] or 0) - pct_diff)
            relevant_change = delta_diff >= 0.05

            near_threshold = abs_diff >= (threshold_pct - threshold_proximity)

            # Si está cerca del threshold o cambia de forma significativa
            if near_threshold or relevant_change:
                print(f"[{name}] Spot: {spot:.6f} | Futures: {futures:.6f} | Δ: {pct_diff:.2f}%")
                last_printed[name]["spot"] = spot
                last_printed[name]["futures"] = futures
                last_printed[name]["pct_diff"] = pct_diff

                if abs_diff > threshold_pct:
                    print(f"🚨 [{name}] Desfase detectado ({pct_diff:.2f}%)")

        await asyncio.sleep(0.2)


async def main():
    tasks = []
    for name, spot_symbol, futures_symbol in PAIRS:
        tasks.append(listen_spot(name, spot_symbol))
        tasks.append(listen_futures(name, futures_symbol))
        tasks.append(monitor_diff(name))
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())
