如何使用QuickFix/n调整FIX消息中的标签顺序?
QuickFix/n v1.10.0 自定义消息字段顺序实现方案
你修改数据字典无效的核心原因是:QuickFix/n的强类型消息(比如FIX44.NewOrderSingle)序列化逻辑是编译时固定的,不依赖运行时加载的数据字典。下面是几个可行的实现方式:
方案1:重写强类型消息的Serialize方法(最可靠)
针对需要自定义顺序的消息类型,直接继承原消息类并重写Serialize方法,手动控制字段输出顺序。
示例(以NewOrderSingle为例):
public class CustomNewOrderSingle : QuickFix.FIX44.NewOrderSingle { public override void Serialize(QuickFix.IAppender appender) { // 严格按客户要求的顺序写入字段 AppendFieldIfPresent(appender, QuickFix.Fields.Tags.ClOrdID); AppendFieldIfPresent(appender, QuickFix.Fields.Tags.Symbol); AppendFieldIfPresent(appender, QuickFix.Fields.Tags.Side); AppendFieldIfPresent(appender, QuickFix.Fields.Tags.OrderQty); AppendFieldIfPresent(appender, QuickFix.Fields.Tags.OrdType); // 继续添加其他需要的字段,必填字段务必包含 } // 封装工具方法,避免空字段报错 private void AppendFieldIfPresent(QuickFix.IAppender appender, int tag) { if (IsSetField(tag)) appender.AppendField(GetField(tag)); } }
使用时直接实例化自定义类:
var customOrder = new CustomNewOrderSingle(); customOrder.SetField(new QuickFix.Fields.ClOrdID("ORD-001")); customOrder.SetField(new QuickFix.Fields.Symbol("AAPL")); // 设置其他字段... initiator.Send(customOrder);
方案2:动态消息结合字典字段顺序(适合临时场景)
如果是动态创建的消息(非强类型),可以通过字典获取指定顺序并强制应用:
// 加载对应版本的数据字典 var fixDict = new QuickFix.DataDictionary.DataDictionary("FIX44.xml"); // 创建动态消息 var dynamicMsg = new QuickFix.Message(); dynamicMsg.Header.SetField(new QuickFix.Fields.BeginString("FIX.4.4")); dynamicMsg.Header.SetField(new QuickFix.Fields.MsgType("D")); // 设置消息字段 dynamicMsg.SetField(new QuickFix.Fields.ClOrdID("ORD-002")); dynamicMsg.SetField(new QuickFix.Fields.Symbol("MSFT")); // 强制按字典定义的顺序序列化 dynamicMsg.SetFieldOrder(fixDict.GetMessageFields("D")); initiator.Send(dynamicMsg);
方案3:自定义消息工厂(全局生效)
如果需要所有消息都遵循自定义顺序,可以替换默认消息工厂,全局注入顺序逻辑:
public class CustomOrderedMessageFactory : QuickFix.DefaultMessageFactory { private readonly Dictionary<string, QuickFix.DataDictionary.DataDictionary> _dictCache = new(); public override QuickFix.Message Create(string beginString, string msgType) { var msg = base.Create(beginString, msgType); // 加载对应版本的字典(缓存避免重复加载) if (!_dictCache.TryGetValue(beginString, out var dict)) { dict = new QuickFix.DataDictionary.DataDictionary($"{beginString}.xml"); _dictCache[beginString] = dict; } // 对指定消息类型应用自定义顺序 if (msgType == "D" || msgType == "8") // NewOrderSingle、ExecutionReport等 { msg.SetFieldOrder(dict.GetMessageFields(msgType)); } return msg; } }
然后在初始化Initiator时指定自定义工厂:
var sessionSettings = new QuickFix.SessionSettings("initiator.cfg"); var customFactory = new CustomOrderedMessageFactory(); var initiator = new QuickFix.Transport.SocketInitiator( yourApplication, yourMessageStoreFactory, sessionSettings, customFactory );
内容的提问来源于stack exchange,提问作者Dušan
相关产品推荐
相关产品推荐

