Update README.md
This commit is contained in:
parent
fde0beb3eb
commit
b24616c150
245
README.md
245
README.md
@ -1,41 +1,92 @@
|
|||||||
# IME Live Data WebSocket Documentation
|
# HedgeTech IME Live Data WebSocket API
|
||||||
|
|
||||||
## Introduction
|
Professional real-time WebSocket streaming service for Iran Mercantile Exchange (IME) market data.
|
||||||
|
|
||||||
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
|
# Overview
|
||||||
|
|
||||||
# 1. WebSocket By Contract Name
|
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
|
||||||
|
|
||||||
```text
|
```text
|
||||||
wss://YOUR_DOMAIN/live/data/websocket/contract/name
|
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
|
||||||
|
|
||||||
|
```text
|
||||||
|
Authorization: Bearer YOUR_ACCESS_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Authentication Flow
|
||||||
|
|
||||||
|
```python
|
||||||
|
extra_headers = {
|
||||||
|
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# WebSocket: Subscribe By Contract Name
|
||||||
|
|
||||||
|
## Endpoint
|
||||||
|
|
||||||
|
```text
|
||||||
|
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/name
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Query Parameters
|
## Query Parameters
|
||||||
|
|
||||||
| Parameter | Type | Required | Description |
|
| Parameter | Type | Required | Description |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| contract_names | list[string] | Yes | List of contract names |
|
| contract_name | list[string] | Yes | List of contract names |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Example Connection
|
## Example Connection
|
||||||
|
|
||||||
```text
|
```text
|
||||||
wss://YOUR_DOMAIN/live/data/websocket/contract/name?contract_names=ContractA&contract_names=ContractB
|
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/name?contract_name=ContractA&contract_name=ContractB
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -44,18 +95,27 @@ wss://YOUR_DOMAIN/live/data/websocket/contract/name?contract_names=ContractA&con
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
import websockets
|
|
||||||
import json
|
import json
|
||||||
|
import websockets
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
|
||||||
uri = (
|
uri = (
|
||||||
"ws://127.0.0.1:8000/live/data/websocket/contract/name"
|
"wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/name"
|
||||||
"?contract_names=ContractA"
|
"?contract_name=ContractA"
|
||||||
"&contract_names=ContractB"
|
"&contract_name=ContractB"
|
||||||
)
|
)
|
||||||
|
|
||||||
async with websockets.connect(uri) as websocket:
|
headers = {
|
||||||
|
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
|
||||||
|
}
|
||||||
|
|
||||||
|
async with websockets.connect(
|
||||||
|
uri,
|
||||||
|
additional_headers=headers,
|
||||||
|
ping_interval=20,
|
||||||
|
ping_timeout=20,
|
||||||
|
) as websocket:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
@ -70,12 +130,16 @@ asyncio.run(main())
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 2. WebSocket By Contract ID
|
# WebSocket: Subscribe By Contract ID
|
||||||
|
|
||||||
|
## Endpoint
|
||||||
|
|
||||||
```text
|
```text
|
||||||
wss://YOUR_DOMAIN/live/data/websocket/contract/id
|
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Query Parameters
|
## Query Parameters
|
||||||
|
|
||||||
| Parameter | Type | Required | Description |
|
| Parameter | Type | Required | Description |
|
||||||
@ -87,7 +151,7 @@ wss://YOUR_DOMAIN/live/data/websocket/contract/id
|
|||||||
## Example Connection
|
## Example Connection
|
||||||
|
|
||||||
```text
|
```text
|
||||||
wss://YOUR_DOMAIN/live/data/websocket/contract/id?contract_id=12345&contract_id=67890
|
wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id?contract_id=12345&contract_id=67890
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -96,18 +160,27 @@ wss://YOUR_DOMAIN/live/data/websocket/contract/id?contract_id=12345&contract_id=
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
import websockets
|
|
||||||
import json
|
import json
|
||||||
|
import websockets
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
|
||||||
uri = (
|
uri = (
|
||||||
"ws://127.0.0.1:8000/live/data/websocket/contract/id"
|
"wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id"
|
||||||
"?contract_id=12345"
|
"?contract_id=12345"
|
||||||
"&contract_id=67890"
|
"&contract_id=67890"
|
||||||
)
|
)
|
||||||
|
|
||||||
async with websockets.connect(uri) as websocket:
|
headers = {
|
||||||
|
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
|
||||||
|
}
|
||||||
|
|
||||||
|
async with websockets.connect(
|
||||||
|
uri,
|
||||||
|
additional_headers=headers,
|
||||||
|
ping_interval=20,
|
||||||
|
ping_timeout=20,
|
||||||
|
) as websocket:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
@ -122,21 +195,18 @@ asyncio.run(main())
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Authentication
|
# WebSocket Response Structure
|
||||||
|
|
||||||
All WebSocket endpoints require authentication.
|
Both endpoints stream identical payload structures.
|
||||||
|
|
||||||
If authentication fails, the connection will be closed with:
|
The only difference is:
|
||||||
|
|
||||||
```text
|
- `contractName` exists in Name endpoint
|
||||||
1008 POLICY VIOLATION
|
- `ContractId` exists in ID endpoint
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Message Structure
|
## Response Example (Contract Name)
|
||||||
|
|
||||||
## Response Structure (Contract Name)
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -149,7 +219,7 @@ If authentication fails, the connection will be closed with:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Response Structure (Contract ID)
|
## Response Example (Contract ID)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -164,11 +234,11 @@ If authentication fails, the connection will be closed with:
|
|||||||
|
|
||||||
# Data Payload Structure
|
# Data Payload Structure
|
||||||
|
|
||||||
The `data` field contains the complete live contract market data.
|
The `data` field contains the complete real-time contract market state.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Full Payload Example
|
# Full Payload Example
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -192,6 +262,7 @@ The `data` field contains the complete live contract market data.
|
|||||||
"sell_price": 0
|
"sell_price": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"Aggregate": {
|
"Aggregate": {
|
||||||
"date": "",
|
"date": "",
|
||||||
"time": "",
|
"time": "",
|
||||||
@ -205,10 +276,12 @@ The `data` field contains the complete live contract market data.
|
|||||||
"open_price": 0,
|
"open_price": 0,
|
||||||
"previous_close": 0
|
"previous_close": 0
|
||||||
},
|
},
|
||||||
|
|
||||||
"AllowedPriceRange": {
|
"AllowedPriceRange": {
|
||||||
"minAllowedPrice": 1,
|
"minAllowedPrice": 1,
|
||||||
"maxAllowedPrice": 9999999999
|
"maxAllowedPrice": 9999999999
|
||||||
},
|
},
|
||||||
|
|
||||||
"ContractInfo": {
|
"ContractInfo": {
|
||||||
"open_interest": 0,
|
"open_interest": 0,
|
||||||
"open_interest_changes": 0
|
"open_interest_changes": 0
|
||||||
@ -218,13 +291,15 @@ The `data` field contains the complete live contract market data.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Payload Fields Description
|
# Payload Field Documentation
|
||||||
|
|
||||||
# BestLimit
|
# BestLimit
|
||||||
|
|
||||||
Represents the top buy and sell order book levels.
|
Represents top order book levels.
|
||||||
|
|
||||||
## Levels
|
---
|
||||||
|
|
||||||
|
## Order Book Levels
|
||||||
|
|
||||||
| Level | Description |
|
| Level | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
@ -232,7 +307,9 @@ Represents the top buy and sell order book levels.
|
|||||||
| 2 | Second order book level |
|
| 2 | Second order book level |
|
||||||
| 3 | Third order book level |
|
| 3 | Third order book level |
|
||||||
|
|
||||||
## Fields
|
---
|
||||||
|
|
||||||
|
## BestLimit Fields
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
@ -245,13 +322,13 @@ Represents the top buy and sell order book levels.
|
|||||||
|
|
||||||
# Aggregate
|
# Aggregate
|
||||||
|
|
||||||
Aggregated market statistics for the contract.
|
Aggregated trading statistics.
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
| date | Trading date |
|
| date | Trading date |
|
||||||
| time | Last update time |
|
| time | Last update time |
|
||||||
| trade_count | Number of trades |
|
| trade_count | Total number of trades |
|
||||||
| total_volume | Total traded volume |
|
| total_volume | Total traded volume |
|
||||||
| total_value | Total traded value |
|
| total_value | Total traded value |
|
||||||
| closing_price | Closing price |
|
| closing_price | Closing price |
|
||||||
@ -265,7 +342,7 @@ Aggregated market statistics for the contract.
|
|||||||
|
|
||||||
# AllowedPriceRange
|
# AllowedPriceRange
|
||||||
|
|
||||||
Allowed trading price range.
|
Allowed trading range.
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
@ -276,7 +353,7 @@ Allowed trading price range.
|
|||||||
|
|
||||||
# ContractInfo
|
# ContractInfo
|
||||||
|
|
||||||
Additional contract information.
|
Contract-level metadata.
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
@ -287,48 +364,55 @@ Additional contract information.
|
|||||||
|
|
||||||
# Error Handling
|
# Error Handling
|
||||||
|
|
||||||
## Invalid Authentication
|
---
|
||||||
|
|
||||||
|
## Authentication Failure
|
||||||
|
|
||||||
|
If the access token is invalid or missing:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
WebSocket closed with code 1008
|
WebSocket closed with code 1008 POLICY VIOLATION
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Invalid Contract
|
## Invalid Contract
|
||||||
|
|
||||||
If an invalid contract name or contract ID is provided, the connection will be closed.
|
If invalid contract names or IDs are provided:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
WebSocket closed with code 1008
|
WebSocket closed with code 1008 POLICY VIOLATION
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Notes
|
# Architecture Notes
|
||||||
|
|
||||||
- The WebSocket streams real-time market data updates.
|
- All streams are asynchronous
|
||||||
- Each contract is subscribed through a dedicated Redis Pub/Sub stream.
|
- Redis Pub/Sub is used internally
|
||||||
- Updates are only sent when market data changes.
|
- Data is pushed only on updates
|
||||||
- The WebSocket connection remains active until disconnected by the client.
|
- Multiple contracts can be subscribed simultaneously
|
||||||
- Multiple contracts can be subscribed simultaneously.
|
- Connections remain active until disconnected
|
||||||
- Timestamps are provided in ISO 8601 format.
|
- ISO 8601 timestamps are used
|
||||||
|
- Built for high-throughput market infrastructure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Recommended Client Strategy
|
# Production Recommendations
|
||||||
|
|
||||||
For production usage, it is recommended to:
|
For production-grade integrations:
|
||||||
|
|
||||||
- Implement automatic reconnect logic
|
- Implement automatic reconnect logic
|
||||||
- Enable heartbeat / ping interval
|
- Enable WebSocket heartbeat
|
||||||
- Process messages asynchronously
|
- Use asynchronous processing pipelines
|
||||||
- Use internal message queues
|
- Queue incoming messages internally
|
||||||
- Configure WebSocket timeout handling
|
- Configure proper timeout handling
|
||||||
|
- Monitor connection lifecycle
|
||||||
|
- Handle transient disconnects gracefully
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Recommended Python Reconnect Example
|
# Production Reconnect Example
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import asyncio
|
import asyncio
|
||||||
@ -336,10 +420,14 @@ import json
|
|||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
URI = (
|
URI = (
|
||||||
"ws://127.0.0.1:8000/live/data/websocket/contract/id"
|
"wss://core.hedgetech.ir/data-engine/ime/live/data/websocket/contract/id"
|
||||||
"?contract_id=12345"
|
"?contract_id=12345"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
HEADERS = {
|
||||||
|
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
|
||||||
|
}
|
||||||
|
|
||||||
async def connect():
|
async def connect():
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@ -348,8 +436,9 @@ async def connect():
|
|||||||
|
|
||||||
async with websockets.connect(
|
async with websockets.connect(
|
||||||
URI,
|
URI,
|
||||||
|
additional_headers=HEADERS,
|
||||||
ping_interval=20,
|
ping_interval=20,
|
||||||
ping_timeout=20
|
ping_timeout=20,
|
||||||
) as websocket:
|
) as websocket:
|
||||||
|
|
||||||
print("Connected")
|
print("Connected")
|
||||||
@ -370,3 +459,19 @@ async def connect():
|
|||||||
|
|
||||||
asyncio.run(connect())
|
asyncio.run(connect())
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Technology Stack
|
||||||
|
|
||||||
|
- FastAPI
|
||||||
|
- Redis Pub/Sub
|
||||||
|
- AsyncIO
|
||||||
|
- WebSocket Protocol
|
||||||
|
- Real-Time Streaming Infrastructure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# HedgeTech
|
||||||
|
|
||||||
|
Developed and maintained by HedgeTech Infrastructure Team.
|
||||||
Loading…
Reference in New Issue
Block a user