MarketDataClient Documentation
The MarketDataClient
is a WebSocket client designed to connect to a market data streaming service, allowing you to subscribe to real-time market data for various instruments. This documentation provides an overview of how to use the MarketDataClient
class, including setup, callbacks, methods, and FlatBuffer message schemas.
- Introduction
- Message Types and Flows
- Initialization
- Connecting to the WebSocket
- Setting Up Callbacks
- Subscription Types
- Market Data Payload Examples
- Example Usage
- Limitations
- FlatBuffer Message Schema
- Conclusion
Introduction
The MarketDataClient
allows users to connect to a market data WebSocket, subscribe to various instruments, and receive real-time tick data. It supports multiple subscription types and leverages FlatBuffers for efficient message processing.
Message Types and Flows
- Login Flow
- Client sends
LoginRequest
upon WebSocket connection. -
Server responds with
LoginResponse
. -
Subscription Flow
- Client sends
SubscribeRequest
. - Server responds with
SubscriptionResponse
. -
Server sends
MarketDataMessage
continuously. -
Unsubscription Flow
- Client sends
UnsubscribeRequest
. - Server responds with
UnsubscriptionResponse
.
Initialization
To start using the MarketDataClient
, initialize the client:
from brokerage_client.data import MarketDataClient
# Initialize the MarketDataClient instance
client = MarketDataClient()
Connecting to the WebSocket
Provide your UCC
(User Client Code) and AUTH_TOKEN
to connect:
AUTH_TOKEN = "your_auth_token_here"
UCC = "your_ucc_here"
client.connect(UCC, AUTH_TOKEN)
If you want the WebSocket connection to run in a separate thread, pass threaded=True
:
AUTH_TOKEN = "your_auth_token_here"
UCC = "your_ucc_here"
client.connect(UCC, AUTH_TOKEN, threaded=True)
When using threaded=True
, the WebSocket connection runs in the background. You must ensure that the main thread remains active; otherwise, the program may exit before processing data.
Example:
client.connect(UCC, AUTH_TOKEN, threaded=True)
try:
while True: # Keeps the main thread alive
pass
except KeyboardInterrupt:
print("KeyboardInterrupt received, closing connection...")
client.close()
Setting Up Callbacks
The MarketDataClient
provides several callbacks that you can assign to handle different events:
on_connect
: Triggered when the WebSocket connection is successfully established.on_ticks
: Triggered when market data (ticks) are received.on_close
: Triggered when the WebSocket connection is closed.
Example:
def on_connect(ws):
print("Connection established.")
subscription_list = [
{"symbol": "RELIANCE.NSE.EQ", "sub_type": "ltp"},
{"symbol": "NIFTY25FEBFUT", "sub_type": "mtick", "expiry": 20250227},
{"symbol": "NIFTY25FEBFUT", "sub_type": "utick", "expiry": 20250227},
]
client.subscribe("sub1", subscription_list)
def on_ticks(ws, ticks):
for i, tick in enumerate(ticks):
print(f"\nTick {i + 1}:")
for key, value in tick.items():
print(f" {key}: {value}")
def on_close(ws):
print(f"WebSocket Connection closed")
# Initialize the MarketDataClient instance
client = MarketDataClient()
# Assign callback functions
client.init(on_connect=on_connect,on_ticks=on_ticks,on_close=on_close)
Subscription Types
sub_type |
Description |
---|---|
ltp |
Last Traded Price data |
mtick |
Market depth data |
utick |
Options chain data (Futures symbol required) |
Market Data Payload Examples
The tick structure represents real-time market data updates and is passed to the on_ticks callback. Each tick contains key market attributes such as price, volume, and market depth levels.
Before receiving market data for the requested symbols, you will first receive the DPR (Daily Price Range) values for those symbols in ticks .
Response Example - DPR Values
[
{
"response_type": "Subscription DPR Values",
"request_id": "sub1",
"symbol": "RELIANCE.NSE.EQ",
"type": "DprPayload",
"dpr_low": 117480.25,
"dpr_high": 143580.78
},
{
"response_type": "Subscription DPR Values",
"request_id": "sub1",
"symbol": "NIFTY25FEBFUT",
"type": "DprPayload",
"dpr_low": 2118090.21,
"dpr_high": 2588775.34
},
{
"response_type": "Subscription DPR Values",
"request_id": "sub1",
"symbol": "NIFTY25FEBFUT",
"type": "DprPayload",
"dpr_low": 2118090.45,
"dpr_high": 2588775.56
}
]
UtickPayload
Example
{
"response_type": "Market Data",
"symbol": "NIFTY25FEBFUT",
"seq_no": 1,
"sub_type": "utick",
"sending_time": 1740462338221772895,
"type": "UtickPayload",
"iv": 0.12,
"spot_price": 2352210.00,
"options": [
{ "strike_price": 2330000.00, "option_type": 67, "ltp": 61440.00, "oi": 220425.00, "volume": 133800 },
{ "strike_price": 2335000.00, "option_type": 67, "ltp": 58515.00, "oi": 21075.00, "volume": 22875 },
{ "strike_price": 2340000.00, "option_type": 67, "ltp": 55785.00, "oi": 177225.00, "volume": 133275 },
{ "strike_price": 2345000.00, "option_type": 67, "ltp": 52810.00, "oi": 56625.00, "volume": 13950 },
{ "strike_price": 2350000.00, "option_type": 67, "ltp": 50205.00, "oi": 890175.00, "volume": 703575 }
.......................................
]
}
MtickPayload
Example
{
"response_type": "Market Data",
"symbol": "NIFTY25FEBFUT",
"seq_no": 1,
"sub_type": "mtick",
"sending_time": 1740462338221772895,
"type": "MtickPayload",
"ltp": 2352210.00,
"volume": 75,
"levels": [
{ "bid": 2352260.00, "bid_qty": 300, "ask": 2352995.00, "ask_qty": 600 },
{ "bid": 2352200.00, "bid_qty": 75, "ask": 2353000.00, "ask_qty": 825 },
{ "bid": 2352195.00, "bid_qty": 225, "ask": 2353385.00, "ask_qty": 75 },
{ "bid": 2352190.00, "bid_qty": 600, "ask": 2353495.00, "ask_qty": 75 },
{ "bid": 2352185.00, "bid_qty": 375, "ask": 2353515.00, "ask_qty": 750 }
]
}
LtpPayload
{
"response_type": "Market Data",
"symbol": "RELIANCE.NSE.EQ",
"seq_no": 1,
"sub_type": "ltp",
"sending_time": 1740462338221772895,
"type": "LtpPayload",
"ltp": 129315.00,
"volume": 5
}
DprPayload
Incase if the DPR range for any symbol changes in middle of the day
{
"response_type": "Dpr Update",
"symbol": "NIFTY25FEBFUT",
"type": "DprUpdate",
"dpr_low": 2119887.00,
"dpr_high": 2679554.00
}
Full Response Example - Market Data
[
{
"response_type": "Market Data",
"symbol": "RELIANCE.NSE.EQ",
"seq_no": 1,
"sub_type": "ltp",
"sending_time": 1740462338221772895,
"type": "LtpPayload",
"ltp": 129315.00,
"ltq": 5
},
{
"response_type": "Market Data",
"symbol": "NIFTY25FEBFUT",
"seq_no": 1,
"sub_type": "mtick",
"sending_time": 1740462338221772895,
"type": "MtickPayload",
"ltp": 2352210.00,
"ltq": 75,
"levels": [
{ "bid": 2352260.00, "bid_qty": 300, "ask": 2352995.00, "ask_qty": 600 },
{ "bid": 2352200.00, "bid_qty": 75, "ask": 2353000.00, "ask_qty": 825 },
{ "bid": 2352195.00, "bid_qty": 225, "ask": 2353385.00, "ask_qty": 75 },
{ "bid": 2352190.00, "bid_qty": 600, "ask": 2353495.00, "ask_qty": 75 },
{ "bid": 2352185.00, "bid_qty": 375, "ask": 2353515.00, "ask_qty": 750 }
]
},
{
"response_type": "Market Data",
"symbol": "NIFTY25FEBFUT",
"seq_no": 1,
"sub_type": "utick",
"sending_time": 1740462338221772895,
"type": "UtickPayload",
"iv": 0.12,
"spot_price": 2352210.00,
"options": [
{ "strike_price": 2330000.00, "option_type": 67, "ltp": 61440.00, "oi": 220425.00, "volume": 133800 },
{ "strike_price": 2335000.00, "option_type": 67, "ltp": 58515.00, "oi": 21075.00, "volume": 22875 },
{ "strike_price": 2340000.00, "option_type": 67, "ltp": 55785.00, "oi": 177225.00, "volume": 133275 },
{ "strike_price": 2345000.00, "option_type": 67, "ltp": 52810.00, "oi": 56625.00, "volume": 13950 },
{ "strike_price": 2350000.00, "option_type": 67, "ltp": 50205.00, "oi": 890175.00, "volume": 703575 },
........................................................
]
}
]
Limitations
- A user can establish up to 10 WebSocket connections.
- Each subscription request can include up to 200 symbols, but a user can subscribe to a maximum of 2000 symbols by making multiple subscription requests.
FlatBuffer Message Schema
Request Schema (RequestWrapper.fbs)
Response Schema (ResponseWrapper.fbs)
Example Usage
from brokerage_client.data import MarketDataClient
AUTH_TOKEN = "your_auth_token_here"
UCC = "your_ucc_here"
def on_connect(ws):
print("Connection established.")
subscription_list = [
{"symbol": "RELIANCE.NSE.EQ", "sub_type": "ltp"},
{"symbol": "NIFTY25FEBFUT", "sub_type": "mtick", "expiry": 20250227},
{"symbol": "NIFTY25FEBFUT", "sub_type": "utick", "expiry": 20250227},
]
client.subscribe("sub1", subscription_list)
def on_ticks(ws, ticks):
for i, tick in enumerate(ticks):
print(f"\nTick {i + 1}:")
for key, value in tick.items():
print(f" {key}: {value}")
def on_close(ws):
print(f"WebSocket Connection closed")
# Initialize the MarketDataClient instance
client = MarketDataClient()
client.init(on_connect=on_connect,on_ticks=on_ticks,on_close=on_close)
# Connect to the market data WebSocket
client.connect(UCC, AUTH_TOKEN)
Conclusion
The MarketDataClient
provides a robust way to connect to a market data streaming service using FlatBuffer serialization. By following this documentation, you can establish connections, subscribe to market data, and process the incoming data efficiently.