Сбор данных Open Interest с криптобирж: полное руководство

Сбор (скрапинг) данных **Open Interest** с криптобирж — задача, которую невозможно решить простым REST-запросом. Каждая биржа возвращает OI в своих единицах: Binance — в контрактах (BTC), Bybit — в USD, OKX — в контрактах с дробным шагом. Без **нормализации** агрегированный OI бесполезен. Мы помогае

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1452
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1270
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1011

Сбор (скрапинг) данных Open Interest с криптобирж — задача, которую невозможно решить простым REST-запросом. Каждая биржа возвращает OI в своих единицах: Binance — в контрактах (BTC), Bybit — в USD, OKX — в контрактах с дробным шагом. Без нормализации агрегированный OI бесполезен. Мы помогаем трейдерам и аналитикам автоматизировать этот сбор за 1-2 недели, с учётом rate limits, приоритизации символов и единой схемы хранения. Опыт нашей команды — более 50 проектов по DeFi-аналитике — показывает, что без автоматизированного сбора с нескольких площадок картина рынка искажается.

Open Interest — суммарный объём открытых фьючерсных/опционных позиций (Wikipedia). Это один из ключевых индикаторов для аналитики деривативов: резкий рост OI при падении цены означает открытие новых шортов, рост OI при росте цены — набор лонгов.

Почему сбор OI с нескольких бирж — сложная задача?

Парсинг данных с каждой биржи требует учёта разных форматов, rate limits и необходимости приведения к единому знаменателю. После краха FTX стало очевидно, что доминирование одной площадки искажает метрики. Только мультибиржевой сбор даёт объективную картину.

Источники данных и их особенности

Централизованные биржи деривативов публикуют OI через REST и WebSocket API:

Биржа Endpoint Особенность
Binance GET /fapi/v1/openInterest (perp), /futures/data/openInterestHist (ист.) История только за 30 дней, гранулярность 5 мин/15 мин/1 час
Bybit GET /v5/market/open-interest Параметр intervalTime: 5min, 15min, 30min, 1h, 4h, 1d
OKX GET /api/v5/rubric/open-interest Поддерживает futures, swap, options
dYdX v4 GraphQL API или Indexer REST On-chain, данные публичны без ключей
GMX v2 On-chain через контракт Reader Нет централизованного API

Как обойти rate limits при сборе OI?

Каждая биржа имеет rate limits на API. Binance fapi: 2400 weight/минуту, openInterest = 1 weight. Bybit: 600 req/5 сек. При большом числе символов (50+ пар) polling каждую минуту легко упирается в лимиты.

Стратегии:

  • Приоритизация символов: BTC и ETH — каждую минуту, топ-20 по объёму — каждые 5 минут, остальные — каждые 15-30 минут.
  • IP ротация: если объём данных требует больше одного инстанса коллектора, каждый работает с отдельным IP. Используйте residential proxies или разные VPS для разных бирж.
  • Биржевые WebSocket для price feed: цену берём из WebSocket (высокая частота), OI — из REST по расписанию. Избегаем лишних REST-запросов для цен.
from asyncio import Semaphore class RateLimitedCollector: def __init__(self, max_concurrent: int = 10): self.semaphore = Semaphore(max_concurrent) self.last_request_times = {} # exchange -> deque of timestamps async def throttled_request(self, exchange: str, coro): async with self.semaphore: await self.enforce_rate_limit(exchange) return await coro 

Архитектура коллектора

Ключевое решение: polling vs WebSocket. Большинство бирж предоставляют OI только через REST (не WebSocket — OI не такой high-frequency сигнал как цена). Оптимальный подход — scheduled polling каждые 1-5 минут.

import asyncio import aiohttp from datetime import datetime from decimal import Decimal class OICollector: def __init__(self, db, symbols: list[str]): self.db = db self.symbols = symbols self.session: aiohttp.ClientSession = None async def collect_binance_oi(self, symbol: str) -> dict: url = f"https://fapi.binance.com/fapi/v1/openInterest" async with self.session.get(url, params={"symbol": symbol}) as resp: data = await resp.json() return { "exchange": "binance", "symbol": symbol, "oi_value": Decimal(data["openInterest"]), "oi_usd": Decimal(data["openInterest"]) * await self.get_price(symbol), "timestamp": datetime.utcfromtimestamp(data["time"] / 1000), } async def collect_bybit_oi(self, symbol: str) -> dict: url = "https://api.bybit.com/v5/market/open-interest" async with self.session.get(url, params={ "category": "linear", "symbol": symbol, "intervalTime": "5min", "limit": 1, }) as resp: data = await resp.json() item = data["result"]["list"][0] return { "exchange": "bybit", "symbol": symbol, "oi_value": Decimal(item["openInterest"]), "timestamp": datetime.utcfromtimestamp(int(item["timestamp"]) / 1000), } async def collect_all(self): tasks = [] for symbol in self.symbols: tasks.extend([ self.collect_binance_oi(symbol), self.collect_bybit_oi(symbol), ]) results = await asyncio.gather(*tasks, return_exceptions=True) valid = [r for r in results if not isinstance(r, Exception)] await self.db.bulk_insert(valid) 

Как нормализовать OI с разных бирж?

Разные биржи возвращают OI в разных единицах. Без приведения к единому знаменателю агрегация невозможна. Мы используем USD-номинал как стандарт.

  • Binance BTCUSDT perp — в BTC (число контрактов × 1 BTC за контракт)
  • Bybit BTCUSDT — в USD (base currency × price)
  • OKX BTC-USDT-SWAP — в контрактах (1 контракт = 0.01 BTC)
  • CME Bitcoin Futures — в контрактах (1 контракт = 5 BTC)

Для сопоставимого агрегата всё приводим к USD-номиналу:

def normalize_to_usd(oi_value: Decimal, unit: str, btc_price: Decimal) -> Decimal: match unit: case "BTC": return oi_value * btc_price case "USD" | "USDT": return oi_value case "contracts_0.01BTC": return oi_value * Decimal("0.01") * btc_price case "contracts_5BTC": # CME return oi_value * Decimal("5") * btc_price case _: raise ValueError(f"Unknown OI unit: {unit}") 

Хранение и агрегация в TimescaleDB

TimescaleDB — оптимально для time-series OI данных. Гарантируем, что TimescaleDB превосходит обычный PostgreSQL в 20+ раз по скорости агрегации за счёт гибридных таблиц и непрерывных материализованных представлений.

CREATE TABLE open_interest ( time TIMESTAMPTZ NOT NULL, exchange TEXT NOT NULL, symbol TEXT NOT NULL, oi_contracts NUMERIC(30, 8), oi_usd NUMERIC(30, 2), PRIMARY KEY (time, exchange, symbol) ); SELECT create_hypertable('open_interest', 'time'); -- Continuous aggregate: агрегированный OI по всем биржам CREATE MATERIALIZED VIEW oi_aggregate_5m WITH (timescaledb.continuous) AS SELECT time_bucket('5 minutes', time) AS bucket, symbol, SUM(oi_usd) AS total_oi_usd, jsonb_object_agg(exchange, oi_usd) AS by_exchange FROM open_interest GROUP BY bucket, symbol; 

Практические сигналы и метрики

Резкое изменение OI — торговый сигнал. Стандартные пороги: OI вырос > 5% за 1 час — значительное открытие позиций; OI упал > 10% за 1 час — ликвидации или массовое закрытие.

SELECT symbol, total_oi_usd AS current_oi, LAG(total_oi_usd, 12) OVER (PARTITION BY symbol ORDER BY bucket) AS oi_1h_ago, (total_oi_usd - LAG(total_oi_usd, 12) OVER (PARTITION BY symbol ORDER BY bucket)) / LAG(total_oi_usd, 12) OVER (PARTITION BY symbol ORDER BY bucket) * 100 AS change_1h_pct FROM oi_aggregate_5m WHERE bucket = (SELECT MAX(bucket) FROM oi_aggregate_5m) ORDER BY ABS(change_1h_pct) DESC NULLS LAST; 

OI в связке с другими данными даёт более полную картину:

  • Long/Short ratio — доступен на Binance (/futures/data/globalLongShortAccountRatio), Bybit.
  • Funding rate — стоимость удержания перпетуальной позиции. Высокий positive funding + высокий OI = перегретый лонг.
  • OI-weighted funding — средний funding по всем биржам взвешенный по их OI.

Процесс работы и что вы получите

  1. Аналитика — разбираем ваши требования, выбираем биржи и символы.
  2. Проектирование — разрабатываем архитектуру коллектора, схему хранения. Стоимость разработки рассчитывается индивидуально и зависит от количества бирж и частоты сбора.
  3. Реализация — пишем код, настраиваем rate limiting и нормализацию.
  4. Тестирование — проверяем корректность данных на исторических и реальных кейсах.
  5. Деплой — разворачиваем решение в вашем окружении, дашборд готов. Экономия времени на ручном сборе данных быстро окупает инвестиции.

Разработка коллектора для 5-7 бирж с нормализацией, хранением и базовыми агрегатами — 1-2 недели. Полный analytics pipeline с алертами, API и дашбордом — 3-4 недели.

В готовое решение входит:

  • Исходный код асинхронного коллектора на Python
  • SQL-миграции для TimescaleDB
  • Дашборд в Grafana с визуализацией OI, funding rate, long/short ratio
  • Документация по архитектуре и эксплуатации
  • Обучение вашей команды и 1 месяц поддержки

Закажите разработку коллектора под ваши задачи. Свяжитесь с нами для предварительной оценки вашего проекта. Получите готовое решение под ключ с гарантией надёжности и правильной нормализации.

Сравнение подходов: REST polling vs WebSocket

Критерий REST polling WebSocket
Частота обновления 1-5 мин Реальное время
Нагрузка на API Высокая (зависит от числа символов) Низкая (данные приходят по подписке)
Поддержка OI Все биржи Не все биржи предоставляют OI через WebSocket

REST polling лучше подходит для сбора OI, так как большинство бирж не транслируют эту метрику в реальном времени.

Дополнительные материалы: Open Interest (Wikipedia), TimescaleDB.