websockets и фреймворка asyncio для получения потоковых данных по грекам опционов (Delta, Gamma, Vega, Theta, Rho, IV) в реальном времени.Исходный код
Представленный ниже Python-код демонстрирует создание асинхронного клиента для подключения к Deribit WebSocket API. Клиент подписывается на канал options.greeks.{instrument_name}.100ms, что позволяет получать обновления греков опционов с интервалом в 100 миллисекунд. В коде предусмотрена логика автоматического переподключения в случае разрыва соединения, а также динамическое получение актуального имени инструмента для подписки.
Полученные в реальном времени греки могут быть использованы для различных целей: от мониторинга рыночной волатильности и оценки рисков до интеграции в сложные торговые стратегии. Например, для классификации рыночных событий на основе этих данных можно использовать продвинутые методы машинного обучения, как описано в статье CatBoost для Классификации Ложных Пробоев в Торговом Боте на Python.
import asyncio
import websockets
import json
import time
class DeribitGreeksClient:
def __init__(self, instrument_name: str, testnet: bool = True):
self.instrument_name = instrument_name
self.url = "wss://test.deribit.com/ws/api/v2" if testnet else "wss://www.deribit.com/ws/api/v2"
self.websocket = None
self.reconnect_interval = 5 # seconds
async def connect(self):
print(f"Connecting to Deribit WebSocket at {self.url}...")
try:
self.websocket = await websockets.connect(self.url)
print("Connected to Deribit WebSocket.")
await self.subscribe_to_greeks()
return True
except Exception as e:
print(f"Connection failed: {e}")
return False
async def subscribe_to_greeks(self):
channel = f"options.greeks.{self.instrument_name}.100ms"
subscribe_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "public/subscribe",
"params": {
"channels": [channel]
}
}
await self.websocket.send(json.dumps(subscribe_request))
print(f"Subscribed to channel: {channel}")
async def listen_for_messages(self):
while True:
try:
message = await self.websocket.recv()
data = json.loads(message)
if data.get("method") == "subscription":
channel = data["params"]["channel"]
greeks_data = data["params"]["data"]
print(f"Received Greeks for {channel}:")
print(f" Delta: {greeks_data.get('delta')}")
print(f" Gamma: {greeks_data.get('gamma')}")
print(f" Vega: {greeks_data.get('vega')}")
print(f" Theta: {greeks_data.get('theta')}")
print(f" Rho: {greeks_data.get('rho')}")
print(f" Implied Volatility: {greeks_data.get('iv')}")
print("-" * 30)
elif data.get("result"):
print(f"Subscription response: {data}")
elif data.get("error"):
print(f"Error: {data['error']}")
except websockets.exceptions.ConnectionClosedOK:
print("Connection closed gracefully.")
break
except websockets.exceptions.ConnectionClosedError as e:
print(f"Connection closed with error: {e}")
await self.handle_reconnect()
break
except Exception as e:
print(f"An unexpected error occurred: {e}")
await self.handle_reconnect()
break
async def handle_reconnect(self):
print(f"Attempting to reconnect in {self.reconnect_interval} seconds...")
await asyncio.sleep(self.reconnect_interval)
while not await self.connect():
print(f"Reconnection failed, retrying in {self.reconnect_interval} seconds...")
await asyncio.sleep(self.reconnect_interval)
print("Reconnected successfully.")
# After reconnecting, the subscription needs to be re-established
await self.subscribe_to_greeks()
# Restart listening
asyncio.create_task(self.listen_for_messages())
async def get_some_instrument_name(testnet: bool = True):
url = "wss://test.deribit.com/ws/api/v2" if testnet else "wss://www.deribit.com/ws/api/v2"
try:
async with websockets.connect(url) as ws:
request = {
"jsonrpc": "2.0",
"id": 7617,
"method": "public/get_instruments",
"params": {
"currency": "BTC",
"kind": "option",
"expired": False
}
}
await ws.send(json.dumps(request))
response = await ws.recv()
data = json.loads(response)
if data and data.get("result"):
# Find an active instrument, preferably with some trading activity
for instrument in data["result"]:
if instrument["is_active"] and instrument["instrument_name"].startswith("BTC-"):
return instrument["instrument_name"]
print("No active BTC option instrument found, using fallback.")
return "BTC-29DEC23-60000-C" # Fallback, might be expired or inactive
except Exception as e:
print(f"Error fetching instrument name: {e}. Using fallback.")
return "BTC-29DEC23-60000-C" # Fallback
async def main():
instrument_to_subscribe = await get_some_instrument_name(testnet=True)
if not instrument_to_subscribe:
print("Could not fetch a valid instrument name. Exiting.")
return
print(f"Using instrument: {instrument_to_subscribe}")
client = DeribitGreeksClient(instrument_to_subscribe, testnet=True)
if await client.connect():
await client.listen_for_messages()
if __name__ == "__main__":
asyncio.run(main())
Разбор параметров
instrument_name: Строка, представляющая полное имя опционного контракта на Deribit (например,'BTC-29DEC23-60000-C'). Этот параметр определяет, для какого конкретного опциона будут запрашиваться греки. В примере используется функцияget_some_instrument_nameдля динамического получения актуального имени инструмента с Deribit Testnet.testnet: Булево значение (Trueпо умолчанию), указывающее, следует ли подключаться к тестовой сети Deribit (wss://test.deribit.com/ws/api/v2) или к основной сети (wss://www.deribit.com/ws/api/v2). Для разработки и тестирования рекомендуется использовать тестовую сеть.reconnect_interval: Целое число, задающее интервал (в секундах) между попытками переподключения к WebSocket в случае разрыва соединения. Обеспечивает устойчивость к временным сетевым проблемам.channel: Строка, определяющая канал подписки на Deribit API. Для получения греков опционов используется форматoptions.greeks.{instrument_name}.100ms. Число100msуказывает на частоту обновлений (каждые 100 миллисекунд).
Как запустить
Для запуска представленного кода выполните следующие шаги:
- Установите необходимые библиотеки: Убедитесь, что у вас установлен Python 3.7+ и библиотека
websockets. Если нет, установите ее с помощью pip:pip install websockets - Сохраните код: Скопируйте весь представленный Python-код и сохраните его в файл с расширением
.py, например,deribit_greeks.py. - Запустите скрипт: Откройте терминал или командную строку, перейдите в директорию, где вы сохранили файл, и выполните команду:
python deribit_greeks.py
После запуска скрипт подключится к Deribit Testnet, динамически определит активный опционный инструмент и начнет выводить в консоль обновления греков для этого инструмента в реальном времени. Вы увидите сообщения о подключении, подписке и затем потоковые данные по Delta, Gamma, Vega, Theta, Rho и Implied Volatility.
Помимо получения греков, для комплексного анализа рынка можно также парсить исторические данные, например, информацию о ликвидациях, как это делается в статье Парсинг Исторических Ликвидаций с Coinglass API на Python. Это позволяет получить более полное представление о динамике рынка и поведении участников. Для обеспечения честной и эффективной работы торговых систем, важно также учитывать аспекты защиты от манипуляций, таких как wash trading, о чем подробно рассказано в статье Реализация защиты от Wash Trading в Matching Engine на Python.




