Введение: что такое арбитраж по ставке финансирования
На крипто рынке у бессрочных фьючерсов существует специальный механизм: ставка финансирования (funding rate) - периодический платёж между держателями длинных (long) и коротких (short) позиций, который служит для выравнивания цены фьючерса с ценой спота.
Арбитраж по ставке финансирования - стратегия, цель которой не столько угадать движение цены, сколько извлечь выгоду из разницы в ставках финансирования на разных площадках или между контрактом и спотом.
Например: если фьючерс на актив торгуется с положительной ставкой +0.03 % за период, то держатели short получают оплату от long. Арбитражер может занять длинную позицию на споте и короткую на фьючерсе, тем самым оставаясь почти нейтральным к движению цены, и получать платёж по ставке. Или - если ставка отрицательная (short платят long) - можно действовать наоборот: short спот и long фьючерс.
Зачем это нужно и когда работает
Это стратегия с относительно низкой ориентированной на движение цены риском
Возможности возникают, когда ставка финансирования отклоняется от нуля или есть разница между площадками.
Нужно учитывать: сборы, проскальзывание, ликвидационный риск, требования маржи, переключения механизмов ставок.
Для начинающих важно понимать: это не «гарантированная» прибыль, а механизм, требующий мониторинга, автоматизации и расчёта.
Для автоматизации нахождения таких "расхождений" ставок финансирования я решил написать скрипт, который будет это делать за меня. Взял биржи: binance, bybit, mexc, okx. Торговля будет ручная, так как тут тоже важна насмотренность и анализ чарта - допустим, если монета улетела на сотни процентов, то лучше стоит ее просто пропустить.
Подробное описание скриптов и логики их работы
В этой части мы разберём внутреннюю архитектуру проекта — как устроены скрипты, какие API используются, как рассчитывается потенциальная прибыль и как всё это работает вместе. Проект состоит из менеджера скринеров и четырёх отдельных скринеров для бирж. Каждый скринер автономен, но следует единой логике.
1. main.py — Менеджер скринеров
Для начала создаем сердце проекта - main.py будет отвечать за координацию скриптов и логирование. Сразу импортируем будущие скрипты - MexcScreener.py и т.п. для удобства, чтобы не возвращаться сюда позже.
import logging
from screeners.mexc_screener import MexcScreener
from screeners.bybit_screener import BybitScreener
from screeners.okx_screener import OkxScreener
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class ScreenerManager:
def __init__(self):
self.screeners = [MexcScreener(), BybitScreener(), OkxScreener(), BinanceScreener()]
def run_screeners(self):
all_results = []
for screener in self.screeners:
data = screener.run()
data = data[:20] # Берём только топ-20
result = {
'ex_name': screener.name,
'coins': data
}
all_results.append(result)
# Запись в файл
with open('results.txt', 'w') as f:
for exchange in all_results:
f.write(f"============ Top {len(exchange['coins'])} coins in {exchange['ex_name']} ============\n")
for coin in exchange['coins']:
f.write(f"{coin['ticker']}. Funding rate: {coin['funding_rate']} - Potential Profit: {coin['potential_profit']:.6%}\n")
return all_results
Что делает:
Инициализирует все скринеры.
Запускает .run() у каждого.
Обрезает результат до топ-20 по potential_profit.
Формирует человекочитаемый отчёт в results.txt.
Логирует процесс через logging.
2. Базовая логика всех скринеров (общее ядро)
Каждый скринер следует одинаковому алгоритму:
Шаг |
Описание |
|---|---|
1 |
Получить список всех перпетульных контрактов |
2 |
Для каждого — получить текущую ставку финансирования |
3 |
Рассчитать потенциальную прибыль = |
4 |
Отсортировать по убыванию прибыли |
5 |
Вернуть топ-N (в нашем случае — 20) |
3. bybit_screener.py — Bybit
Ключевые эндпоинты для запросов к api:
Эндпоинт |
Что делает |
|---|---|
|
Все линейные перпетульные контракты (USDT-маржа) |
|
Последняя ставка финансирования |
Базовый url для формирования запросов - "https://api.bybit.com"
Важно: Bybit не отдаёт все funding rates одним запросов, нужно запрашивать по символу.
Блок 1: Импорты и настройка логирования
import requests, time, decimal, logging
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime
from typing import Dict, Any, List
import re
Что делает: Подключает библиотеки для работы с API (requests), параллельного выполнения (ThreadPoolExecutor), точных вычислений с денежными величинами (decimal), работы с датами и логирования.
Блок 2: Класс BybitScreener и инициализация
class BybitScreener:
BASE_URL = "https://api.bybit.com"
FUNDING_RATE_ENDPOINT = "/v5/market/funding/history"
INSTRUMENTS_INFO_ENDPOINT = "/v5/market/instruments-info"
def __init__(self):
self.name = 'Bybit'
self.contracts = self.get_all_contracts()
logger.info(f"Initialized with Bybit Screener{len(self.contracts)} contracts")
Что делает:
Определяет скринер для Bybit с базовым URL и необходимыми endpoint.
При создании объекта автоматически загружает список всех контрактов
Логирует количество доступных контрактов.
Блок 3: Получение списка контрактов
def get_all_contracts(self) -> List[Dict[str, Any]]:
url = f"{self.BASE_URL}{self.EXCHANGE_INFO_ENDPOINT}"
response = requests.get(url)
response.raise_for_status()
contracts = []
for symbol in response.json()['symbols']:
if symbol['contractType'] == 'PERPETUAL':
contracts.append({
'symbol': symbol['symbol'],
'takerFeeRate': decimal.Decimal(symbol.get('takerFee', '0')),
'makerFeeRate': decimal.Decimal(symbol.get('makerFee', '0'))
})
return contracts
Что делает:
Отправляет запрос к API Bybit для получения всех линейных контрактов.
Исключает фьючерсы с датой экспирации (не подходят для арбитража).
Для каждого контракта сохраняет символ и комиссии (
makerFeeRateиtakerFeeRate).Возвращает список контрактов для дальнейшего анализа.
Блок 4: Проверка экспирации контрактов
def is_future_dated_contract(self, symbol: str, current_date: datetime) -> bool:
match = re.search(r'-(\d{2})([A-Z]{3})(\d{2})$', symbol)
if match:
day, month, year = match.groups()
contract_date = datetime.strptime(f"20{year}-{month}-{day}", "%Y-%b-%d")
return contract_date > current_date
return False
Что делает:
Проверяет тикер контракта на наличие даты экспирации.
Использует регулярные выражения, чтобы понять, является ли контракт будущим фьючерсом.
Возвращает
True, если контракт истечёт позже текущей даты.
Блок 5: Получение текущей funding rate
def get_current_funding_rate(self, symbol: str) -> decimal.Decimal:
url = f"{self.BASE_URL}{self.FUNDING_RATE_ENDPOINT}"
params = {"symbol": symbol, "category": "linear", "limit": 1}
try:
response = requests.get(url, params=params)
response.raise_for_status()
funding_rate_data = response.json()['result']['list'][0]
return self.format_funding_rate(funding_rate_data)
except (requests.exceptions.HTTPError, IndexError, KeyError) as e:
logger.warning(f"Error fetching funding rate for {symbol}: {e}")
return decimal.Decimal('0')
Что делает:
Отправляет запрос к API Bybit, чтобы получить последнюю ставку финансирования.
Обрабатывает ошибки запроса и пустые данные.
Блок 6: Форматирование funding rate и расчёт прибыли
def format_funding_rate(self, funding_rate_data):
funding_rate = funding_rate_data.get('fundingRate', '0')
return decimal.Decimal(funding_rate).quantize(decimal.Decimal('1E-6'))
def calculate_potential_profit(self, funding_rate: decimal.Decimal, contract: Dict[str, Any]) -> decimal.Decimal:
total_fee = contract['makerFeeRate'] * 2
return funding_rate - total_fee
Что делает:
Преобразует строковое значение funding rate в
Decimal.Округляет до 6 знаков после запятой для удобства отображения и расчётов.
Учитывает комиссии биржи (двойную maker fee) при расчёте потенциальной прибыли.
Возвращает реальный доход, который можно получить после оплаты комиссий.
Блок 7: Анализ funding rates
def analyze_funding_rates(self):
funding_rates = []
with ThreadPoolExecutor(max_workers=5) as executor:
futures = {executor.submit(self.get_current_funding_rate, contract['symbol']): contract for contract in self.contracts}
for future in as_completed(futures):
contract = futures[future]
try:
rate = future.result()
potential_profit = self.calculate_potential_profit(rate, contract)
funding_rates.append({
'ticker': contract['symbol'],
'funding_rate': rate,
'potential_profit': potential_profit
})
except Exception as e:
logger.error(f"Error analyzing {contract['symbol']}: {e}")
sorted_rates = sorted(funding_rates, key=lambda x: x['potential_profit'], reverse=True)
return sorted_rates
Что делает:
Параллельно запрашивает funding rate для всех контрактов через
ThreadPoolExecutor.Вычисляет потенциальную прибыль для каждого контракта.
Сортирует контракты по
potential_profitпо убыванию.Возвращает список самых прибыльных контрактов.
Блок 9: Запуск скринера
def run(self):
logger.info("Starting BybitScreener")
try:
best_contracts = self.analyze_funding_rates()
logger.info(f"BybitScreener completed. Found {len(best_contracts)} contracts.")
return best_contracts
except Exception as e:
logger.error(f"An error occurred during BybitScreener execution: {e}")
return []
Что делает:
Объединяет все функции: загружает контракты, анализирует их funding rate, сортирует по доходности.
Логирует успешное завершение или ошибки выполнения.
Возвращает готовый список контрактов с потенциальной прибылью.
Остальные скринеры
Все остальные скрипты следуют аналогичной логике - разве что отличаются эндпоинты и подобные ньюансы. Для того, чтобы не томить читателей кодом, все остальные скринеры загружены на github - https://github.com/kir1l/Funding-Arbitrage-Screener
ВыводПо итогу, запустив скрипт мы получим вывод с лучшими монетками на биржах, и уже там можно будет собирать фандинг.
Ключ к успешному арбитражу — хеджирование: открытие противоположной позиции минимизирует ценовой риск, а прибыль формируется только за счёт funding rate. При этом важно учитывать комиссии, проскальзывание и требования маржи.
Аарбитраж ставок финансирования позволяет извлекать доход с относительно низким риском, используя автоматизированные скринеры для мониторинга возможностей на разных биржах. Хотя и от вас будет зависить многое - важна скорость принятия решений и возможность находится у терминала, но всё же такой терминал сильно упростит работу по арбитражу ставок финансирования.
dyadyaSerezha
Ещё одна статья о том "как заработать на крипте/трейдинге". Ещё одна статья без сути: "я вложил Х килобаксов и за N месяцев заработал в среднем M баксов в месяц со средним отклонением в O баксов и максимальным в P баксов.
Где все эти данные? А если их нет или стыдно публиковать, зачем все эти "зарабатывающие" скрипты? Не понимаю.