Интеграция API Bybit в мобильное криптоприложение
Bybit V5 API — это унифицированный интерфейс, который объединил Spot, Linear, Inverse и Option под одним базовым URL. Звучит удобно, пока не столкнёшься с тем, что одни и те же параметры (category, symbol) интерпретируются по-разному в зависимости от маршрута. Мобильная интеграция требует чёткого разграничения категорий ещё на уровне архитектуры.
Аутентификация и подпись в V5
Bybit использует HMAC-SHA256, как и большинство бирж, но есть отличие: параметры для GET-запросов конкатенируются как timestamp + api_key + recv_window + queryString, а для POST — timestamp + api_key + recv_window + rawBody. Тело запроса передаётся как JSON (не form-encoded), что нетипично для REST API бирж.
Ошибка ret_code: 10002 («Request timestamp expired») на Android появляется даже при recvWindow=20000, если устройство использует NTP-сервер с задержкой. Решение то же, что с Binance — кешируем serverTime с /v5/market/time и вычитаем локальное смещение.
Отдельная история — ротация API-ключей. Bybit поддерживает IP-whitelist на уровне ключа: если пользователь работает через мобильный интернет с динамическим IP, whitelist не применим. Важно передавать пользователям информацию о рисках открытых ключей (без IP-привязки) и убирать разрешения на вывод средств из mobile-ключей по умолчанию.
WebSocket V5: отличия от предыдущих версий
wss://stream.bybit.com/v5/public/spot — публичный стрим. wss://stream.bybit.com/v5/private — приватный, требует аутентификации через auth operation сразу после подключения:
{
"op": "auth",
"args": ["api_key", "expires", "signature"]
}
expires — Unix timestamp в миллисекундах плюс 1000 (действителен 1 секунду). Signature — HMAC-SHA256("GET/realtime" + expires). Ошибка {"op":"auth","success":false,"ret_msg":"api_key not found"} обычно означает, что ключ создан для Testnet, а подключение идёт к Mainnet.
Bybit не требует периодического продления listenKey — авторизация на уровне WebSocket-сессии. Но сессия разрывается при длительном отсутствии activity. Keepalive через {"op":"ping"} каждые 20 секунд — обязательно.
На iOS фоновый режим требует VoIP entitlement или фоновую задачу через BGTaskScheduler, если нужно отслеживать исполнение ордеров. Иначе — только push-уведомления через серверный компонент.
Особенности Bybit для мобильных трейдеров
Bybit поддерживает Unified Trading Account (UTA) — режим, где маржа разделяется между Spot, Derivatives и Options. Это означает, что запрос баланса (/v5/account/wallet-balance) может вернуть один аккаунт с несколькими coin-записями и агрегированным totalEquity. Парсинг требует защиты от null в полях unrealisedPnl и cumRealisedPnl — они отсутствуют для Spot.
Order Book через WebSocket-стрим orderbook.{depth}.{symbol} приходит двумя типами сообщений: type: "snapshot" (полный снимок) и type: "delta" (изменения). Реализация локального стакана: применяем дельту к снапшоту, удаляем уровни с size: "0", поддерживаем sorted структуру (TreeMap в Android, SortedDictionary в .NET MAUI). Типичный баг — игнорирование u (update ID) и нарушение порядка применения дельт при переподключении.
Стек и процесс
Для нативного Android: Retrofit 2 + OkHttp + kotlinx.serialization (быстрее Gson для больших JSON-ответов стакана). Для iOS: URLSession + Combine + Codable с кастомным KeyDecodingStrategy для snake_case полей Bybit.
Тестируем на Bybit Testnet (api-testnet.bybit.com) — там доступен faucet для получения тестовых монет. Обязательно покрываем тестами логику применения orderbook delta: загружаем заранее записанные WebSocket-сессии и воспроизводим их в MockWebServer.
Оценка проекта начинается с уточнения: нужен ли UTA или Classic Account, какие категории (Spot / Linear / Inverse), нужна ли поддержка Copy Trading API. Срок базовой интеграции — 2–3 недели. Полный трейдинговый модуль — 5–10 недель.







