Интеграция бота с API Bybit

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Интеграция бота с API Bybit
Простая
~2-3 рабочих дня
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1062
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Интеграция бота с API Bybit

Bybit предоставляет REST и WebSocket API для торговли, мониторинга позиций и получения рыночных данных. Документация актуальна для Bybit V5 API — унифицированного эндпоинта, объединяющего spot, linear, inverse, option под одним интерфейсом.

Аутентификация

Bybit API использует HMAC-SHA256 подпись. Для приватных эндпоинтов:

import hmac
import hashlib
import time
import httpx

class BybitClient:
    BASE_URL = "https://api.bybit.com"

    def __init__(self, api_key: str, api_secret: str, testnet: bool = False):
        self.api_key = api_key
        self.api_secret = api_secret
        if testnet:
            self.BASE_URL = "https://api-testnet.bybit.com"

    def _sign(self, params: str, timestamp: int) -> str:
        sign_str = f"{timestamp}{self.api_key}5000{params}"
        return hmac.new(
            self.api_secret.encode('utf-8'),
            sign_str.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()

    async def get_wallet_balance(self, account_type: str = "UNIFIED") -> dict:
        timestamp = int(time.time() * 1000)
        params = f"accountType={account_type}"
        signature = self._sign(params, timestamp)

        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"{self.BASE_URL}/v5/account/wallet-balance",
                params={"accountType": account_type},
                headers={
                    "X-BAPI-API-KEY": self.api_key,
                    "X-BAPI-TIMESTAMP": str(timestamp),
                    "X-BAPI-RECV-WINDOW": "5000",
                    "X-BAPI-SIGN": signature
                }
            )
        return response.json()

Размещение ордеров

async def place_order(
    self,
    category: str,     # 'spot', 'linear', 'inverse'
    symbol: str,       # 'BTCUSDT'
    side: str,         # 'Buy' или 'Sell' (с заглавной!)
    order_type: str,   # 'Market' или 'Limit'
    qty: str,          # количество как строка
    price: str = None, # для limit ордеров
    time_in_force: str = "GTC"
) -> dict:
    payload = {
        "category": category,
        "symbol": symbol,
        "side": side,
        "orderType": order_type,
        "qty": qty,
        "timeInForce": time_in_force
    }
    if price:
        payload["price"] = price

    timestamp = int(time.time() * 1000)
    body = json.dumps(payload)
    signature = self._sign(body, timestamp)

    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{self.BASE_URL}/v5/order/create",
            content=body,
            headers={
                "X-BAPI-API-KEY": self.api_key,
                "X-BAPI-TIMESTAMP": str(timestamp),
                "X-BAPI-RECV-WINDOW": "5000",
                "X-BAPI-SIGN": signature,
                "Content-Type": "application/json"
            }
        )
    return response.json()

WebSocket для real-time данных

import asyncio
import websockets
import json

class BybitWebSocket:
    WS_URL = "wss://stream.bybit.com/v5/public/linear"

    async def subscribe_orderbook(self, symbol: str, depth: int = 50):
        async with websockets.connect(self.WS_URL) as ws:
            # Подписка
            await ws.send(json.dumps({
                "op": "subscribe",
                "args": [f"orderbook.{depth}.{symbol}"]
            }))

            async for message in ws:
                data = json.loads(message)
                if data.get("topic", "").startswith("orderbook"):
                    await self.process_orderbook(data)

    async def subscribe_private(self, api_key: str, api_secret: str):
        """Private WebSocket для уведомлений об ордерах"""
        ws_url = "wss://stream.bybit.com/v5/private"

        async with websockets.connect(ws_url) as ws:
            # Аутентификация
            expires = int((time.time() + 10) * 1000)
            sign = hmac.new(
                api_secret.encode(),
                f"GET/realtime{expires}".encode(),
                hashlib.sha256
            ).hexdigest()

            await ws.send(json.dumps({
                "op": "auth",
                "args": [api_key, expires, sign]
            }))

            # Подписка на исполнения ордеров
            await ws.send(json.dumps({
                "op": "subscribe",
                "args": ["order", "execution", "position"]
            }))

            async for message in ws:
                data = json.loads(message)
                await self.handle_private_event(data)

Rate limits

Bybit ограничивает количество запросов. Для V5 API:

  • REST: 120 запросов/сек на IP (общий), 10-600 запросов/сек на endpoint
  • WebSocket: до 480 подписок на соединение
import asyncio
from collections import deque

class RateLimiter:
    def __init__(self, max_requests: int, window_seconds: float):
        self.max_requests = max_requests
        self.window = window_seconds
        self.requests = deque()

    async def acquire(self):
        now = time.monotonic()
        # Удаляем устаревшие записи
        while self.requests and self.requests[0] < now - self.window:
            self.requests.popleft()

        if len(self.requests) >= self.max_requests:
            sleep_time = self.requests[0] + self.window - now
            await asyncio.sleep(sleep_time)

        self.requests.append(time.monotonic())

Обработка ошибок

Bybit возвращает retCode: 0 при успехе, ненулевой при ошибке:

def check_response(self, response: dict, operation: str):
    ret_code = response.get("retCode", -1)
    if ret_code != 0:
        error_msg = response.get("retMsg", "Unknown error")
        raise BybitAPIError(f"{operation} failed [{ret_code}]: {error_msg}")
    return response.get("result", {})

Основные коды ошибок: 10001 — неверный API key, 10006 — превышен rate limit, 110007 — недостаточно баланса, 130021 — ордер не найден. Для production бота — обработчик всех кодов с retry логикой для временных ошибок.