Исходный код
При парсинге DEX на Solana (в частности, Raydium) классический HTTP-поллинг быстро приводит к лимитам (Rate Limits) и бану IP-адреса. Raydium использует ликвидность OpenBook (Serum) для лимитных ордеров. Чтобы получить актуальный стакан, нам нужно напрямую читать данные аккаунтов marketBids и marketAsks. Ниже представлен асинхронный скрипт на Python, реализующий ротацию RPC-узлов и резидентных прокси для безопасного получения сырых данных стакана.
Для построения отказоустойчивой архитектуры сбора данных рекомендуется использовать брокеры сообщений. Подробнее об этом читайте в статье Интеграция Kafka для обработки потоковых тиковых данных на Python. Если вы планируете масштабировать сбор на сотни торговых пар, ознакомьтесь с материалом про Мультиплексирование WebSocket Binance Futures на Python.
import asyncio
import aiohttp
import random
from typing import List, Dict, Any, Optional
# Список ваших приватных или публичных RPC-узлов Solana для ротации
RPC_ENDPOINTS: List[str] = [
"https://api.mainnet-beta.solana.com",
"https://solana-api.projectserum.com",
"https://rpc.ankr.com/solana"
]
# Список резидентных прокси (формат: http://user:pass@ip:port)
PROXY_POOL: List[str] = [
"http://user1:pass1@residential.proxyprovider.com:9000",
"http://user2:pass2@residential.proxyprovider.com:9000",
"http://user3:pass3@residential.proxyprovider.com:9000"
]
class RaydiumOrderbookParser:
def __init__(self, rpc_urls: List[str], proxies: List[str]):
self.rpc_urls = rpc_urls
self.proxies = proxies
def _get_route(self) -> tuple[str, Optional[str]]:
"""Возвращает случайный RPC-узел и прокси для запроса."""
rpc = random.choice(self.rpc_urls)
proxy = random.choice(self.proxies) if self.proxies else None
return rpc, proxy
async def fetch_account_data(self, session: aiohttp.ClientSession, account_pubkey: str) -> Optional[Dict[str, Any]]:
"""Получает сырые данные аккаунта Solana с использованием ротации."""
rpc_url, proxy = self._get_route()
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "getAccountInfo",
"params": [
account_pubkey,
{"encoding": "base64"}
]
}
try:
async with session.post(rpc_url, json=payload, proxy=proxy, timeout=10) as response:
if response.status == 200:
result = await response.json()
if "result" in result and result["result"]["value"]:
return result["result"]["value"]
else:
print(f"Аккаунт {account_pubkey} не найден или пуст.")
else:
print(f"Ошибка HTTP {response.status} на узле {rpc_url}")
except Exception as e:
print(f"Сбой запроса через {rpc_url} (Прокси: {proxy}): {e}")
return None
async def main():
# Адрес аккаунта Bids (аски/биды) для конкретного рынка OpenBook/Raydium
# Например, SOL/USDC OpenBook Market Bids
sol_usdc_bids_address = "5jF7K88ZhhBsDMkWST787UcH68766gV6T67mDq98g"
parser = RaydiumOrderbookParser(RPC_ENDPOINTS, PROXY_POOL)
async with aiohttp.ClientSession() as session:
print("Запуск парсинга стакана Raydium...")
for iteration in range(5):
print(f"Итерация {iteration + 1}: запрос данных...")
data = await parser.fetch_account_data(session, sol_usdc_bids_address)
if data:
raw_bytes_info = data.get("data", [])
print(f"Успешно получено байт: {len(raw_bytes_info[0]) if raw_bytes_info else 0}")
await asyncio.sleep(2)
if __name__ == "__main__":
asyncio.run(main()) Разбор параметров
RPC_ENDPOINTS: Список эндпоинтов нод Solana. Для продакшена рекомендуется использовать платные тарифы от Helius, QuickNode или Triton, так как публичные ноды имеют жесткие лимиты на количество запросов в секунду (RPS).PROXY_POOL: Список резидентных или мобильных прокси-серверов. Резидентные прокси мимикрируют под обычных домашних пользователей, что делает их блокировку со стороны Cloudflare (защищающего API Raydium) практически невозможной.getAccountInfo: Метод JSON-RPC Solana для получения состояния аккаунта. Мы запрашиваем данные в форматеbase64, чтобы затем локально декодировать структуру стакана (Slab) OpenBook._get_route: Внутренний метод класса, реализующий простейшую балансировку нагрузки (Load Balancing) путем случайного выбора пары RPC + Proxy для каждого отдельного запроса.
Как запустить
Для запуска скрипта вам понадобится интерпретатор Python версии 3.8 или выше и библиотека aiohttp для выполнения асинхронных HTTP-запросов.
Установите необходимую зависимость в вашем терминале:
pip install aiohttp Замените демонстрационные адреса в RPC_ENDPOINTS и PROXY_POOL на ваши реальные данные. Запустите скрипт:
python main.py Полученные бинарные данные стакана необходимо декодировать в соответствии с макетом структуры OpenBook Market (используя библиотеки construct или готовые парсеры). Если вам требуется передавать полученные сигналы в торговые модули на C++ с минимальной задержкой, изучите руководство Как связать Python и C++ через ZeroMQ для передачи сигналов.




