Broker Real-time Order Updates Module - Websocket
¶
Section | Description |
---|---|
EndPoint | Connection EndPoint details |
Base Endpoint¶
wss://server.quantsapp.com/order-updates
Query Params¶
Name | Value |
---|---|
ws_msg_type | etoken |
etoken | etoken_value 1 |
portal | api |
sub_portal | api |
version | 1.0.0 |
country | in |
uid | mac_address of connected network 2 |
ref_id | unique random alphanumeric string of len 16 |
Sample WS Url
Websocket Connection Response¶
Name | Description | Allowed Values |
---|---|---|
status str |
Status code | -1 | 0 | 1 |
msg str |
Message | Success | Failure Message |
ws_msg_type str |
Login token to be used for further Authentication | qapp_api_gateway_options_etoken_authorized |
On Failure Websocket will be closed with any of the below Error Codes
Error Code | Error Description | Actions to be done |
---|---|---|
4000 |
Invalid Session | Relogin and try with new jwt_token |
4001 |
User Already disconnected | Retry again |
4002 |
Query Params Missing | Please make sure all required query params are passed |
4003 |
Invalid Data | Value of Query params are invalid |
4004 |
Account Not Exists | Create a new account |
4005 |
Account Locked | Please contact [email protected] |
4006 |
Force disconnect due to max active connections reached | Retry again with the disconnected conn to make it active again |
4007 |
Force disconnect due to ideal state for sometime | Retry again |
4008 |
UID Mismatch | Retry again |
4009 |
Force Disconnect due to other device login | Some other device use the secret key, Retry again to make this connection active |
4500 |
Server Error | Retry again after sometime |
Broker Order Update Data binary
¶
It's a byte encoded data with little-endian
byte-order. The message structure is of below
Data Ref | Data Type | Byte Data Range | Data Name |
---|---|---|---|
α |
short (2 bytes) |
0 : 2 | Length of Broker ClientID |
β |
int32 (4 bytes) |
2 : 6 | Length of Broker Update data |
γ |
char[] (α bytes) |
6 : 6+α |
Broker ClientID |
δ |
char[] (β bytes) |
6+α : 6+α +β |
Broker Update data |
Broker Order Update decoding example
sample data
Binary data = b"\x0e\x00\x05\x01\x00\x00choice,X253314\x1f\x8b\x08\x00K\x8eJh\x02\xffUPMK\x031\x10\xfd+%\xe7V\xf2\xb9!K/^\x04=(B\x05=\x85m6\xc5\xc0~5\x99\x1c\x8a\xf8\xdf\xcdd\xa9\xd6\x9c\xde\xcc{\xf3\xe6M\xbeH\xe7H\xbb!\xees\x0e\xceo\xdf\xb9\x12\x82I\xb2\xdd\x90\xa3\x9dc\xefc\xe8\x91\xbe?\xbc\xbe\xbc\xd1\xf2\xd8\xbeA\xd2\xdf\x92L\xd2J\t\xddHe\xb8F\xc1\xd9F\x7f\xb2\x95gX\xc2\xc5\x9e\xc20xl\xd0\xb5Q\x90V\x05\x86)A\xcc\xa3\x9f\x00\xcd\x9e\x1f\x1f\x0e\x1f-\xe3\xbb\xa7<\xed\xb8j]\xcb\x15U\xb4&J(8"\bI\x8bVwL]\xcb\xff\x0b\x8e6\'\xefl^\xfa\x0eP\xc9\xb44\x9a\t\xae\xe9\xfa\xea\xd4\xdcg\x07\x16.\x0b*\xc8\x14\xc7\x01\xcd\xebi6A\x07\xb9n\x84\xd8M)@\xa5\xac\x83Xz\xa2\xe0\xe2\xbf~@\xc3\xb92\xf2w\xf0j7\x84q\x1d:\xd7(7\x19\x84\xd4\xdc\x18\xc3\x0b\x97`^\xec\xdf5\xf4\xfb\x07\xff\xf2\xc6\xbe\x91\x01\x00\x00"
Base64 data = "DgAFAQAAY2hvaWNlLFgyNTMzMTQfiwgAS45KaAL/VVBNSwMxEP0rJedW8rkhSy9eBD0oQgU9hW02xcB+NZkcivjfzWSp1pzezHvz5k2+SOdIuyHucw7Ob9+5EoJJst2Qo51j72Pokb4/vL680fLYvkHS35JM0koJ3UhluEbB2UZ/spVnWMLFnsIweGzQtVGQVgWGKUHMo58AzZ4fHw4fLeO7pzztuGpdyxVVtCZKKDgiXGJJi1Z3TF3L/wuONifvbF76DlDJtDSaCa7p+urU3GcHFi4LKsgUxwHN62k2QQe5boTYTSlApayDWHqi4OK/fkDDuTLyd/BqN4RxHTrXKDcZhNTcGMMLl2Be7N819PsH//LGvpEBAAA="
Byte array data = [14, 0, 5, 1, 0, 0, 99, 104, 111, 105, 99, 101, 44, 88, 50, 53, 51, 51, 49, 52, 31, 139, 8, 0, 75, 142, 74, 104, 2, 255, 85, 80, 77, 75, 3, 49, 16, 253, 43, 37, 231, 86, 242, 185, 33, 75, 47, 94, 4, 61, 40, 66, 5, 61, 133, 109, 54, 197, 192, 126, 53, 153, 28, 138, 248, 223, 205, 100, 169, 214, 156, 222, 204, 123, 243, 230, 77, 190, 72, 231, 72, 187, 33, 238, 115, 14, 206, 111, 223, 185, 18, 130, 73, 178, 221, 144, 163, 157, 99, 239, 99, 232, 145, 190, 63, 188, 190, 188, 209, 242, 216, 190, 65, 210, 223, 146, 76, 210, 74, 9, 221, 72, 101, 184, 70, 193, 217, 70, 127, 178, 149, 103, 88, 194, 197, 158, 194, 48, 120, 108, 208, 181, 81, 144, 86, 5, 134, 41, 65, 204, 163, 159, 0, 205, 158, 31, 31, 14, 31, 45, 227, 187, 167, 60, 237, 184, 106, 93, 203, 21, 85, 180, 38, 74, 40, 56, 34, 92, 98, 73, 139, 86, 119, 76, 93, 203, 255, 11, 142, 54, 39, 239, 108, 94, 250, 14, 80, 201, 180, 52, 154, 9, 174, 233, 250, 234, 212, 220, 103, 7, 22, 46, 11, 42, 200, 20, 199, 1, 205, 235, 105, 54, 65, 7, 185, 110, 132, 216, 77, 41, 64, 165, 172, 131, 88, 122, 162, 224, 226, 191, 126, 64, 195, 185, 50, 242, 119, 240, 106, 55, 132, 113, 29, 58, 215, 40, 55, 25, 132, 212, 220, 24, 195, 11, 151, 96, 94, 236, 223, 53, 244, 251, 7, 255, 242, 198, 190, 145, 1, 0, 0]
import base64, json, gzip
def decode_broker_update_data(byte_data: bytes) -> dict:
len_broker_client, len_data = struct.unpack('<hi', byte_data[:6])
broker_client = struct.unpack(f"<{len_broker_client}s", byte_data[6:6+len_broker_client])[0].decode()
broker_updated_data = json.loads(gzip.decompress(struct.unpack(f"<{len_data}s", byte_data[6+len_broker_client:6+len_broker_client+len_data])[0]))
return broker_updated_data
// Import pako for GZIP decompression
const pako = require('pako'); // For Node.js
/**
* Decodes broker update data from a byte array.
* @param {ArrayBuffer} byteData - The raw binary data as an ArrayBuffer.
* @returns {Promise<Object>} - A promise that resolves with the decoded JSON object.
*/
async function decodeBrokerUpdateData(byteData) {
// Create a DataView to read primitive types (like integers) with specific byte order.
const dataView = new DataView(byteData);
// 1. Read len_broker_client (2-byte short, little-endian) and len_data (4-byte int, little-endian)
// The 'true' argument specifies little-endian byte order.
const lenBrokerClient = dataView.getInt16(0, true); // Reads 2 bytes at offset 0
const lenData = dataView.getInt32(2, true); // Reads 4 bytes at offset 2
// Calculate start and end offsets for various parts of the data.
const brokerClientStart = 6;
const brokerClientEnd = brokerClientStart + lenBrokerClient;
const gzippedJsonStart = brokerClientEnd;
const gzippedJsonEnd = gzippedJsonStart + lenData;
// Basic validation to prevent reading beyond buffer bounds
if (gzippedJsonEnd > byteData.byteLength) {
throw new Error("Provided byte data is too short for the declared lengths.");
}
// 2. Extract and decode broker_client string
// Create a Uint8Array view of the specific slice for broker_client.
const brokerClientBytes = new Uint8Array(byteData, brokerClientStart, lenBrokerClient);
// Use TextDecoder to convert bytes to a string (UTF-8 is common for .decode())
const brokerClient = new TextDecoder('utf-8').decode(brokerClientBytes);
// 3. Extract and decompress the GZIPped JSON data
// Create a Uint8Array view of the specific slice for gzipped JSON data.
const gzippedJsonBytes = new Uint8Array(byteData, gzippedJsonStart, lenData);
let decompressedJsonString;
try {
// Use pako's ungzip function. 'to: "string"' tells pako to return a string.
decompressedJsonString = pako.ungzip(gzippedJsonBytes, { to: 'string' });
} catch (error) {
console.error("Error during GZIP decompression:", error);
throw new Error("Failed to decompress GZIP data. It might be corrupted or not valid GZIP.");
}
// 4. Parse the decompressed JSON string
let brokerUpdatedData;
try {
brokerUpdatedData = JSON.parse(decompressedJsonString);
} catch (error) {
console.error("Error during JSON parsing:", error);
throw new Error("Failed to parse JSON data. Decompressed data might not be valid JSON.");
}
return brokerUpdatedData;
}
Broker Order Update Structure¶
Name | Description | Allowed Values |
---|---|---|
ac str |
Broker Account | BrokerClient |
b_orderid str |
Broker OrderID | str |
e_orderid str |
Exchange OrderID | str |
q_ref_id int |
Quantsapp Reference ID | int |
qty int |
Quantity | int |
qty_filled int |
Quantity Filled | int |
instrument str |
Instrument | str |
bs str |
Buy or Sell | OrderBuySell |
price float |
Order Price | float |
price_filled float |
Order Price filled | float |
product_type str |
Order Product type | ProductType |
order_status str |
Order status | OrderStatus |
order_type int |
Order Type | OrderType |
o_ctr int |
Order update counter | int |
user_id int |
UserID placed the Order | int |
b_usec_update int |
Broker order update microseconds (µsec) | int |
q_usec int |
Quantsapp order update microseconds (µsec) | int |
stop_price float |
Stop Price | float |
Sample decodeed data
{
"ac": "choice,X253314",
"b_orderid": "ATQOU00001<6",
"e_orderid": "1400000137645927",
"q_ref_id": 1,
"qty_filled": 0,
"qty": 75,
"instrument": "NIFTY:12-Jun-25:c:25050",
"bs": "b",
"price": 0.15,
"price_filled": 0,
"product_type": "nrml",
"order_status": "transit",
"order_type": "limit",
"o_ctr": 3,
"userid": 622594,
"b_usec_update": 1749713270000000,
"q_usec": 1749713234729992,
"stop_price": 0.0
}
-
EToken received from Execution Process ↩
-
MAC Address Retrieval Code
Pythonimport uuid def get_mac_address() -> str: """Retreive the mac address of the connected network interface""" # Get the hardware address as a 48-bit positive integer mac_num = uuid.getnode() # 1. Convert the number to hex # 2. Pad it to 12 chars # 3. Convert it to a series of two char strings # 4. Join them with colons # 5. convert to uppercase return ':'.join(f"{b:02x}" for b in mac_num.to_bytes(6)).upper() print(get_mac_address) # 15:A2:C8:DD:31:11
JavaScriptconst os = require('os'); /** * Retrieves the MAC address of a connected non-internal network interface. * Prioritizes non-internal (e.g., Ethernet, Wi-Fi) interfaces with a MAC address. * * @returns {string | null} The MAC address in 'XX:XX:XX:XX:XX:XX' format, or null if not found. */ function getMacAddress() { const interfaces = os.networkInterfaces(); let macAddress = null; // Iterate over all network interfaces for (const interfaceName in interfaces) { const networkInterface = interfaces[interfaceName]; for (const iface of networkInterface) { // Filter out internal (loopback) interfaces and ensure it has a MAC address if (!iface.internal && iface.mac && iface.mac !== '00:00:00:00:00:00') { macAddress = iface.mac.toUpperCase(); // Found a valid MAC address, you might want to return the first one found // or continue iterating if you have a specific interface in mind. // For simplicity, we return the first valid one here. return macAddress; } } } return macAddress; // Return null if no suitable MAC address was found } // --- Usage Example --- const mac = getMacAddress(); if (mac) { console.log(`MAC Address: ${mac}`); } else { console.log("No MAC address found for a non-internal interface."); } // MAC Address: 15:A2:C8:DD:31:11