QuickFixJ 2.2.0 FIX44客户端仅接收MarketDataSnapshotFullRefresh部分数据
我之前帮人排查过类似的QuickFixJ重复组解析问题,结合你提供的日志和代码,给你几个针对性的解决思路:
1. 确认FIX数据字典的重复组配置
QuickFixJ依赖数据字典来解析重复组(比如NoMDEntries(268)对应的MDEntry条目组),如果字典里的MarketDataSnapshotFullRefresh消息没有正确定义这个组,就会导致后续条目被丢弃,甚至NoMDEntries的值被错误覆盖。
打开你使用的FIX44.xml字典文件,检查MarketDataSnapshotFullRefresh节点下是否包含正确的重复组定义:
<message name="MarketDataSnapshotFullRefresh" msgtype="W" msgcat="app"> <!-- 其他必填字段定义 --> <group name="NoMDEntries" required="Y"> <field name="MDEntryType" required="Y"/> <field name="MDEntryPx" required="N"/> <field name="MDEntrySize" required="N"/> <field name="MDEntryDate" required="N"/> <!-- 其他MDEntry组内字段 --> </group> </message>
如果缺失这个组定义,或者组内字段配置不全,就会导致解析异常。
2. 确保会话配置了正确的数据字典
检查你的SessionSettings配置文件,确认会话指定了正确的字典路径:
[SESSION] # 替换为你的FIX44.xml实际路径 DataDictionary=resources/FIX44.xml
如果没有配置DataDictionary项,或者路径错误,QuickFixJ会使用内置的默认字典,而默认字典可能不包含完整的重复组定义,导致解析失败。
3. 升级QuickFixJ版本
你使用的quickfix-all 2.2.0是非常老旧的版本(发布于2010年左右),这个版本存在已知的重复组解析bug。建议升级到较新的稳定版本,比如2.3.0或者更高版本,这些版本修复了很多老版本的组解析问题。
在Maven中修改依赖:
<dependency> <groupId>org.quickfixj</groupId> <artifactId>quickfixj-all</artifactId> <version>2.3.0</version> </dependency>
4. 临时手动解析重复组(应急方案)
如果暂时无法升级版本或修改字典,可以在fromApp方法中绕过自动crack,手动解析重复组:
@Override public void fromApp(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType { String msgType = message.getString(MsgType.FIELD); if (MsgType.MARKET_DATA_SNAPSHOT_FULL_REFRESH.equals(msgType)) { // 手动获取原始的NoMDEntries值 int actualEntryCount = message.getInt(NoMDEntries.FIELD); logger.info("原始消息中的条目数:{}", actualEntryCount); // 定义MDEntry组结构 Group mdEntryGroup = new Group(NoMDEntries.FIELD, MDEntryType.FIELD); // 遍历所有条目(QuickFixJ组索引从1开始) for (int i = 1; i <= actualEntryCount; i++) { message.getGroup(i, mdEntryGroup); String entryType = mdEntryGroup.getString(MDEntryType.FIELD); double entryPx = mdEntryGroup.getDouble(MDEntryPx.FIELD); long entrySize = mdEntryGroup.getLong(MDEntrySize.FIELD); logger.info("条目{}: 类型={}, 价格={}, 数量={}", i, entryType, entryPx, entrySize); // 这里添加你的业务处理逻辑 } } else { // 其他消息类型继续使用自动crack crack(message, sessionID); } }
这个方法可以绕过自动解析的问题,但只是临时方案,还是建议优先解决字典或版本问题。
5. 验证原始消息的合规性
虽然从日志看原始消息格式正常,但可以再确认每个MDEntry组的字段是否符合FIX44规范,比如是否缺失MDEntryType这类必填字段。不过从你提供的日志来看,这个可能性较低。
内容的提问来源于stack exchange,提问作者Totoro

