You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:23:18