Метрика Taker Buy/Sell Ratio является одним из ключевых индикаторов активности участников рынка, позволяя оценить доминирование покупателей или продавцов, агрессивно исполняющих свои ордера по рыночной цене. В отличие от обычного объема, который включает как лимитные, так и рыночные ордера, Taker Buy/Sell Ratio фокусируется исключительно на ‘taker’ активности, то есть на тех участниках, которые ‘забирают’ ликвидность с рынка. Понимание этой метрики критически важно для квантов и трейдеров, стремящихся получить преимущество в высокочастотной торговле и анализе рыночной микроструктуры.
В этой статье мы покажем, как создать надежный Python-скрипт для сбора данных AggTrades с Binance и расчета Taker Buy/Sell Ratio в реальном времени. Мы будем использовать асинхронное программирование для эффективной обработки потоковых данных, что является стандартом в работе с биржевыми API. Если вы интересуетесь другими продвинутыми торговыми стратегиями, рекомендуем ознакомиться с нашей статьей Автоматическое Дельта-Хеджирование на Deribit с Python: Гайд для Квантов.
Исходный код
Представленный ниже скрипт подключается к WebSocket API Binance для получения агрегированных тиковых сделок (AggTrades) по указанному символу. Он использует класс TakerRatioCalculator для обработки входящих сообщений, определения типа taker-ордера (покупка или продажа) и расчета Taker Buy/Sell Ratio в скользящем окне. Результаты выводятся в консоль, предоставляя актуальное представление о рыночной агрессии.
import asyncio
import websockets
import json
import pandas as pd
from collections import deque
class TakerRatioCalculator:
def __init__(self, symbol: str, window_size: int = 100):
self.symbol = symbol.upper()
self.window_size = window_size
self.trades_buffer = deque(maxlen=window_size)
self.taker_buy_volume = 0.0
self.taker_sell_volume = 0.0
print(f"[INFO] Инициализирован калькулятор для {self.symbol} с окном {self.window_size} сделок.")
def _process_trade(self, trade_data: dict):
"""
Обрабатывает одну агрегированную сделку, определяя ее как Taker Buy или Taker Sell.
'm': true - buyer is maker, means seller is taker (Taker Sell)
'm': false - seller is maker, means buyer is taker (Taker Buy)
"""
quantity = float(trade_data['q']) # Количество
price = float(trade_data['p']) # Цена
is_buyer_maker = trade_data['m'] # True, если покупатель - мейкер
trade_volume = quantity * price
if is_buyer_maker: # Покупатель - мейкер -> продавец - тейкер -> Taker Sell
self.taker_sell_volume += trade_volume
return 'sell', trade_volume
else: # Продавец - мейкер -> покупатель - тейкер -> Taker Buy
self.taker_buy_volume += trade_volume
return 'buy', trade_volume
def _update_buffer(self, trade_type: str, trade_volume: float):
"""
Добавляет новую сделку в буфер и удаляет старейшую, если буфер полон.
Обновляет суммарные объемы Taker Buy/Sell.
"""
if len(self.trades_buffer) == self.window_size:
old_trade_type, old_trade_volume = self.trades_buffer.popleft()
if old_trade_type == 'buy':
self.taker_buy_volume -= old_trade_volume
else:
self.taker_sell_volume -= old_trade_volume
self.trades_buffer.append((trade_type, trade_volume))
def _calculate_ratio(self) -> float:
"""
Рассчитывает Taker Buy/Sell Ratio.
Ratio = Taker Buy Volume / (Taker Buy Volume + Taker Sell Volume)
"""
total_taker_volume = self.taker_buy_volume + self.taker_sell_volume
if total_taker_volume == 0:
return 0.5 # Нейтральное значение, если нет объема
return self.taker_buy_volume / total_taker_volume
async def _handle_message(self, message: str):
"""
Обрабатывает входящее сообщение WebSocket.
"""
data = json.loads(message)
if data['e'] == 'aggTrade': # Проверяем, что это агрегированная сделка
trade_type, trade_volume = self._process_trade(data)
self._update_buffer(trade_type, trade_volume)
if len(self.trades_buffer) == self.window_size: # Рассчитываем только когда буфер заполнен
ratio = self._calculate_ratio()
print(f"[{pd.to_datetime(data['E'], unit='ms')}] {self.symbol} Taker Buy/Sell Ratio: {ratio:.4f} (Buy: {self.taker_buy_volume:.2f}, Sell: {self.taker_sell_volume:.2f})")
async def main():
symbol = "BTCUSDT"
window_size = 200 # Количество последних сделок для расчета соотношения
calculator = TakerRatioCalculator(symbol, window_size)
uri = f"wss://stream.binance.com:9443/ws/{symbol.lower()}@aggTrade"
print(f"[INFO] Подключение к WebSocket: {uri}")
async with websockets.connect(uri) as websocket:
print("[INFO] Подключено. Ожидание данных...")
while True:
try:
message = await websocket.recv()
await calculator._handle_message(message)
except websockets.exceptions.ConnectionClosedOK:
print("[INFO] Соединение закрыто.")
break
except Exception as e:
print(f"[ERROR] Произошла ошибка: {e}")
await asyncio.sleep(1) # Пауза перед повторной попыткой
if __name__ == "__main__":
asyncio.run(main())
Разбор параметров
symbol: Строка, представляющая торговую пару, для которой будет рассчитываться метрика. Например,"BTCUSDT"или"ETHUSDT". Регистр не имеет значения, так как скрипт преобразует его в верхний регистр.window_size: Целое число, определяющее размер скользящего окна для расчета Taker Buy/Sell Ratio. Это количество последних агрегированных сделок, которые будут учитываться при расчете. Большее значениеwindow_sizeсглаживает метрику, меньшее делает ее более чувствительной к краткосрочным изменениям.
Как запустить
Для запуска этого скрипта вам потребуется установленный Python 3.7+ и несколько библиотек. Если вы сталкиваетесь с проблемами при работе с API, возможно, вам будет полезна статья Обход Cloudflare на DexScreener: Скрипт на Python и Selenium, хотя для Binance WebSocket это не требуется.
-
Установите необходимые библиотеки: Откройте терминал или командную строку и выполните следующую команду:
pip install websockets pandas -
Сохраните код: Скопируйте предоставленный выше Python-код и сохраните его в файл с расширением
.py, например,taker_ratio_calculator.py. -
Запустите скрипт: Откройте терминал в директории, где вы сохранили файл, и выполните команду:
python taker_ratio_calculator.py -
Наблюдайте за результатом: Скрипт начнет подключаться к Binance WebSocket и выводить в консоль текущее значение Taker Buy/Sell Ratio по мере поступления новых данных и заполнения скользящего окна. Вы увидите логи, подобные этим:
[INFO] Инициализирован калькулятор для BTCUSDT с окном 200 сделок. [INFO] Подключение к WebSocket: wss://stream.binance.com:9443/ws/btcusdt@aggTrade [INFO] Подключено. Ожидание данных... [2023-10-27 10:30:01.123] BTCUSDT Taker Buy/Sell Ratio: 0.5234 (Buy: 12345.67, Sell: 11223.45) [2023-10-27 10:30:01.456] BTCUSDT Taker Buy/Sell Ratio: 0.5198 (Buy: 12500.10, Sell: 11500.20) ...Этот скрипт предоставляет базовую, но мощную основу для анализа рыночной агрессии. Вы можете расширить его функциональность, добавив сохранение данных в базу данных, визуализацию или интеграцию с торговыми стратегиями, например, как в статье Динамическое кредитное плечо по VIX на Python: Гайд для Квантов, адаптировав логику под метрики ликвидности.




