ARTICLE AD BOX
I'm building a project to get market data from Deribit FIX. I'm using QuickFIX for this.
Here is my toAdmin and fromAdmin block of code, which handles the logon connection logic:
def toAdmin(self, message, sessionID): """Handles message authentication for outgoing admin messages.""" msg_type = fix.MsgType() message.getHeader().getField(msg_type) if msg_type.getValue() == fix.MsgType_Logon: nonce = os.urandom(32) timestamp_ms = str(int(time.time() * 1000)) nonce_b64 = base64.b64encode(nonce).decode('utf-8') raw_data = f"{timestamp_ms}.{nonce_b64}" signature_input = raw_data + self.client_secret signature_hash = hashlib.sha256(signature_input.encode('utf-8')).digest() signature_b64 = base64.b64encode(signature_hash).decode('utf-8') message.setField(fix.Username(self.client_id)) # tag 553 message.setField(fix.Password(signature_b64)) # tag 554 message.setField(fix.RawDataLength(len(raw_data))) # tag 95 message.setField(fix.RawData(raw_data)) # tag 96 logger.info("Sending Logon with Deribit authentication") logger.info(f"Client ID: {self.client_id}") logger.info(f"Client Secret (first 10): {self.client_secret[:10]}...") logger.info(f"Timestamp: {timestamp_ms}") logger.info(f"RawData length: {len(raw_data)}") logger.info(f"RawData: {raw_data}") logger.info(f"Signature (first 20): {signature_b64[:20]}...") logger.info(f"Full Logon Message:\n{message.toString()}") def fromAdmin(self, message, sessionID): """Handles incoming admin messages from Deribit.""" msg_type = fix.MsgType() message.getHeader().getField(msg_type) logger.info(f"Received admin message type: {msg_type.getValue()}") logger.info(f"Full message:\n{message.toString()}") if msg_type.getValue() == fix.MsgType_Logon: logger.info("Logon acknowledgment received from Deribit!") elif msg_type.getValue() == fix.MsgType_Logout: text = fix.Text() if message.isSetField(text): message.getField(text) logger.error(f"LOGOUT RECEIVED - Reason: {text.getValue()}") else: logger.error("LOGOUT RECEIVED - No reason provided") logger.error(f"Full logout message:\n{message.toString()}") elif msg_type.getValue() == fix.MsgType_Reject: logger.error(f"REJECT RECEIVED:\n{message.toString()}") if message.isSetField(fix.Text()): text = fix.Text() message.getField(text) logger.error(f"Reject reason: {text.getValue()}") else: logger.debug(f"Admin message type: {msg_type.getValue()}") def toApp(self, message, sessionID): """Handles outgoing application messages.""" logger.debug(f"Sending message to app: {message}") def fromApp(self, message, sessionID): """Handles incoming application messages.""" try: self.process_message(message, sessionID) except Exception as e: logger.error(f"Error processing message: {e}", exc_info=True)When I run the project, I see this in my terminal:
2025-12-04 00:42:48,691 - INFO - Sending Logon with Deribit authentication 2025-12-04 00:42:48,743 - INFO - connection stops on this idFIX.4.4:MYTRADER->DERIBITSERVERSo far, I've checked that my Deribit API credential are correct and have both read and write permissions.
