How to send a FIX message with custom tag ordering?

  Kiến thức lập trình

The order request is sent on FIX server and the order of tags is changed.

What if I wanted output for the sequence as it is arranged by me (and not getting modified by the server).

public void send50(Order order) {

    quickfix.fix50sp1.NewOrderSingle newOrderSingle = new quickfix.fix50sp1.NewOrderSingle(new ClOrdID(order.getID()),
            sideToFIXSide(order.getSide()), new TransactTime(), typeToFIXType(order.getType()));
    newOrderSingle.set(new OrderQty(order.getQuantity()));
    newOrderSingle.set(new Symbol(order.getSymbol()));
    newOrderSingle.set(new Price(order.getSharePrice()));
    newOrderSingle.set(new Account("13501100"));
    newOrderSingle.setField(new NoPartyIDs(1));
    newOrderSingle.setField(new PartyIDSource('C'));
    newOrderSingle.setField(new PartyRole(12));
    newOrderSingle.setField(new PartyID("13501100"));**

This is the sequence given by the user to the server and it is arranged by the server as:


So what can be done if I wanted the output in the same sequence which is sent?


Grant and TT are correct in stating that actually FIX does not mandate a specific tag (or field) ordering except inside repeating groups.
However, there are some counterparties which require a specific field ordering in the message body.

When setting fields on a message, QuickFIX/J arranges the tags in the order as they appear in the data dictionary. This is because the code for a specific message type is generated from the data dictionary on compile time.

If you wanted to change this ordering there are two possibilities.

  1. Change the data dictionary and recompile QuickFIX/J. Instructions are here: build instructions

  2. Extend the general Message, specify the tag ordering and pass it to the super constructor. See below for example code.
    NOTE: Thinking further about this I realized that there is a downside to this approach. In the case of the event that your side needs to resend messages, then the messages from the store are parsed using the configured data dictionary and message factory for that session. I.e. you will probably end up using the field ordering from the data dictionary / generated code again.
    So to sum this up: option 1 is the clean approach but requires rebuilding QuickFIX/J.

And a general note: please note that you don’t have to add the repeating group count (NoPartyIDs in your code) by yourself. This is done by QuickFIX/J when you add a group to the message.

Example code:

    public void testCustomFieldOrder() {

        final int[] FIELD_ORDER = {38, 55, 44, 1};
        final int[] PARTY_GROUP_ORDER = {447, 452, 448, 0};

        class MyNewOrderSingle extends quickfix.fix50sp1.Message {

            public static final String MSGTYPE = "D";

            public MyNewOrderSingle() {
                getHeader().setField(new quickfix.field.MsgType(MSGTYPE));


        class MyPartyGroup extends Group {

            public MyPartyGroup() {
                super(453, 447, PARTY_GROUP_ORDER);


        quickfix.fix50sp1.NewOrderSingle nos1 = new quickfix.fix50sp1.NewOrderSingle();
        nos1.setString(38, "1000");
        nos1.setString(55, "SYM");
        nos1.setString(44, "1");
        nos1.setString(1, "ACCOUNT");
        nos1.setString(100, "XETR");
        quickfix.fix50sp1.NewOrderSingle.NoPartyIDs group1 = new quickfix.fix50sp1.NewOrderSingle.NoPartyIDs();
        group1.setString(447, "C");
        group1.setString(452, "12");
        group1.setString(448, "PARTYID");

        System.out.println("orig   " + nos1.toString().replace('01', '|'));

        MyNewOrderSingle nos2 = new MyNewOrderSingle();
        nos2.setString(38, "1000");
        nos2.setString(55, "SYM");
        nos2.setString(44, "1");
        nos2.setString(1, "ACCOUNT");
        nos2.setString(100, "XETR");

        MyPartyGroup group2 = new MyPartyGroup();
        group2.setString(447, "C");
        group2.setString(452, "12");
        group2.setString(448, "PARTYID");

        System.out.println("custom " + nos2.toString().replace('01', '|'));



orig   8=FIXT.1.1|9=75|35=D|1=ACCOUNT|38=1000|44=1|55=SYM|100=XETR|453=1|448=PARTYID|447=C|452=12|10=014|
custom 8=FIXT.1.1|9=75|35=D|38=1000|55=SYM|44=1|1=ACCOUNT|100=XETR|453=1|447=C|452=12|448=PARTYID|10=014|