Skip to content

WebSockets

Real-time market data and order updates via WebSocket streams.

The SDK connects to WebSocket streams at wss://ws2.ethereal.trade.

All code samples use AsyncWSClient. A synchronous WSClient is also available with the same API.

For available stream types, parameters, and message formats, see the official documentation.

WebSocket client

import asyncio
from ethereal import AsyncWSClient

async def main():
    ws = AsyncWSClient({
        "base_url": "wss://ws2.ethereal.trade",
    })
    await ws.open()

    async def on_ticker(data):
        print(f"Ticker: {data}")

    ws.callbacks["Ticker"] = [on_ticker]
    await ws.subscribe(stream_type="Ticker", symbol="BTCUSD")

    # Keep the connection open until disconnected
    await ws.wait()

asyncio.run(main())

Subscribe to multiple streams

async def setup_streams(ws):
    ws.callbacks["Ticker"] = [lambda d: print(f"Ticker: {d}")]
    ws.callbacks["L2Book"] = [lambda d: print(f"Book: {d}")]

    await ws.subscribe(stream_type="Ticker", symbol="BTCUSD")
    await ws.subscribe(stream_type="L2Book", symbol="BTCUSD")

Account-specific streams

Account Required

Requires at least one subaccount. See Creating Accounts if needed.

from ethereal import AsyncWSClient, AsyncRESTClient

async def main():
    rest = await AsyncRESTClient.create({
        "base_url": "https://api.ethereal.trade",
        "chain_config": {
            "rpc_url": "https://rpc.ethereal.trade",
            "private_key": "your_private_key",
        }
    })
    subaccounts = await rest.subaccounts()
    subaccount_id = str(subaccounts[0].id)
    await rest.close()

    ws = AsyncWSClient({
        "base_url": "wss://ws2.ethereal.trade",
    })
    await ws.open()

    ws.callbacks["OrderUpdate"] = [lambda d: print(f"Order: {d}")]
    await ws.subscribe(stream_type="OrderUpdate", subaccountId=subaccount_id)

    await ws.wait()

Connection management

await ws.close()     # Close the connection
await ws.open()      # Reconnect

Deprecated config option

Existing configs that set transport="websocket" are still accepted for compatibility, but the SDK only supports the WebSocket API and new code should omit the option.