Update README.md
This commit is contained in:
parent
6044610719
commit
f49c3c061a
92
README.md
92
README.md
@ -1,7 +1,5 @@
|
||||
# HT Data Engine | TSE & IFB | WebSocket
|
||||
|
||||
## Real-Time Market Streams (TSE & IFB)
|
||||
|
||||
### WebSocket • High-Frequency • Low-Latency
|
||||
|
||||
---
|
||||
@ -9,7 +7,6 @@
|
||||
## 1. Overview
|
||||
|
||||
This documentation describes the **HT Data Engine WebSocket API** for subscribing to real-time market data for **TSE & IFB** symbols.
|
||||
|
||||
The API provides multiple channels delivering structured financial data such as order books, aggregate trades, OHLCV, and fund/contract information.
|
||||
|
||||
All WebSocket endpoints require **JWT token-based authentication** and support multiple symbols or ISINs in a single connection.
|
||||
@ -28,13 +25,13 @@ Send a `POST` request to:
|
||||
https://core.hedgetech.ir/auth/user/token/issue
|
||||
```
|
||||
|
||||
**Headers:**
|
||||
Headers:
|
||||
|
||||
```
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
```
|
||||
|
||||
**Body:**
|
||||
Body:
|
||||
|
||||
```
|
||||
username=your_username&password=your_password
|
||||
@ -72,7 +69,6 @@ Authorization: <your_token>
|
||||
| `wss://core.hedgetech.ir/data-engine/tse-ifb/live/data/websocket/symbol/name` | Subscribe using **symbol names** |
|
||||
|
||||
**Note:** The output payload structure is identical for both endpoints, except the symbol identifier field:
|
||||
|
||||
- `symbolIsin` for `/symbol/isin`
|
||||
- `symbolName` for `/symbol/name`
|
||||
|
||||
@ -93,15 +89,14 @@ The data engine provides **two separate WebSocket endpoints**:
|
||||
```
|
||||
|
||||
Both endpoints deliver **identical payload structures**, including the same channels and the same `data` schema.
|
||||
|
||||
The **only difference** is the identifier field inside each message:
|
||||
|
||||
| Endpoint | Identifier Field in Payload |
|
||||
|----------|----------------------------|
|
||||
|----------|------------------------------|
|
||||
| `/symbol/isin` | `"symbolIsin": "<ISIN>"` |
|
||||
| `/symbol/name` | `"symbolName": "<Symbol>"` |
|
||||
|
||||
**Example for ISIN endpoint:**
|
||||
Example for ISIN endpoint:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -112,7 +107,7 @@ The **only difference** is the identifier field inside each message:
|
||||
}
|
||||
```
|
||||
|
||||
**Example for Symbol-Name endpoint:**
|
||||
Example for Symbol-Name endpoint:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -136,16 +131,17 @@ No other structural difference exists between these two WebSocket services.
|
||||
## 4. Connection Flow (Updated)
|
||||
|
||||
1. Establish WebSocket connection with the proper `Authorization` header.
|
||||
|
||||
2. Include query parameters in the URL. **Each symbol/ISIN and channel is repeated as a separate query parameter**:
|
||||
|
||||
For ISIN endpoint:
|
||||
```
|
||||
wss://core.hedgetech.ir/data-engine/tse-ifb/live/data/websocket/symbol/isin?
|
||||
channels=<channel1>&channels=<channel2>&
|
||||
symbol_isins=<ISIN1>&symbol_isins=<ISIN2>
|
||||
```
|
||||
|
||||
For symbol names endpoint:
|
||||
or for symbol names:
|
||||
|
||||
```
|
||||
wss://core.hedgetech.ir/data-engine/tse-ifb/live/data/websocket/symbol/name?
|
||||
channels=<channel1>&channels=<channel2>&
|
||||
@ -153,6 +149,7 @@ No other structural difference exists between these two WebSocket services.
|
||||
```
|
||||
|
||||
3. If verification passes, the WebSocket connection is accepted.
|
||||
|
||||
4. Real-time messages are streamed continuously until the connection is closed.
|
||||
|
||||
**Important:** Unauthorized connections are closed immediately with **code 1008**.
|
||||
@ -230,6 +227,8 @@ All messages are delivered in the following **JSON structure**:
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Example: `order-book`
|
||||
|
||||
```json
|
||||
@ -256,6 +255,8 @@ All messages are delivered in the following **JSON structure**:
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Example: `ohlcv-last-1m`
|
||||
|
||||
```json
|
||||
@ -273,6 +274,8 @@ All messages are delivered in the following **JSON structure**:
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.4 Example: `aggregate`
|
||||
|
||||
```json
|
||||
@ -296,6 +299,8 @@ All messages are delivered in the following **JSON structure**:
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.5 Example: `institutional-vs-individual`
|
||||
|
||||
```json
|
||||
@ -316,6 +321,8 @@ All messages are delivered in the following **JSON structure**:
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.6 Example: `contract-info`
|
||||
|
||||
```json
|
||||
@ -331,6 +338,8 @@ All messages are delivered in the following **JSON structure**:
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6.7 Example: `fund-info`
|
||||
|
||||
```json
|
||||
@ -349,7 +358,24 @@ All messages are delivered in the following **JSON structure**:
|
||||
|
||||
---
|
||||
|
||||
## 7. Error Handling
|
||||
### 7. Other Channels
|
||||
|
||||
Payload models follow the **Pydantic models** provided (`Aggregate`, `OrderBook`, `InstitutionalVsIndividual`, `ContractInfo`, `FundInfo`) and always adhere to the format:
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "<channel-name>",
|
||||
"symbolIsin": "<symbolIsin>",
|
||||
"timestamp": "<ISO8601 timestamp>",
|
||||
"data": { ...channel-specific data... }
|
||||
}
|
||||
```
|
||||
|
||||
> NOTE: Replace `symbolIsin` with `symbolName` when using the `/symbol/name` endpoint.
|
||||
|
||||
---
|
||||
|
||||
## 8. Error Handling
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
@ -358,9 +384,11 @@ All messages are delivered in the following **JSON structure**:
|
||||
|
||||
---
|
||||
|
||||
## 8. Code Examples
|
||||
## 9. Examples
|
||||
|
||||
### 8.1 Python (WebSocket Client)
|
||||
### 9.1 Python (WebSocket Client)
|
||||
|
||||
This example adds a small helper to **support both endpoints** by checking which identifier field exists in incoming messages.
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
@ -385,7 +413,7 @@ token = "<your_token>"
|
||||
asyncio.run(subscribe(url, token))
|
||||
```
|
||||
|
||||
### 8.2 JavaScript (WebSocket Client)
|
||||
### 9.2 JavaScript (WebSocket Client)
|
||||
|
||||
```javascript
|
||||
const WebSocket = require('ws');
|
||||
@ -409,7 +437,7 @@ ws.on('message', (data) => {
|
||||
ws.on('close', () => console.log('Disconnected'));
|
||||
```
|
||||
|
||||
### 8.3 Go (WebSocket Client)
|
||||
### 9.3 Go (WebSocket Client)
|
||||
|
||||
```go
|
||||
package main
|
||||
@ -452,7 +480,25 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### 8.4 Rust (WebSocket Client)
|
||||
### 9.4 Julia (WebSocket Client)
|
||||
|
||||
```julia
|
||||
using WebSockets, JSON
|
||||
|
||||
url = "wss://core.hedgetech.ir/data-engine/tse-ifb/live/data/websocket/symbol/isin?channels=order-book&channels=best-limit&symbol_isins=IRT3SATF0001"
|
||||
token = "<your_token>"
|
||||
|
||||
WebSockets.open(url, extra_headers=["Authorization" => token]) do ws
|
||||
while !eof(ws)
|
||||
msg = String(readavailable(ws))
|
||||
data = JSON.parse(msg)
|
||||
symbol = get(data, "symbolIsin", get(data, "symbolName", ""))
|
||||
println(data["timestamp"], " ", symbol, " ", data["channel"])
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### 9.5 Rust (WebSocket Client)
|
||||
|
||||
```rust
|
||||
use tokio_tungstenite::connect_async;
|
||||
@ -479,7 +525,9 @@ async fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
### 8.5 Subscription Notes
|
||||
---
|
||||
|
||||
### 9.6 Subscription Notes
|
||||
|
||||
- Multiple symbols and channels can be subscribed in a **single WebSocket connection**.
|
||||
- The server streams messages continuously; handle them asynchronously.
|
||||
@ -487,7 +535,7 @@ async fn main() {
|
||||
|
||||
---
|
||||
|
||||
## 9. Best Practices
|
||||
## 10. Best Practices
|
||||
|
||||
- Reconnect with **exponential backoff** in case of disconnects.
|
||||
- Validate your JWT **before subscribing**.
|
||||
@ -498,7 +546,7 @@ async fn main() {
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Quick Developer Checklist (for avoiding common mistakes)
|
||||
## Appendix: Quick developer checklist (for avoiding common mistakes)
|
||||
|
||||
- ✅ Use correct endpoint for your identifier type (`symbol/isin` vs `symbol/name`).
|
||||
- ✅ Provide `Authorization` header with a valid token on the WebSocket handshake.
|
||||
@ -506,3 +554,5 @@ async fn main() {
|
||||
- ✅ Handle both `symbolIsin` and `symbolName` in your message parsing to make the client resilient.
|
||||
- ✅ Treat messages' `data` payload consistently across endpoints (same schema).
|
||||
- ✅ Monitor for WS close code `1008` to detect authorization or policy errors.
|
||||
|
||||
---
|
||||
|
||||
Loading…
Reference in New Issue
Block a user