Асинхронный сбор Funding Rate с Binance, Bybit и OKX на Python

Асинхронный сбор Funding Rate с Binance, Bybit и OKX на Python ИНВЕСТИЦИИ, ВКЛАДЫ и СБЕРЕЖЕНИЯ
Пошаговое руководство по созданию асинхронного скрипта на Python для одновременного сбора ставок финансирования (Funding Rate) с Binance, Bybit и OKX с использованием CCXT.
Суть: Готовый асинхронный скрипт на Python с использованием библиотеки CCXT для параллельного сбора ставок финансирования (Funding Rate) с бирж Binance, Bybit и OKX, минимизирующий задержки за счет неблокирующего ввода-вывода.

Исходный код

В количественном анализе и арбитраже ставки финансирования (Funding Rate) играют ключевую роль. Они определяют стоимость удержания позиций на рынке бессрочных фьючерсов и позволяют находить неэффективности между площадками. Однако последовательный опрос API нескольких бирж занимает слишком много времени, что недопустимо для высокочастотных стратегий.

Для решения этой задачи мы будем использовать асинхронный подход на базе библиотеки ccxt.async_support. Это позволит отправлять запросы к Binance, Bybit и OKX одновременно, сокращая общее время выполнения до скорости ответа самого медленного API.

Перед тем как разворачивать подобные скрипты в боевой среде, крайне важно протестировать их взаимодействие с биржами. Подробнее об этом вы можете прочитать в нашей статье Работа с Testnet API криптобирж в Python CCXT: Настройка.

Если вас интересует не только линейный деривативный рынок, но и опционы, рекомендуем ознакомиться с руководством Как извлечь исторические данные по опционам Deribit (Implied Volatility) с Python requests.

Кроме того, мониторинг рыночных аномалий и резких изменений ставок финансирования концептуально схож с отслеживанием критических событий в DeFi-сегменте. О методах такого мониторинга читайте в материале Мониторинг Flash Loan атак в Ethereum на Web3.py и Alchemy API.

Ниже представлен полный код асинхронного коллектора:

import asyncio
import ccxt.async_support as ccxt
import time
from typing import Dict, List, Any

SYMBOLS = ['BTC/USDT:USDT', 'ETH/USDT:USDT', 'SOL/USDT:USDT']

async def fetch_funding_for_exchange(exchange_id: str, symbols: List[str]) -> List[Dict[str, Any]]:
    exchange_class = getattr(ccxt, exchange_id)
    exchange = exchange_class({
        'enableRateLimit': True,
        'options': {
            'defaultType': 'swap',
        }
    })
    
    results = []
    try:
        await exchange.load_markets()
        valid_symbols = [sym for sym in symbols if sym in exchange.markets]
        
        if not valid_symbols:
            return results

        try:
            rates = await exchange.fetch_funding_rates(valid_symbols)
            for sym, rate_data in rates.items():
                results.append({
                    'exchange': exchange_id,
                    'symbol': sym,
                    'funding_rate': rate_data.get('fundingRate'),
                    'timestamp': rate_data.get('timestamp'),
                    'datetime': rate_data.get('datetime')
                })
        except Exception:
            tasks = []
            for sym in valid_symbols:
                tasks.append(exchange.fetch_funding_rate(sym))
            
            rates_responses = await asyncio.gather(*tasks, return_exceptions=True)
            for sym, resp in zip(valid_symbols, rates_responses):
                if isinstance(resp, Exception):
                    continue
                results.append({
                    'exchange': exchange_id,
                    'symbol': sym,
                    'funding_rate': resp.get('fundingRate'),
                    'timestamp': resp.get('timestamp'),
                    'datetime': resp.get('datetime')
                })
    except Exception as e:
        print(f'Ошибка при работе с {exchange_id}: {e}')
    finally:
        await exchange.close()
    return results

async def main():
    exchanges = ['binance', 'bybit', 'okx']
    start_time = time.time()
    
    tasks = [fetch_funding_for_exchange(ex, SYMBOLS) for ex in exchanges]
    all_results = await asyncio.gather(*tasks)
    
    print(f'\nСбор завершен за {time.time() - start_time:.2f} сек.\n')
    print('Биржа      | Символ          | Ставка %     | Время обновления')
    print('-' * 75)
    
    for exchange_res in all_results:
        for item in exchange_res:
            rate = item['funding_rate']
            rate_pct = f'{rate * 100:.4f}%' if rate is not None else 'N/A'
            dt = item['datetime'] or 'N/A'
            exchange_name = item['exchange'].upper()
            symbol_name = item['symbol']
            print(f'{exchange_name:<10} | {symbol_name:<15} | {rate_pct:<12} | {dt}')

if __name__ == \'__main__\':
    asyncio.run(main())

Разбор параметров

  • SYMBOLS: Список целевых торговых инструментов в унифицированном формате CCXT. Для бессрочных контрактов используется паттерн Base/Quote:Receipt (например, BTC/USDT:USDT).
  • ccxt.async_support: Асинхронный модуль библиотеки CCXT, использующий asyncio для выполнения неблокирующих сетевых запросов к биржам.
  • fetch_funding_rates: Метод для пакетного получения ставок финансирования. Если биржа не поддерживает этот метод для выбранных символов, скрипт автоматически переключается на конкурентные запросы через fetch_funding_rate.
  • asyncio.gather: Функция, которая запускает корутины параллельно и ожидает завершения всех задач. Это позволяет опрашивать Binance, Bybit и OKX одновременно.
  • exchange.close(): Метод для корректного закрытия HTTP-сессий. Его вызов в блоке finally гарантирует отсутствие утечек ресурсов при возникновении исключений.

Как запустить

Для запуска скрипта вам потребуется Python версии 3.8 или выше. Установите библиотеку ccxt:

pip install ccxt

Сохраните код в файл funding_collector.py и запустите его из терминала:

python funding_collector.py

Скрипт мгновенно опросит все три биржи в параллельном режиме и выведет структурированную таблицу с актуальными ставками финансирования.

Оцените статью
FinFluct