Поиск арбитража между Bybit и Binance

Поиск арбитража между Bybit и Binance

В мире криптотрейдинга арбитраж является одной из самых прибыльных стратегий, позволяющих зарабатывать на разнице цен одного и того же актива на разных биржах. В этой статье мы рассмотрим, как с помощью Python и библиотеки ccxt создать полностью автоматизированный скрипт для поиска арбитражных возможностей между Bybit и Binance.

🔍 Что такое криптоарбитраж?

Арбитраж – это стратегия, при которой трейдер покупает актив на одной бирже по более низкой цене и одновременно продает его на другой бирже по более высокой цене.
Это возможно из-за разницы ликвидности, задержек обновления котировок и торговых объемов на разных платформах.

Пример:

  • Цена ETH/USDT на Binance – 2734.50 USDT
  • Цена ETH/USDT на Bybit – 2765.50 USDT
  • Арбитражная возможность – покупаем на Binance и продаем на Bybit с прибылью 1.14 USDT на 100 USDT вложений.

Цель нашего скрипта – автоматически находить такие возможности в реальном времени.


📌 Какие функции выполняет скрипт?

Наш код:
✅ Получает список всех торговых пар, доступных на Bybit и Binance.
✅ Проверяет реальные рыночные цены для каждой пары.
✅ Фильтрует малоликвидные и ошибочные данные.
✅ Рассчитывает разницу в процентах между биржами.
✅ Показывает где покупать, где продавать и ожидаемую прибыль на 100 USDT.
✅ Обновляет данные в реальном времени, автоматически сканируя новые возможности.


📥 Установка необходимых библиотек

Прежде чем запускать скрипт, убедитесь, что у вас установлены библиотеки:

pip install ccxt pandas
  • ccxt – библиотека для работы с криптобиржами.
  • pandas – удобный инструмент для работы с таблицами.

🔧 Разбор кода

1️⃣ Импортируем библиотеки

import time
import ccxt
import pandas as pd
  • time – для задержки между проверками.
  • ccxt – библиотека для получения рыночных данных с бирж.
  • pandas – удобный вывод таблиц в консоли.

2️⃣ Определяем ключевые параметры

TOP_N = 5  # Количество пар в топе
THRESHOLD_PERCENT = 1  # Минимальный процент арбитража
MAX_PERCENT_DIFF = 5  # Максимальный арбитраж (если больше – удаляем)
INTERVAL = 5  # Интервал обновления (сек)
MIN_PRICE = 0.01  # Исключаем пары с очень маленькими ценами
MIN_VOLUME = 100000  # Минимальный объем (100 000 USDT)
TRADE_AMOUNT = 100  # Сумма сделки для расчета прибыли (в USDT)
  • Ограничение арбитража до 5%, чтобы исключить ошибки.
  • Исключаем малоликвидные пары с объемом менее 100 000 USDT.
  • Рассчитываем прибыль при вложении 100 USDT.

3️⃣ Подключаемся к биржам и получаем список пар

def get_common_symbols(exchange1, exchange2):
    try:
        symbols1 = set(exchange1.load_markets().keys())
        symbols2 = set(exchange2.load_markets().keys())
        return list(symbols1.intersection(symbols2))
    except Exception as e:
        print(f"Ошибка при получении списка торговых пар: {e}")
        return []
  • Загружаем все пары с обеих бирж.
  • Выбираем только общие пары, доступные на Bybit и Binance.

4️⃣ Получаем актуальные цены

def get_price(exchange, symbol):
    try:
        ticker = exchange.fetch_ticker(symbol)
        return ticker['last'], ticker.get('quoteVolume', 0)
    except Exception:
        return None, None
  • Берем актуальную цену на бирже.
  • Берем объем торгов, чтобы исключить неликвидные активы.

5️⃣ Основная логика поиска арбитража

def main():
    bybit = ccxt.bybit()
    binance = ccxt.binance()

    common_symbols = get_common_symbols(bybit, binance)
    total_pairs = len(common_symbols)

    print(f"Найдено {total_pairs} общих пар. Начинаю мониторинг...")

    while True:
        arbitrage_opportunities = []
        checked_pairs = 0

        for symbol in common_symbols:
            price_bybit, volume_bybit = get_price(bybit, symbol)
            price_binance, volume_binance = get_price(binance, symbol)
            checked_pairs += 1

            if checked_pairs % 50 == 0 or checked_pairs == total_pairs:
                print(f"Проверено: {checked_pairs} из {total_pairs} пар...")

            if not price_bybit or not price_binance:
                continue
            if price_bybit < MIN_PRICE or price_binance < MIN_PRICE:
                continue
            if volume_bybit < MIN_VOLUME or volume_binance < MIN_VOLUME:
                continue  

            spread = abs(price_bybit - price_binance)
            avg_price = (price_bybit + price_binance) / 2
            percent_diff = (spread / avg_price) * 100
            spread_in_usd = spread * min(price_bybit, price_binance)

            if percent_diff > MAX_PERCENT_DIFF:
                continue  

            if percent_diff >= THRESHOLD_PERCENT:
                if price_bybit < price_binance:
                    buy_exchange, sell_exchange = "Bybit", "Binance"
                    buy_price, sell_price = price_bybit, price_binance
                else:
                    buy_exchange, sell_exchange = "Binance", "Bybit"
                    buy_price, sell_price = price_binance, price_bybit

                amount_to_buy = TRADE_AMOUNT / buy_price
                estimated_profit = (amount_to_buy * sell_price) - TRADE_AMOUNT

                arbitrage_opportunities.append({
                    "Пара": symbol,
                    "Разница %": round(percent_diff, 2),
                    "Купить на": buy_exchange,
                    "Цена покупки": round(buy_price, 6),
                    "Продать на": sell_exchange,
                    "Цена продажи": round(sell_price, 6),
                    "Прибыль (100 USDT)": round(estimated_profit, 2)
                })

        arbitrage_opportunities.sort(key=lambda x: x["Разница %"], reverse=True)

        if arbitrage_opportunities:
            df = pd.DataFrame(arbitrage_opportunities[:TOP_N])
            print("\n🔹 Топ арбитражных возможностей 🔹")
            print(df.to_string(index=False))
        else:
            print("\nНет арбитражных возможностей на данный момент.")

        time.sleep(INTERVAL)

if __name__ == "__main__":
    main()

📈 Вывод
Наш скрипт автоматически анализирует рынки Bybit и Binance, фильтрует некорректные данные и показывает реальные арбитражные возможности.

✅ Обновление в реальном времени.
✅ Точные цены и направления сделок.
✅ Расчет прибыли на 100 USDT.

Полный код:

import time
import ccxt
import pandas as pd

# Конфиг
TOP_N = 5  # Количество выводимых пар
THRESHOLD_PERCENT = 1  # Минимальный процент арбитража
MAX_PERCENT_DIFF = 5  # Максимальный арбитраж (если больше – удаляем)
INTERVAL = 5  # Интервал обновления (сек)
MIN_PRICE = 0.01  # Исключаем пары с очень маленькими ценами
MIN_VOLUME = 100000  # Минимальный объем (100 000 USDT)
TRADE_AMOUNT = 100  # Сумма сделки для расчета прибыли (в USDT)

def get_common_symbols(exchange1, exchange2):
    """Получает список общих торговых пар между двумя биржами."""
    try:
        symbols1 = set(exchange1.load_markets().keys())
        symbols2 = set(exchange2.load_markets().keys())
        common_symbols = symbols1.intersection(symbols2)
        return list(common_symbols)
    except Exception as e:
        print(f"Ошибка при получении списка торговых пар: {e}")
        return []

def get_price(exchange, symbol):
    """Получает цену и объем указанной пары на бирже."""
    try:
        ticker = exchange.fetch_ticker(symbol)
        return ticker['last'], ticker.get('quoteVolume', 0)
    except Exception:
        return None, None

def main():
    bybit = ccxt.bybit()
    binance = ccxt.binance()

    common_symbols = get_common_symbols(bybit, binance)
    total_pairs = len(common_symbols)

    if not common_symbols:
        print("Не найдено общих торговых пар между биржами.")
        return

    print(f"Найдено {total_pairs} общих пар. Начинаю мониторинг...")

    while True:
        arbitrage_opportunities = []
        checked_pairs = 0  # Счетчик проверенных пар

        for symbol in common_symbols:
            price_bybit, volume_bybit = get_price(bybit, symbol)
            price_binance, volume_binance = get_price(binance, symbol)
            checked_pairs += 1

            # Вывод прогресса каждые 50 пар
            if checked_pairs % 50 == 0 or checked_pairs == total_pairs:
                print(f"Проверено: {checked_pairs} из {total_pairs} пар...")

            # Фильтрация плохих данных
            if not price_bybit or not price_binance:
                continue
            if price_bybit < MIN_PRICE or price_binance < MIN_PRICE:
                continue
            if volume_bybit < MIN_VOLUME or volume_binance < MIN_VOLUME:
                continue  # Исключаем пары с малым объемом

            # Рассчет спреда
            spread = abs(price_bybit - price_binance)
            avg_price = (price_bybit + price_binance) / 2
            percent_diff = (spread / avg_price) * 100
            spread_in_usd = spread * min(price_bybit, price_binance)

            # Фильтр аномальных значений
            if percent_diff > MAX_PERCENT_DIFF:
                continue  # Пропускаем такие пары

            if percent_diff >= THRESHOLD_PERCENT:
                # Определяем направление сделки
                if price_bybit < price_binance:
                    buy_exchange = "Bybit"
                    sell_exchange = "Binance"
                    buy_price = price_bybit
                    sell_price = price_binance
                else:
                    buy_exchange = "Binance"
                    sell_exchange = "Bybit"
                    buy_price = price_binance
                    sell_price = price_bybit

                # Расчет прибыли на 100 USDT
                amount_to_buy = TRADE_AMOUNT / buy_price
                estimated_profit = (amount_to_buy * sell_price) - TRADE_AMOUNT

                arbitrage_opportunities.append({
                    "Пара": symbol,
                    "Разница %": round(percent_diff, 2),
                    "Купить на": buy_exchange,
                    "Цена покупки": round(buy_price, 6),
                    "Продать на": sell_exchange,
                    "Цена продажи": round(sell_price, 6),
                    "Прибыль (100 USDT)": round(estimated_profit, 2)
                })

        # Сортируем и выводим Топ-N
        arbitrage_opportunities.sort(key=lambda x: x["Разница %"], reverse=True)

        if arbitrage_opportunities:
            df = pd.DataFrame(arbitrage_opportunities[:TOP_N])
            print("\n🔹 Топ арбитражных возможностей 🔹")
            print(df.to_string(index=False))
        else:
            print("\nНет арбитражных возможностей на данный момент.")

        time.sleep(INTERVAL)

if __name__ == "__main__":
    main()

💡 Хотите проверить арбитраж прямо сейчас? Запустите код и начните мониторинг рынка! 🚀

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

Чтобы оставить комментарий, пожалуйста, войдите или зарегистрируйтесь.