2016-01-13 141 views
0

我想澄清在以下情況下QuickFIX/J(FIX 4.2)的行爲。有兩方參與這一QuickFIX/J通信:QuickFIX/J中斷開連接的客戶端的消息隊列行爲

  1. 客戶端發起,名爲
  2. 我們公司的接受者計劃,名爲A

登錄到一個,他們交換FIX信息與標籤35=A。連接建立後,I開始提交訂單。有可能是一個點然而,在意外斷開,此時一個決定發送所有的的未結訂單的取消我(這是有效的,因爲一個不知道爲什麼失敗或當會回來活着)。

注意,這整個取消上斷開程序啓動和處理由一個孤獨的 - 它從一個onLogout(...)方法發起並由其正常秩序的管理機制處理。對於每個開放訂單I生成單個35=F消息,並且在每次成功取消時生成ExecutionReport35=8)。

回來活着,這些ExecutionReport s必須交付給不知何故,使其意識到了所有以前的訂單已被取消。我有一個印象,QuickFIX/J的消息隊列實現處理這個沒有應用程序級的援助。確保所有QuickFIX消息傳遞給對方(http://permalink.gmane.org/gmane.comp.finance.quickfix.devel/169)。

出乎我的理解,但是,沒有ExecutionReport小號沒有在一個QuickFIX日誌顯示的,或交付在重新連接,導致是不知道它以前的訂單有已被取消。我注意到,記錄不會的,因爲在QuickFIX/JSessionsendRaw(Message message, int num)方法的下面的源代碼中出現:

/** 
* Send the message 
* 
* @param message is the message to send 
* @param num is the seq num of the message to send, if 0, the next expected sender seqnum is used. 
* @return 
*/ 
private boolean sendRaw(Message message, int num) { 
    ... 
     } else { 
      try { 
       application.toApp(message, sessionID); 
      } catch (final DoNotSend e) { 
       return false; 
      } catch (final Throwable t) { 
       logApplicationException("toApp()", t); 
      } 
      messageString = message.toString(); 
      if (isLoggedOn()) { // happens only if session is connected 
       result = send(messageString); // logging happens within "send" 
      } 
     } 
    ... 
} 

而消除由的啓動產生ExecutionReport消息被該會議沒有登錄斷開連接,因此它從未打到send(messageString);並且沒有記錄發生。我相信沒有消息排隊(基於事實回收活動時沒有收到任何消息)出於同樣的原因。

我們公司基於相信QuickFIX/J保證所有消息都能毫無損失地交付,但我對上述場景的觀察卻另有說明。

當會話沒有登錄時,QuickFIX/J的消息隊列是如何運行的?它應該排隊消息嗎,等待將來會話再次可用時發送,還是在會話關閉期間停止排隊?

+0

如果沒有人回答這個問題,你可以試試QF/j郵件列表。 –

+0

「但是,如果我意外斷開連接,那麼A會決定取消所有I [...]的所有未結訂單的取消」。聽起來很糟糕。只是因爲有15分鐘的網絡問題,您取消所有訂單?很抱歉這麼說,但這聽起來很荒謬。這背後有什麼理由?那個要求有什麼真正的商業解釋? –

+0

@GrantBirchmeier感謝您的反饋。我們實際上證實了'35 = 8'和'150 = 4'在重新連接時從接受者來到發起者。我無法檢測到這一點。 – ylee

回答

1

而就在private boolean sendRaw(Message message, int num)方法結束時有這樣的代碼:

if (num == 0) { 
    final int msgSeqNum = header.getInt(MsgSeqNum.FIELD); 
    if (persistMessages) { 
     state.set(msgSeqNum, messageString); 
    } 
    state.incrNextSenderMsgSeqNum(); 
} 

state.set(msgSeqNum, messageString)將調用messageStore.set(sequence, message)如果會話沒有被連接,其實際存儲以便稍後傳送該消息。

據我所知,所有的消息將排隊,直到會話成功登錄。

0

這裏是我的10美分:當QF/J保證消息傳遞這對有效會話的基礎上,序列號,和缺口填補...

如果會話丟失沒有辦法保證什麼。只要發現序列號不匹配,您必須將發起方和接受方配置爲在重新連接時填充間隙。嗯,你的ResetOnDisconnect標誌在配置中說了什麼? ResetOnLogout如何?

我不認爲在QF中有一個等待會話的消息「隊列」,因爲會話可能會發出迪斯科並且永遠不會重新意味着QF隊列剛剛被填滿,或者永遠是活動的,這不是QF要做的事情能夠爲每個人提供開箱即用的服務。

如果您有迪斯科舞廳,您也不能使用OnLogout將執行報告發送給斷開連接的客戶端!首先,OnLogout並不總是在每個迪斯科舞廳上調用,其次如您所說,我們進入QF內部並且無法找到會話發送消息給其他人,除此之外。我不希望QF內部隊列爲我處理這種情況。同樣,有保證的交付是當連接UP時...這是一個依賴。但是,我期望它被記錄在某處。你的日誌配置是什麼?

我認爲你需要看看爲什麼:「當/活着回來時,這些ExecutionReports必須交付給/以某種方式,以便它知道它以前的所有訂單已被取消。」是不是更多的迪斯科所有的訂單被取消的過程?爲什麼/需要確認?這是一個給定的,不是?這可能是你必須單獨編碼到QF基地的東西。

+0

CancelOnDisconnect是我聽說過的標誌:) – rupweb

+0

「爲什麼/需要確認?」我們認爲這對未來的實施非常有用,因爲我們可以讓客戶在斷開連接時取消未結訂單(也不會取消)。另外,交換這些確認通常是安全的,因爲取消可能由於某些原因而不能由公司正確啓動。無論如何,我當時錯過了一些東西,現在知道'150 = 4'的'35 = 8'會在重新連接時被髮送到客戶端。 – ylee

+0

感謝您的反饋。 – ylee

0

閱讀this

一些公司支持在LOGON消息的標記35002(取消上斷開),可能的值:

  • 0:不使用COD
  • 1:使用COD只有當一個 「優雅」 註銷被髮送
  • 2:使用COD上的任何 「網絡」 斷開
  • 3:1和2

翅如果您的交易對手支持這一點,請退出。我沒有檢查QuickFIX支持,但您可以隨時手動添加標籤,或自定義您的FIX詞典以支持標籤。

這是高頻交易者經常使用的。我對這個行業不熟悉,因此在評論部分提出了問題。

相關問題