| README.md | ||
HedgeTech IME Live Data WebSocket API
Professional real-time WebSocket streaming service for Iran Mercantile Exchange (IME) market data.
Overview
The HedgeTech IME Live Data WebSocket service provides ultra low-latency real-time streaming market data for IME contracts.
The service is designed for:
- Trading Platforms
- HFT Systems
- Algorithmic Trading
- Quantitative Infrastructure
- Market Monitoring Systems
- Real-Time Dashboards
- Risk Engines
All streams are powered by Redis Pub/Sub infrastructure and asynchronously distributed through FastAPI WebSocket endpoints.
Base URL
https://core.hedgetech.ir/data-engine/ime
Available WebSocket Endpoints
| Endpoint | Description |
|---|---|
/live/data/websocket/contract/name |
Subscribe using contract names |
/live/data/websocket/contract/id |
Subscribe using contract IDs |
Authentication
All WebSocket endpoints require authentication.
Authentication is performed during the WebSocket handshake phase using Authorization headers.
Authorization Header
Authorization: Bearer YOUR_ACCESS_TOKEN
Example Authentication Flow
extra_headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
WebSocket: Subscribe By Contract Name
Endpoint
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/name
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| contract_name | list[string] | Yes | List of contract names |
Example Connection
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/name?contract_name=ContractA&contract_name=ContractB
Python Example
import asyncio
import json
import websockets
async def main():
uri = (
"wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/name"
"?contract_name=ContractA"
"&contract_name=ContractB"
)
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
async with websockets.connect(
uri,
additional_headers=headers,
ping_interval=20,
ping_timeout=20,
) as websocket:
while True:
message = await websocket.recv()
data = json.loads(message)
print(json.dumps(data, indent=4))
asyncio.run(main())
WebSocket: Subscribe By Contract ID
Endpoint
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| contract_id | list[string] | Yes | List of contract IDs |
Example Connection
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id?contract_id=12345&contract_id=67890
Python Example
import asyncio
import json
import websockets
async def main():
uri = (
"wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id"
"?contract_id=12345"
"&contract_id=67890"
)
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
async with websockets.connect(
uri,
additional_headers=headers,
ping_interval=20,
ping_timeout=20,
) as websocket:
while True:
message = await websocket.recv()
data = json.loads(message)
print(json.dumps(data, indent=4))
asyncio.run(main())
WebSocket Response Structure
Both endpoints stream identical payload structures.
The only difference is:
contractNameexists in Name endpointContractIdexists in ID endpoint
Response Example (Contract Name)
{
"channel": "IME Stream",
"contractName": "ContractA",
"timestamp": "2026-05-23T15:10:00.000000",
"data": {}
}
Response Example (Contract ID)
{
"channel": "IME Stream",
"ContractId": "12345",
"timestamp": "2026-05-23T15:10:00.000000",
"data": {}
}
Data Payload Structure
The data field contains the complete real-time contract market state.
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 Field Documentation
BestLimit
Represents top order book levels.
Order Book Levels
| Level | Description |
|---|---|
| 1 | Best market level |
| 2 | Second order book level |
| 3 | Third order book level |
BestLimit 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 trading statistics.
| Field | Description |
|---|---|
| date | Trading date |
| time | Last update time |
| trade_count | Total 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 range.
| Field | Description |
|---|---|
| minAllowedPrice | Minimum allowed price |
| maxAllowedPrice | Maximum allowed price |
ContractInfo
Contract-level metadata.
| Field | Description |
|---|---|
| open_interest | Open interest |
| open_interest_changes | Open interest changes |
Error Handling
Authentication Failure
If the access token is invalid or missing:
WebSocket closed with code 1008 POLICY VIOLATION
Invalid Contract
If invalid contract names or IDs are provided:
WebSocket closed with code 1008 POLICY VIOLATION
Architecture Notes
- All streams are asynchronous
- Redis Pub/Sub is used internally
- Data is pushed only on updates
- Multiple contracts can be subscribed simultaneously
- Connections remain active until disconnected
- ISO 8601 timestamps are used
- Built for high-throughput market infrastructure
Production Recommendations
For production-grade integrations:
- Implement automatic reconnect logic
- Enable WebSocket heartbeat
- Use asynchronous processing pipelines
- Queue incoming messages internally
- Configure proper timeout handling
- Monitor connection lifecycle
- Handle transient disconnects gracefully
Production Reconnect Example
import asyncio
import json
import websockets
URI = (
"wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id"
"?contract_id=12345"
)
HEADERS = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
async def connect():
while True:
try:
async with websockets.connect(
URI,
additional_headers=HEADERS,
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())
Technology Stack
- FastAPI
- Redis Pub/Sub
- AsyncIO
- WebSocket Protocol
- Real-Time Streaming Infrastructure
HedgeTech
Developed and maintained by HedgeTech Infrastructure Team.