Working Python Script for WebSocket Live.
import requests
import json
import websocket
import struct
WebSocketurl = 'wss://developer-ws.paytmmoney.com/broadcast/user/v1/data?x_jwt_token={{public_access_token}}'
preferences = [
{
"actionType": "ADD",
"modeType": "FULL",
"scripType": "INDEX",
"exchangeType": "NSE",
"scripId": "13"
}
];
remove_Preference = [
{
"actionType": "ADD",
"modeType": "LTP",
"scripType": "EQUITY",
"exchangeType": "BSE",
"scripId": "523144"
}
]
class decoder:
def unpack(self, binary, start, end, byte_format="I"):
"""Unpack binary data as given data type format."""
return struct.unpack("<" + byte_format, binary[start:end])[0]
def parse_binary(self, buffer_packet):
buffer_length = len(buffer_packet)
packet = bytearray(buffer_packet)
response = []
byte_buffer = packet.copy()
position = 0
while position != buffer_length:
packet_type = byte_buffer[position]
position += 1
if packet_type == 64:
self.process_index_ltp_packet(byte_buffer, response, position)
position += 22
elif packet_type == 65:
self.process_index_quote_packet(byte_buffer, response, position)
position += 42
elif packet_type == 66:
self.process_index_full_packet(byte_buffer, response, position)
position += 38
elif packet_type == 61:
self.process_ltp_packet(byte_buffer, response, position)
position += 22
elif packet_type == 62:
self.process_quote_packet(byte_buffer, response, position)
position += 66
elif packet_type == 63:
self.process_full_packet(byte_buffer, response, position)
position += 174
return response
def process_index_ltp_packet(self, byte_buffer, response, position):
"""
parses index_ltp packets into readable format
:param byte_buffer: ByteBuffer packet received from server
:param response: Response Array in readable format
:param position: current position of packet to be processed
"""
response.append({
"LTP": round(self.unpack(byte_buffer, position, position + 4, "f"), 2),
"LTT": self.unpack(byte_buffer, position + 4, position + 8),
"security_id": self.unpack(byte_buffer, position + 8, position + 12),
"tradable": byte_buffer[position + 12],
"mode": byte_buffer[position + 13],
"change_absolute": round(self.unpack(byte_buffer, position + 14, position + 18, "f"), 2),
"change_percent": round(self.unpack(byte_buffer, position + 18, position + 22, "f"), 2)
})
def process_ltp_packet(self, byte_buffer, response, position):
"""
parses ltp packets into readable format
:param byte_buffer: ByteBuffer packet received from server
:param response: Response Array in readable format
:param position: current position of packet to be processed
"""
response.append({
"LTP": round(self.unpack(byte_buffer, position, position + 4, "f"), 2),
"LTT": self.unpack(byte_buffer, position + 4, position + 8),
"security_id": self.unpack(byte_buffer, position + 8, position + 12),
"tradable": byte_buffer[position + 12],
"mode": byte_buffer[position + 13],
"change_absolute": round(self.unpack(byte_buffer, position + 14, position + 18, "f"), 2),
"change_percent": round(self.unpack(byte_buffer, position + 18, position + 22, "f"), 2)
})
def process_quote_packet(self, byte_buffer, response, position):
"""
parses quote packets into readable format
:param byte_buffer: ByteBuffer packet received from server
:param response: Response Array in readable format
:param position: current position of packet to be processed
"""
response.append({
"LTP": round(self.unpack(byte_buffer, position, position + 4, "f"), 2),
"LTT": self.unpack(byte_buffer, position + 4, position + 8),
"security_id": self.unpack(byte_buffer, position + 8, position + 12),
"tradable": byte_buffer[position + 12],
"mode": byte_buffer[position + 13],
"last_traded_quantity": self.unpack(byte_buffer, position + 14, position + 18),
"average_traded_price": round(self.unpack(byte_buffer, position + 18, position + 22, "f"), 2),
"volume_traded": self.unpack(byte_buffer, position + 22, position + 26),
"total_buy_quantity": self.unpack(byte_buffer, position + 26, position + 30),
"total_sell_quantity": self.unpack(byte_buffer, position + 30, position + 34),
"open": round(self.unpack(byte_buffer, position + 34, position + 38, "f"), 2),
"close": round(self.unpack(byte_buffer, position + 38, position + 42, "f"), 2),
"high": round(self.unpack(byte_buffer, position + 42, position + 46, "f"), 2),
"low": round(self.unpack(byte_buffer, position + 46, position + 50, "f"), 2),
"change_percent": round(self.unpack(byte_buffer, position + 50, position + 54, "f"), 2),
"change_absolute": round(self.unpack(byte_buffer, position + 54, position + 58, "f"), 2),
"fifty_two_week_high": round(self.unpack(byte_buffer, position + 58, position + 62, "f"), 2),
"fifty_two_week_low": round(self.unpack(byte_buffer, position + 62, position + 66, "f"), 2)
})
def process_index_quote_packet(self, byte_buffer, response, position):
"""
parses index_quote packets into readable format
:param byte_buffer: ByteBuffer packet received from server
:param response: Response Array in readable format
:param position: current position of packet to be processed
"""
response.append({
"LTP": round(self.unpack(byte_buffer, position, position + 4, "f"), 2),
"security_id": self.unpack(byte_buffer, position + 4, position + 8),
"tradable": byte_buffer[position + 8],
"mode": byte_buffer[position + 9],
"open": round(self.unpack(byte_buffer, position + 10, position + 14, "f"), 2),
"close": round(self.unpack(byte_buffer, position + 14, position + 18, "f"), 2),
"high": round(self.unpack(byte_buffer, position + 18, position + 22, "f"), 2),
"low": round(self.unpack(byte_buffer, position + 22, position + 26, "f"), 2),
"change_percent": round(self.unpack(byte_buffer, position + 26, position + 30, "f"), 2),
"change_absolute": round(self.unpack(byte_buffer, position + 30, position + 34, "f"), 2),
"fifty_two_week_high": round(self.unpack(byte_buffer, position + 34, position + 38, "f"), 2),
"fifty_two_week_low": round(self.unpack(byte_buffer, position + 38, position + 42, "f"), 2)
})
def process_full_packet(self, byte_buffer, response, position):
"""
parses full packets into readable format
:param byte_buffer: ByteBuffer packet received from server
:param response: Response Array in readable format
:param position: current position of packet to be processed
"""
depth_size = 20
depth_packet = {}
for i in range(5):
depth = "depth_packet_#" + str(i + 1)
depth_obj = {
"buy_quantity": self.unpack(byte_buffer, 1 + (i * depth_size), 5 + (i * depth_size)),
"sell_quantity": self.unpack(byte_buffer, 5 + (i * depth_size), 9 + (i * depth_size)),
"buy_order": self.unpack(byte_buffer, 9 + (i * depth_size), 11 + (i * depth_size), "h"),
"sell_order": self.unpack(byte_buffer, 11 + (i * depth_size), 13 + (i * depth_size), "h"),
"buy_price": round(self.unpack(byte_buffer, 13 + (i * depth_size), 17 + (i * depth_size), "f"), 2),
"sell_price": round(self.unpack(byte_buffer, 17 + (i * depth_size), 21 + (i * depth_size), "f"), 2)
}
depth_packet[depth] = depth_obj
tick = {"depth_packet": depth_packet}
position += 100
tick["ltp"] = round(self.unpack(byte_buffer, position, position + 4, "f"), 2)
tick["last_traded_time"] = self.unpack(byte_buffer, position + 4, position + 8)
tick["security_id"] = self.unpack(byte_buffer, position + 8, position + 12)
tick["tradable"] = byte_buffer[position + 12]
tick["mode"] = byte_buffer[position + 13]
tick["last_traded_quantity"] = self.unpack(byte_buffer, position + 14, position + 18)
tick["average_traded_price"] = round(self.unpack(byte_buffer, position + 18, position + 22, "f"), 2)
tick["volume_traded"] = self.unpack(byte_buffer, position + 22, position + 26)
tick["total_buy_quantity"] = self.unpack(byte_buffer, position + 26, position + 30)
tick["total_sell_quantity"] = self.unpack(byte_buffer, position + 30, position + 34)
tick["open"] = round(self.unpack(byte_buffer, position + 34, position + 38, "f"), 2)
tick["close"] = round(self.unpack(byte_buffer, position + 38, position + 42, "f"), 2)
tick["high"] = round(self.unpack(byte_buffer, position + 42, position + 46, "f"), 2)
tick["low"] = round(self.unpack(byte_buffer, position + 46, position + 50, "f"), 2)
tick["change_percent"] = round(self.unpack(byte_buffer, position + 50, position + 54, "f"), 2)
tick["change_absolute"] = round(self.unpack(byte_buffer, position + 54, position + 58, "f"), 2)
tick["fifty_two_week_high"] = round(self.unpack(byte_buffer, position + 58, position + 62, "f"), 2)
tick["fifty_two_week_low"] = round(self.unpack(byte_buffer, position + 62, position + 66, "f"), 2)
tick["OI"] = self.unpack(byte_buffer, position + 66, position + 70)
tick["OI_change"] = self.unpack(byte_buffer, position + 70, position + 74)
response.append(tick)
def process_index_full_packet(self, byte_buffer, response, position):
"""
parses index_full packets into readable format
:param byte_buffer: ByteBuffer packet received from server
:param response: Response Array in readable format
:param position: current position of packet to be processed
"""
response.append({
"LTP": round(self.unpack(byte_buffer, position, position + 4, "f"), 2),
"security_id": self.unpack(byte_buffer, position + 4, position + 8),
"tradable": byte_buffer[position + 8],
"mode": byte_buffer[position + 9],
"open": round(self.unpack(byte_buffer, position + 10, position + 14, "f"), 2),
"close": round(self.unpack(byte_buffer, position + 14, position + 18, "f"), 2),
"high": round(self.unpack(byte_buffer, position + 18, position + 22, "f"), 2),
"low": round(self.unpack(byte_buffer, position + 22, position + 26, "f"), 2),
"change_percent": round(self.unpack(byte_buffer, position + 26, position + 30, "f"), 2),
"change_absolute": round(self.unpack(byte_buffer, position + 30, position + 34, "f"), 2),
"last_trade_time": self.unpack(byte_buffer, position + 34, position + 38)
})
def message_Received(ws, message):
print("message arrived")
#message receved is utf-8
bye_bufferDecoder = decoder()
print(bye_bufferDecoder.parse_binary(message))
def on_open(ws):
print("connection Opened")
ws.send(json.dumps(preferences))
# ws.send(preferences)
def on_close(ws,close_status_code,close_message):
print("Closed")
print("Status Code--->")
print(close_status_code)
print(close_message)
def on_error(ws,e):
print(e)
ws = websocket.WebSocketApp(WebSocketurl,on_open=on_open,on_close=on_close,on_message=message_Received,on_error=on_error)
ws.run_forever()