Збір даних Open Interest з криптобірж: повне керівництво

Ручний збір даних Open Interest з криптобірж — це хаос із різних форматів та одиниць виміру, що спотворює аналітику деривативів. Ми автоматизуємо парсинг та агрегацію OI з кількох майданчиків в єдину схему зберігання, позбавляючи вас від рутини та помилок. Наша команда реалізує проєкт під ключ — від аудиту джерел до налаштування моніторингу та подальшої підтримки, щоб ви отримували надійні дані для торгових рішень.
Часті запитання

Збір (скрапінг) даних 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.

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

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1543
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142