| README.md | ||
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:
- WebSocket By Contract Name
- 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
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
wss://YOUR_DOMAIN/live/data/websocket/contract/name?contract_names=ContractA&contract_names=ContractB
Python Example
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
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
wss://YOUR_DOMAIN/live/data/websocket/contract/id?contract_id=12345&contract_id=67890
Python Example
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:
1008 POLICY VIOLATION
Message Structure
Response Structure (Contract Name)
{
"channel": "IME Stream",
"contractName": "ContractA",
"timestamp": "2026-05-23T15:10:00.000000",
"data": {}
}
Response Structure (Contract ID)
{
"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
{
"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
WebSocket closed with code 1008
Invalid Contract
If an invalid contract name or contract ID is provided, the connection will be closed.
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
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())