文件预览

arbitrage.py

查看 money-toolkit 技能包中的文件内容。

文件内容

scripts/arbitrage.py

#!/usr/bin/env python3
"""跨所套利计算器"""
import json
import sys
import urllib.request
import urllib.error

COIN_SYMBOLS = {
    'btc': 'bitcoin', 'eth': 'ethereum', 'usdt': 'tether',
    'sol': 'solana', 'bnb': 'binancecoin', 'xrp': 'ripple',
    'ada': 'cardano', 'doge': 'dogecoin', 'dot': 'polkadot',
    'matic': 'matic-network'
}

def fetch_price(coin_id):
    """Fetch price from CoinGecko."""
    url = f"https://api.coingecko.com/api/v3/simple/price?ids={coin_id}&vs_currencies=usd"
    try:
        with urllib.request.urlopen(url, timeout=10) as r:
            data = json.loads(r.read())
            return data.get(coin_id, {}).get('usd', 0)
    except:
        return 0

def check_binance(symbol):
    url = f"https://api.binance.com/api/v3/ticker/price?symbol={symbol}USDT"
    try:
        with urllib.request.urlopen(url, timeout=10) as r:
            return float(json.loads(r.read()).get('price', 0))
    except:
        return 0

def check_okx(symbol):
    url = f"https://www.okx.com/api/v5/market/ticker?instId={symbol}-USDT"
    try:
        with urllib.request.urlopen(url, timeout=10) as r:
            data = json.loads(r.read())
            return float(data['data'][0]['last'])
    except:
        return 0

def check_bybit(symbol):
    url = f"https://api.bybit.com/v5/market/tickers?category=spot&symbol={symbol}USDT"
    try:
        with urllib.request.urlopen(url, timeout=10) as r:
            data = json.loads(r.read())
            return float(data['result']['list'][0]['lastPrice'])
    except:
        return 0

def check_arbitrage(coin):
    symbol = coin.upper()
    prices = {
        'Binance': check_binance(symbol),
        'OKX': check_okx(symbol),
        'Bybit': check_bybit(symbol)
    }
    
    valid = {k: v for k, v in prices.items() if v > 0}
    if len(valid) < 2:
        print(f"  ⚠️ {symbol}: 数据不足 | {prices}")
        return
    
    best = max(valid, key=valid.get)
    worst = min(valid, key=valid.get)
    spread = valid[best] - valid[worst]
    spread_pct = (spread / valid[worst]) * 100 if valid[worst] > 0 else 0
    
    if spread_pct > 0.1:
        arrow = "🔴"
    elif spread_pct > 0.01:
        arrow = "🟡"
    else:
        arrow = "🟢"
    
    print(f"  {arrow} {symbol}: 价差 {spread_pct:.3f}% | ${spread:.4f}")
    print(f"     最高: {best} (${valid[best]:,.2f}) | 最低: {worst} (${valid[worst]:,.2f})")

def main():
    coins = sys.argv[1:] if len(sys.argv) > 1 else ['btc', 'eth', 'sol', 'bnb']
    
    print("🏦 跨所套利扫描")
    print(f"{'─'*45}")
    for c in coins:
        check_arbitrage(c)
    
    print(f"\n💡 价差>0.1%有套利空间 | 需扣除手续费(0.1%)和滑点")
    print("💡 不包含转账时间和Gas费")

if __name__ == '__main__':
    main()