# IME Live Data WebSocket Documentation ## Introduction This WebSocket service provides real-time market data for Iran Mercantile Exchange (IME) contracts. The service streams live contract updates from Redis Pub/Sub channels and delivers them to connected WebSocket clients. Two WebSocket endpoints are available: 1. WebSocket By Contract Name 2. WebSocket By Contract ID Both endpoints provide the exact same payload structure. The only difference is how contracts are subscribed. --- # WebSocket Endpoints # 1. WebSocket By Contract Name ```text wss://YOUR_DOMAIN/live/data/websocket/contract/name ``` ## Query Parameters | Parameter | Type | Required | Description | |---|---|---|---| | contract_names | list[string] | Yes | List of contract names | --- ## Example Connection ```text wss://YOUR_DOMAIN/live/data/websocket/contract/name?contract_names=ContractA&contract_names=ContractB ``` --- ## Python Example ```python import asyncio import websockets import json async def main(): uri = ( "ws://127.0.0.1:8000/live/data/websocket/contract/name" "?contract_names=ContractA" "&contract_names=ContractB" ) async with websockets.connect(uri) as websocket: while True: message = await websocket.recv() data = json.loads(message) print(json.dumps(data, indent=4)) asyncio.run(main()) ``` --- # 2. WebSocket By Contract ID ```text wss://YOUR_DOMAIN/live/data/websocket/contract/id ``` ## Query Parameters | Parameter | Type | Required | Description | |---|---|---|---| | contract_id | list[string] | Yes | List of contract IDs | --- ## Example Connection ```text wss://YOUR_DOMAIN/live/data/websocket/contract/id?contract_id=12345&contract_id=67890 ``` --- ## Python Example ```python import asyncio import websockets import json async def main(): uri = ( "ws://127.0.0.1:8000/live/data/websocket/contract/id" "?contract_id=12345" "&contract_id=67890" ) async with websockets.connect(uri) as websocket: while True: message = await websocket.recv() data = json.loads(message) print(json.dumps(data, indent=4)) asyncio.run(main()) ``` --- # Authentication All WebSocket endpoints require authentication. If authentication fails, the connection will be closed with: ```text 1008 POLICY VIOLATION ``` --- # Message Structure ## Response Structure (Contract Name) ```json { "channel": "IME Stream", "contractName": "ContractA", "timestamp": "2026-05-23T15:10:00.000000", "data": {} } ``` --- ## Response Structure (Contract ID) ```json { "channel": "IME Stream", "ContractId": "12345", "timestamp": "2026-05-23T15:10:00.000000", "data": {} } ``` --- # Data Payload Structure The `data` field contains the complete live contract market data. --- ## Full Payload Example ```json { "BestLimit": { "1": { "buy_quantity": 0, "buy_price": 0, "sell_quantity": 0, "sell_price": 0 }, "2": { "buy_quantity": 0, "buy_price": 0, "sell_quantity": 0, "sell_price": 0 }, "3": { "buy_quantity": 0, "buy_price": 0, "sell_quantity": 0, "sell_price": 0 } }, "Aggregate": { "date": "", "time": "", "trade_count": 0, "total_volume": 0, "total_value": 0, "closing_price": 0, "last_price": 0, "low_price": 0, "high_price": 0, "open_price": 0, "previous_close": 0 }, "AllowedPriceRange": { "minAllowedPrice": 1, "maxAllowedPrice": 9999999999 }, "ContractInfo": { "open_interest": 0, "open_interest_changes": 0 } } ``` --- # Payload Fields Description # BestLimit Represents the top buy and sell order book levels. ## Levels | Level | Description | |---|---| | 1 | Best market level | | 2 | Second order book level | | 3 | Third order book level | ## Fields | Field | Description | |---|---| | buy_quantity | Buy order quantity | | buy_price | Buy order price | | sell_quantity | Sell order quantity | | sell_price | Sell order price | --- # Aggregate Aggregated market statistics for the contract. | Field | Description | |---|---| | date | Trading date | | time | Last update time | | trade_count | Number of trades | | total_volume | Total traded volume | | total_value | Total traded value | | closing_price | Closing price | | last_price | Last traded price | | low_price | Lowest traded price | | high_price | Highest traded price | | open_price | Opening price | | previous_close | Previous closing price | --- # AllowedPriceRange Allowed trading price range. | Field | Description | |---|---| | minAllowedPrice | Minimum allowed price | | maxAllowedPrice | Maximum allowed price | --- # ContractInfo Additional contract information. | Field | Description | |---|---| | open_interest | Open interest | | open_interest_changes | Open interest changes | --- # Error Handling ## Invalid Authentication ```text WebSocket closed with code 1008 ``` --- ## Invalid Contract If an invalid contract name or contract ID is provided, the connection will be closed. ```text WebSocket closed with code 1008 ``` --- # Notes - The WebSocket streams real-time market data updates. - Each contract is subscribed through a dedicated Redis Pub/Sub stream. - Updates are only sent when market data changes. - The WebSocket connection remains active until disconnected by the client. - Multiple contracts can be subscribed simultaneously. - Timestamps are provided in ISO 8601 format. --- # Recommended Client Strategy For production usage, it is recommended to: - Implement automatic reconnect logic - Enable heartbeat / ping interval - Process messages asynchronously - Use internal message queues - Configure WebSocket timeout handling --- # Recommended Python Reconnect Example ```python import asyncio import json import websockets URI = ( "ws://127.0.0.1:8000/live/data/websocket/contract/id" "?contract_id=12345" ) async def connect(): while True: try: async with websockets.connect( URI, ping_interval=20, ping_timeout=20 ) as websocket: print("Connected") while True: message = await websocket.recv() data = json.loads(message) print(data) except Exception as e: print("Disconnected:", e) await asyncio.sleep(5) asyncio.run(connect()) ```