请求Security List时fromApp函数接收消息不完整的技术求助
问题:Security List消息解析不一致
请求Security List时出现数据丢失问题:日志中记录的完整入站FIX消息包含10条证券条目,但fromApp函数仅接收到不含具体证券信息的简化消息,无法正确解析数据。
日志中的完整入站消息
<20230329-09:37:52, FIXT.1.1:ECO->XTRM, incoming> (8=FIXT.1.19=00274135=y49=XTRM56=ECO34=245452=20230329-09:37:50.971347=UTF-8320=293202393750642322=2b7e5fb5-9a04-42fd-938a-09a7981c1f5e560=0393=3481301=XNSA1300=OTC893=N146=1048=PHAMDEKRIGHT22=9955=PHARMA DEKO RIGHTS454=1455=NGRGT0000089456=4167=CS762=OTC224=20150220225=20141217106=PHARMDEKO-I107=PHARMA DEKO RIGHTS1205=11206=01208=0.01000001150=1.8000000562=11140=015=NRA235=CLOSE236=0696=201502020697=048=OANDORGHT22=9955=OANDO RIGHTS454=1455=NGRGT0000071456=4167=CS762=OTC224=20150203225=20141124106=OANDO-I107=OANDO RIGHTS1205=11206=01208=0.01000001150=16.5000000562=11140=015=NRA235=CLOSE236=0696=20150203697=048=MEYERIGHTS22=9955=MEYER PLC RIGHTS454=1455=NGRGT0000121456=4167=CS762=OTC106=MEYER-I107=MEYER PLC RIGHTS1205=11206=01208=0.01000001150=0.7500000562=11140=015=NRA235=CLOSE236=0697=048=RR2019SOVREN22=9955=SOVEREIGN TRUST INSURANCE PLC RIGHTS 2019454=1455=NG2019SOVRE6456=4167=CS762=OTC224=20190807225=20190528106=SOVRENINS-I107=SOVEREIGN TRUST INSURANCE PLC RIGHTS 20191205=11206=01208=0.01000001150=0.0100000562=11140=015=NRA235=CLOSE236=0696=20190807697=048=RR2019WAPIC22=9955=WAPIC INSURANCE PLCS 2019 RIGHT454=1455=NGRR2019WAP1456=4167=CS762=OTC224=20200117106=WAPIC-I107=WAPIC INSURANCE PLCS 2019 RIGHT1205=11206=01208=0.01000001150=0.0100000562=11140=015=NRA235=CLOSE236=0696=20200117697=048=RR2020ABBEY22=9955=ABBEY MORTGAGE BANK PLC 2020 RIGHT454=1455=NGRR2020ABB3456=4167=CS762=OTC224=20210217106=ABBEYBDS-I107=ABBEY MORTGAGE BANK PLC 2020 RIGHT1205=11206=01208=0.01000001150=0.2300000562=11140=015=NRA235=CLOSE236=0696=20210217697=048=RR2020UPDC22=9955=UACN PROPERTY DEVELOPMENT CO. PLC-RIGHTS454=1455=NGRR2020UPD7456=4167=CS762=OTC224=20200318106=UAC-PROP-I107=UACN PROPERTY DEVELOPMENT CO. PLC-RIGHTS1205=11206=01208=0.01000001150=0.0100000562=11140=015=NRA235=CLOSE236=0696=20200318697=048=RR2018WAPCO22=9955=LAFARGE RIGHTS 2018454=1455=NGRR18WAPCO0456=4167=CS762=OTC224=20190201225=20181217106=WAPCO-I107=LAFARGE RIGHTS 20181205=11206=01208=0.01000001150=0.0100000562=11140=015=NRA235=CLOSE236=0696=20190201697=048=RR2019CILEAS22=9955=C&I LEASING PLC 2019 RIGHT454=1455=NGRR2019CIL5456=4167=CS762=OTC224=20200117106=CILEASING-I107=C&I LEASING PLC 2019 RIGHT1205=11206=01208=0.01000001150=0.6000000562=11140=015=NRA235=CLOSE236=0696=20200117697=048=RR2019FIDSON22=9955=FIDSON HEALTHCARE RIGHTS 2019454=1455=NG2019FIDSO0456=4167=CS762=OTC224=20190415225=20190305106=FIDSON-I107=FIDSON HEALTHCARE RIGHTS 20191205=11206=01208=0.01000001150=0.9500000562=11140=015=NRA235=CLOSE236=0696=20190415697=010=253)
fromApp函数中接收的消息
8=FIXT.1.19=17035=y34=245149=XTRM52=20230329-09:37:50.96956=ECO347=UTF-8146=10320=293202393750642322=022b739f-702c-4462-9c90-c0035175e0d6393=348560=0893=N1300=ETF1301=XNSA10=214
相关Java代码
public void fromApp(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType { try { log.info("track1 :: On from App........Message received is: " + message); if (message.getHeader().getString(MsgType.FIELD).equals(MsgType.MARKET_DATA_SNAPSHOT_FULL_REFRESH) || message.getHeader().getString(MsgType.FIELD).equals(MsgType.MARKET_DATA_INCREMENTAL_REFRESH)) { log.warning("Feed Recieved ... " + message.toString()); new Thread(new OnNGXFIXFeed(message, sessionID)).start(); } if(message.getHeader().getString(MsgType.FIELD).equals(MsgType.SECURITY_LIST)) { log.warning("Security List : "); onSecurityListResponse(message); } if (message.getHeader().getString(MsgType.FIELD).equals(MsgType.SECURITY_DEFINITION)) { log.warning("Security Definition Message ... " + message.toString()); onSecurityRequest(message); requestSymbolFeed(); } } }
解决方案
这个问题的核心是QuickFIX/J未主动在toString()中输出重复组(NoRelatedSym,Tag146)内容,但实际数据已被解析到消息对象中,需通过API手动提取。
1. 确认FIX数据字典配置
确保会话配置文件中指定了正确的DataDictionary,且字典包含SecurityList的重复组定义:
[SESSION] DataDictionary=path/to/FIXT11.xml
字典中SecurityList的定义需包含:
<message name="SecurityList" msgtype="y" msgcat="app"> <field name="SecurityReqID" required="Y"/> <field name="SecurityResponseID" required="Y"/> <field name="SecurityRequestResult" required="Y"/> <field name="NoRelatedSym" required="Y"> <component name="RelatedSym"/> </field> </message>
2. 手动提取重复组数据
修改onSecurityListResponse方法,通过QuickFIX/J的Group API提取证券数据:
private void onSecurityListResponse(Message message) throws FieldNotFound { int securityCount = message.getInt(NoRelatedSym.FIELD); log.info("共收到{}条证券数据", securityCount); Group relatedSymGroup = new Group(NoRelatedSym.FIELD, Symbol.FIELD); for (int i = 1; i <= securityCount; i++) { message.getGroup(i, relatedSymGroup); // 提取需要的字段 String symbol = relatedSymGroup.getString(Symbol.FIELD); String securityName = relatedSymGroup.getString(SecurityName.FIELD); String securityID = relatedSymGroup.getString(SecurityID.FIELD); log.info("第{}条证券:代码={},名称={},ID={}", i, symbol, securityName, securityID); // 业务逻辑处理... } }
3. 验证会话配置
检查会话设置中未禁用字段验证:
[SESSION] ValidateFieldsHaveValues=Y ValidateUserDefinedFields=N
4. 调试优化
如需查看完整原始消息,可在fromApp中打印原始字节:
log.info("原始消息内容:{}", new String(message.getRawData()));
内容的提问来源于stack exchange,提问作者Ahmed Decode
相关产品推荐
相关产品推荐

