发送Logon时Deribit FIX连接中断问题(基于QuickFIX)
排查Deribit FIX接口QuickFIX连接中断问题
问题背景
基于QuickFIX开发Deribit FIX行情数据获取项目,已确认API凭证有效且具备读写权限,但发送Logon消息后立即出现连接中断:
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->DERIBITSERVER
相关登录逻辑代码如下:
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)
排查与修复方案
1. 检查Deribit FIX端点与SSL配置
Deribit测试网和主网的FIX端点不同,且强制使用SSL加密:
- 测试网:
fix.test.deribit.com:443 - 主网:
fix.deribit.com:443
确保QuickFIX配置文件中SocketConnectHost、SocketConnectPort正确,且添加UseSSL=Y启用传输层加密。
2. 补全Logon消息必填字段
Deribit要求Logon消息必须包含以下字段,当前代码可能遗漏:
- EncryptMethod (tag 98):固定为
0(Deribit用SSL加密,无需应用层加密) - HeartBtInt (tag 108):建议设为30(心跳间隔,单位秒)
- ResetSeqNumFlag (tag 141):设为
Y重置会话序列号,避免历史序列冲突
修改toAdmin方法,在设置现有字段后添加:
message.setField(fix.EncryptMethod(0)) message.setField(fix.HeartBtInt(30)) message.setField(fix.ResetSeqNumFlag(True))
3. 校准本地服务器时间
Deribit的签名验证依赖精确时间戳,要求本地时间与NTP服务器同步,误差不能超过5分钟。使用系统自带时间同步工具或ntpdate命令校准时间。
4. 开启QuickFIX详细日志
修改QuickFIX配置文件,开启调试级日志,查看底层交互细节:
FileStorePath=store FileLogPath=log UseDataDictionary=Y DataDictionary=FIX44.xml SocketConnectHost=fix.test.deribit.com SocketConnectPort=443 UseSSL=Y LogonTimeout=30 HeartBtInt=30 ResetSeqNumFlag=Y # 开启调试日志 Debug=Y LogMessages=Y
查看log目录下的日志文件,确认是否收到Deribit返回的Reject/Logout消息(可能因日志级别未在终端输出)。
5. 验证签名生成逻辑
对照Deribit规则检查签名生成:
- nonce必须是32字节随机数据,Base64编码后无多余字符
- 时间戳必须是毫秒级字符串
- 签名输入为
{timestamp_ms}.{nonce_b64} + client_secret,无额外分隔符 - SHA256哈希后需Base64编码作为Password字段
6. 检查会话ID配置
Deribit的FIX会话ID格式为FIX.4.4:CLIENT_ID->DERIBIT,确保配置文件中SenderCompID为你的Client ID,TargetCompID为DERIBIT(测试网/主网一致)。
总结
优先排查SSL配置、必填字段完整性和时间同步,这些是Deribit FIX连接中断的高频原因。开启详细日志后,可精准定位Deribit返回的具体错误信息。
内容的提问来源于stack exchange,提问作者AKSHAT GUPTA
相关产品推荐
相关产品推荐

