繁体   English   中英

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

[英]Message queue behavior in QuickFIX/J for disconnected clients

我想阐明在以下情况下QuickFIX/J (FIX 4.2)的行为。 QuickFIX/J通讯涉及两方:

  1. 客户端启动器,称为I。
  2. 我们公司的接受方程序称为A。

登录到A时 ,它们交换标记为35=A FIX消息。 建立连接后, 开始提交订单。 可能有但是一个点,在那里意外断开,此时A决定发送取消所有的所有的的未结订单的(这是有效 ,因为不知道为什么失败了,或者当活着回来)。

请注意,整个断开时取消过程都是由A单独启动和处理的-它是从AonLogout(...)方法启动的,并由其常规订单管理机制处理。 对于I的每个未结订单,将生成一条35=F消息,并且在每次成功取消时都将生成ExecutionReport35=8 )。

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

但是,与我的理解相反, AQuickFIX日志中未显示ExecutionReport也没有在重新连接时将其发送给 ,导致不知道其先前的订单已被取消。 我注意到由于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的消息队列在这种情况下应如何表现? 它是否应该对消息进行排队,是等待会话在将来再次可用时发送,还是在会话关闭时在整个持续时间内停止排队?

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) ,该存储实际上存储了消息,以便在未连接会话时稍后传递。

据我所知,所有消息都将排队,直到会话成功登录。

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

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

我认为在QF中没有消息等待队列中的消息,因为会话可能会出现迪斯科舞厅,并且从不侦察,这意味着QF队列一直处于填充状态或一直处于活动状态,这不是QF能够做到的开箱即用。

如果您有迪斯科舞厅,那么您都不能使用OnLogout将执行报告发送到断开连接的客户端! 首先,并非总是在每个迪斯科中都调用OnLogout,其次,正如您所说,我们进入了QF内部,它找不到会话向其发送消息,因此除外。 我不希望QF内部队列为我处理这种情况。 同样,保证的传送是在连接建立时进行的……这是一个依赖项。 不过,我希望它在某处被记录下来。 您的日志记录配置是什么?

我认为您需要查看原因: “当/重新恢复运行时,必须将这些ExecutionReports发送到/以某种方式,以便它知道以前的所有订单都已取消。” 是不是整个过程都比迪斯科舞会的所有订单都被取消了? 为什么/需要确认? 这是既定的,不是吗? 这可能是您必须单独对QF基础进行编码的内容。

阅读

某些公司在LOGON消息中支持标记35002 (断开时取消),其值可能为:

  • 0:请勿使用COD
  • 1:仅在发送“正常”注销时使用COD
  • 2:在任何“网络”断开连接上使用COD
  • 3:1和2

找出对方是否支持。 我尚未检查QuickFIX支持,但您始终可以自己手动添加标签,也可以自定义FIX词典以支持该标签。

显然,这是高频交易者经常使用的。 我对该行业不熟悉,因此在评论部分提出了问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM