QuickFIX / J中断开连接的客户端的消息队列行为

时间:2016-01-13 03:45:22

标签: java session quickfix quickfixj

我想在以下场景中阐明QuickFIX/J(FIX 4.2)的行为。此QuickFIX/J通信涉及两方:

  1. 客户端发起人,名为
  2. 我们公司的接受者计划,名为 A
  3. 登录 A 时,他们会与标记35=A交换FIX消息。建立连接后,开始提交订单。然而,可能有一点,意外断开连接,此时 A 决定为的所有未结订单发送取消(这是有效的,因为 A 不知道为什么失败或会活着回来。)

    请注意,此整个取消取消程序仅由 A 启动和处理 - 它是从 A onLogout(...)启动的方法由其正常的订单管理机制处理。为的每个未结订单生成一条35=F条消息,并在每次成功取消时生成ExecutionReport35=8)。

    恢复活着时,必须以某种方式将这些ExecutionReport传递给,以便它知道所有先前的订单已被取消。我的印象是QuickFIX/J的消息队列实现在没有应用程序级帮助的情况下处理此问题。确保所有QuickFIX消息都可以传递给对方(http://permalink.gmane.org/gmane.comp.finance.quickfix.devel/169)。

    与我的理解相反, A ExecutionReport日志中没有显示QuickFIX,或重新连接时,导致不知道其先前的订单已被取消。我注意到由于sendRaw(Message message, int num)Session的{​​{1}}方法的以下源代码,因此未发生日志记录:

    QuickFIX/J

    在为断开连接启动的取消生成/** * 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的消息队列在这种情况下的行为如何?它是否应该对消息进行排队,等待会话在将来再次可用时发送,还是在会话结束时停止排队?

3 个答案:

答案 0 :(得分: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)实际存储邮件以供稍后传递。

据我所知,所有邮件都会排队,直到会话成功登录。

答案 1 :(得分:0)

这是我的10美分:当QF / J保证基于序列号和间隙填充的活动会话的消息传递...

如果会话丢失,则无法保证任何内容。一旦发现序列号不匹配,您需要做的是将启动器和接受器配置为重新连接时的间隙填充。嗯,您的ResetOnDisconnect标志在配置中说了什么? ResetOnLogout怎么样?

我认为在QF中等待会话的消息“队列”并不存在,因为会话可以迪斯科并且永远不会重新调整意味着QF队列只是保持填充,或者永远是活跃的,这不是QF将要发生的事情能够为每个人提供开箱即用的服务。

如果您有迪斯科舞厅,也不能使用OnLogout将执行报告发送到断开连接的客户端!首先,OnLogout并不总是在每个迪斯科舞厅上调用,其次正如你所说我们进入QF内部并且它找不到发送消息的会话,所以它除外。我不希望QF内部队列为我处理这种情况。再次,保证传递是在连接是UP时...这是一个依赖。但是,我希望在某处记录它。你的日志配置是什么?

我认为您需要查看原因:“当/恢复活着时,必须将这些ExecutionReports传递给/以某种方式,以便它知道所有先前的订单已被取消。” isn'迪斯科的所有订单都被取消了吗?为什么/需要确认?这是给定的,不是吗?这可能是您必须单独编写QF基础的代码。

答案 2 :(得分:0)

阅读this

有些公司支持35002消息中的标记LOGON(取消时取消),并带有可能的值:

  • 0:不要使用COD
  • 1:仅在发送“优雅”注销时使用COD
  • 2:在任何“网络”断开连接时使用COD
  • 3:1 AND 2

了解您的对手方是否支持此功能。我没有检查过QuickFIX支持,但您可以自己手动添加标记,或自定义FIX字典以支持标记。

显然,高频交易员经常使用它。我不熟悉那个行业,因此在评论部分提出了这个问题。