通过QuickFixJ向Bloomberg发送X报文时报缺少instrument_MarketData组件错误
问题原因
你的代码存在三处核心错误,直接导致彭博端报文校验失败:
- 字段归属错误:你混淆了FIX协议不同层级的字段归属规则:
279(MDUpdateAction)、269(MDEntryType)、270(MDEntryPx)是NoMDEntries分组下的直接字段,不属于Instrument组件,你将这些字段填入Instrument对象,会导致报价分组缺少必填交易字段,同时Instrument组件本身没有填入正确的证券标识。48(SecurityID)、22(IDSource)是Instrument组件的专属字段,你直接将其填到MDIncGrp根层级,不会被识别为Instrument组件的内容,这就是报错提示NULL component instrument_MarketData的直接原因。
- 对象复用错误:你复用了同一个
Instrument和NoMDEntries对象,Java中对象为引用传递,两次addGroup实际添加的是同一个对象的最后修改值,会导致第一条报价数据被覆盖。 - 多余的组件封装逻辑:手动构造
MDIncGrp属于多余操作,QuickFixJ会自动根据添加的NoMDEntries分组生成对应组件和计数字段,手动封装反而容易出现字段位置错误。
修复方案
代码修改示例
/** * 构造彭博市场数据增量刷新报文 * @param marketPrice 行情数据对象 * */ public MarketDataIncrementalRefresh createMarketDataIncrementalRefresh(MarketPrice marketPrice) { quickfix.fix50sp2.MarketDataIncrementalRefresh message = new MarketDataIncrementalRefresh(); // 填充头部自定义字段 message.getHeader().setString(1022, "****"); // 构造共用的Instrument组件,填入证券标识 Instrument instrument = new Instrument(); instrument.setString(48, marketPrice.getCUSIP()); instrument.setString(22, "1"); // 构造买价报价分组 quickfix.fix50sp2.MarketDataIncrementalRefresh.NoMDEntries bidGroup = new quickfix.fix50sp2.MarketDataIncrementalRefresh.NoMDEntries(); bidGroup.setString(279, "0"); // 增量更新动作:新增 bidGroup.setString(269, "0"); // 报价类型:买价 bidGroup.setString(270, marketPrice.getBid_kech().toString()); bidGroup.set(instrument); // 填入证券组件 message.addGroup(bidGroup); // 构造卖价报价分组 quickfix.fix50sp2.MarketDataIncrementalRefresh.NoMDEntries askGroup = new quickfix.fix50sp2.MarketDataIncrementalRefresh.NoMDEntries(); askGroup.setString(279, "0"); askGroup.setString(269, "1"); // 报价类型:卖价 askGroup.setString(270, marketPrice.getAsk_kech().toString()); askGroup.set(instrument); message.addGroup(askGroup); return message; }
字典适配说明
你必须使用彭博提供的专属FIX数据字典,不能直接用官方默认的FIX50SP2字典:
- 彭博的FIX接口有自定义的字段、组件规则、字段顺序要求,默认字典和彭博规则不匹配会导致报文校验失败。
- 你可以从彭博开发者平台下载对应版本的FIX XML字典文件,用QuickFixJ的代码生成工具重新生成适配彭博规范的消息类,同时在QuickFixJ的配置文件中指定使用该自定义字典。
内容的提问来源于stack exchange,提问作者user16806803
相关产品推荐
相关产品推荐

