Skip to main content
 首页 » 编程设计

python之使用 Python 在 QuickFIX 中发送 TradeCaptureReport 但无法接收到任何 TradeCaptureReportAck

2025年05月04日26zfyouxi

我使用 QuickFIX 1.13.3 的 Python API 编写了一个启动器。

它只是将类型为TradeCaptureReport(代码:AE)的消息发送给接受者。 我应该收到一个 TradeCaptureReportAck(事实上,如果我使用另一个客户端,我会收到它),但没有任何回复。

使用 Wireshark,我可以看到登录和注销正确执行,心跳也正确保存。

我写的Application定义如下:

import sys 
import time 
import thread 
import quickfix as fix 
import quickfix44 as fix44 
from datetime import datetime 
 
class Application (fix.Application): 
    orderID = 0 
    execID = 0 
    tradeID = 0 
    global settings 
 
    def onCreate (self, sessionID): 
        self.sessionID = sessionID 
        print ("Application created - session: " + sessionID.toString ()) 
 
    def onLogon (self, sessionID): 
        print ("Logon") 
 
    def onLogout (self, sessionID): 
        print ("Logout") 
 
    def onMessage (self, message, sessionID): 
        print (message) 
 
    def toAdmin (self, message, sessionID): 
        msgType = fix.MsgType () 
        message.getHeader ().getField (msgType) 
        if (msgType.getValue () == fix.MsgType_Logon): 
            message.setField (fix.Password (settings.get (self.sessionID).getString ("Password"))) 
            message.setField (fix.ResetSeqNumFlag (True)) 
 
    def fromAdmin (self, message, sessionID): 
        pass 
 
    def toApp (self, message, sessionID): 
        pass 
 
    def fromApp (self, message, sessionID): 
        pass 
 
    def genOrderID (self): 
        self.orderID += 1 
        return repr (self.orderID) 
 
    def genTradeReportID (self): 
        self.tradeID += 1 
        return repr (self.tradeID) 
 
    def genExecID (self): 
        self.execID += 1 
        return repr (self.execID) 
 
    def run (self): 
        time.sleep (5) 
        self.queryEnterOrder () 
        time.sleep (5) 
 
    def queryEnterOrder (self): 
        print ("\nTradeCaptureReport (AE)\n") 
        trade = fix.Message () 
        trade.getHeader ().setField (fix.BeginString (fix.BeginString_FIX44)) 
        trade.getHeader ().setField (fix.MsgType (fix.MsgType_TradeCaptureReport)) 
 
        trade.setField (fix.TradeReportTransType (fix.TradeReportTransType_NEW))       # 487 
        trade.setField (fix.TradeReportID (self.genTradeReportID ()))                  # 571 
        trade.setField (fix.TrdSubType (4))                        # 829 
        trade.setField (fix.SecondaryTrdType (2))                  # 855 
        trade.setField (fix.Symbol ("MYSYMBOL"))                   # 55 
        trade.setField (fix.LastQty (22))                          # 32 
        trade.setField (fix.LastPx (21.12))                        # 31 
        trade.setField (fix.TradeDate ((datetime.now ().strftime ("%Y%m%d"))))                      # 75 
        trade.setField (fix.TransactTime ((datetime.now ().strftime ("%Y%m%d-%H:%M:%S.%f"))[:-3]))  # 60 
        trade.setField (fix.PreviouslyReported (False))            # 570 
 
        group = fix44.TradeCaptureReport ().NoSides () 
 
        group.setField (fix.Side (fix.Side_SELL))                  # 54 
        group.setField (fix.OrderID (self.genOrderID ()))          # 37 
        group.setField (fix.NoPartyIDs (1))                        # 453 
        group.setField (fix.PartyIDSource (fix.PartyIDSource_PROPRIETARY_CUSTOM_CODE)) # 447 
        group.setField (fix.PartyID ("CLEARING"))                  # 448 
        group.setField (fix.PartyRole (fix.PartyRole_CLEARING_ACCOUNT))                # 452 
        trade.addGroup (group) 
 
        group.setField (fix.Side (fix.Side_BUY))                   # 54 
        group.setField (fix.OrderID (self.genOrderID ()))          # 37 
        group.setField (fix.NoPartyIDs (1))                        # 453 
        group.setField (fix.PartyIDSource (fix.PartyIDSource_PROPRIETARY_CUSTOM_CODE)) # 447 
        group.setField (fix.PartyID ("CLEARING"))                  # 448 
        group.setField (fix.PartyRole (fix.PartyRole_CLEARING_ACCOUNT))                # 452 
        trade.addGroup (group) 
 
        fix.Session.sendToTarget (trade, self.sessionID) 

由于以下代码片段而运行:

file = sys.argv[1] 
settings = fix.SessionSettings (file) 
application = Application () 
storeFactory = fix.FileStoreFactory (settings) 
initiator = fix.SocketInitiator (application, storeFactory, settings) 
 
initiator.start () 
application.run () 
initiator.stop () 

更新

消息的交换如下(I = Initiator,A = Acceptor):

1. I ---------- LOGON -----------> A 
2. I <--------- LOGON ------------ A 
3. I ---- TradeCaptureReport ----> A 
4. I ---------- LOGOFF ----------> A 
5. I <--------- LOGOFF ----------- A 

如您所见,在 3. 和 4. 之间缺少一条 TradeCaptureReportAck 类型的消息。

欢迎任何提示!

请您参考如下方法:

尝试实现您的 fromAdmin 和 fromApp 方法,您应该会在此处看到返回的 FIX 消息。检查您的 TradeCaptureReportAck 是否到达此处并确认它们遵循与登录、注销和检测信号相同的调用。并实现您的 onMessage 方法,或检查您是否在此处收到任何 FIX 消息。这应该是您应该看到 ACK 返回消息的地方。