HT_DataEngine_IME_websocket/README.md
2026-05-23 16:42:16 +03:30

6.6 KiB

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

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())