Search code examples
c#quickfixquickfixn

QuickFix/n - Custom fields inside Logon


I'm trying to create an initiator based on QuickFix/n. My counterpart (server) demand the logon message to carry two custom fields.I already added those to the Data Dictionary, in the Fields as well as in the Logon message. In the code i can manipulate the message to add the username and password, but i can't find how to load custom fields.

Here are some excerpts from what i've done so far:

TradeClientApp.cs

...

public void ToAdmin(Message message, SessionID sessionID)
        {
            QuickFix.SessionSettings settings = new QuickFix.SessionSettings("./initiator.cfg");
            List<SessionID> sids = settings.GetSessions().ToList();
            Dictionary settingsDict = settings.Get(sids.First());
            var appName = settingsDict.GetString("ApplicationName");
            var userType = settingsDict.GetString("UserType");

            if (message.GetType() == typeof(QuickFix.FIX44.Logon))
            {
                message.SetField(new Username("USERNAME"));
                message.SetField(new Password("PASSWORD"));
                message.SetField(new QuickFix.Fields.ResetSeqNumFlag(true));

                //tag 9933
                message.SetField(new RawData(string.Format($"9933={appName}")));
                //tag 20110
                message.SetField(new RawData(string.Format($"20110={userType}")));

            }
        }

The initiator.cfg file:

[DEFAULT]
UseDataDictionary=Y
DataDictionary=./spec/FIX44.xml
FileStorePath=store
FileLogPath=log
ConnectionType=initiator
ReconnectInterval=60

[SESSION]
BeginString=FIX.4.4
SenderCompID=USERNAME
ResetSeqNumFlag=Y
Username=USERNAME
Password=PASSWORD
TargetCompID=TARGETCOMPID
StartTime=12:30:00
EndTime=23:30:00
HeartBtInt=10
ApplicationName=app-name
UserType=V
SocketConnectPort=446
SocketConnectHost=SERVERHOST

Inside the FIX44.XML

<message name="Logon" msgtype="A" msgcat="admin">
      <field name="EncryptMethod" required="Y" />
      <field name="HeartBtInt" required="Y" />
      <field name="RawDataLength" required="N" />
      <field name="RawData" required="N" />
      <field name="ResetSeqNumFlag" required="N" />
      <field name="NextExpectedMsgSeqNum" required="N" />
      <field name="MaxMessageSize" required="N" />
      <group name="NoMsgTypes" required="N">
        <field name="RefMsgType" required="N" />
        <field name="MsgDirection" required="N" />
      </group>
      <field name="TestMessageIndicator" required="N" />
      <field name="Username" required="N" />
      <field name="Password" required="N" />
      <field name="ApplicationName" required="N" />
      <field name="UserType" required="N" />
    </message>

 <fields>
   ...

   <field number="9933" name="ApplicationName" type="STRING"/>
   <field number="20110" name="UserType" type="STRING" />
 </fields>
</fix>

When i try to connect i get this log:

<outgoing> 8=FIX.4.49=12035=A34=149=USERNAME52=20191008-21:19:41.49856=TARGETCOMPID96=20110=V98=0108=10141=Y553=USERNAME554=PASSWORD10=097

Using the RawData as shown in my example, the message carries 20110=V as RawData, which is tag 96, which doesn't help me. I already tried inside ToAdmin:

message.Header.SetField(new StringField(QuickFix.Fields.Tags.UserType, ""));

or

message.SetField(new QuickFix.Fields.UserType(true));

but neither work.

How on earth do you add custom fields to the logon message?


Solution

  • I think you are getting the RawData data type wrong. That is literally meant for raw data, not for Strings that follow the default encoding.

    From the spec:

    string field containing raw data with no format or content restrictions. Data fields are always immediately preceded by a length field. The length field should specify the number of bytes of the value of the data field (up to but not including the terminating SOH).

    I am not so familiar with the C# implementation of QuickFIX but you should simply be able to add these fields with the specific tag number, e.g.

    message.SetField(new StringField(20110, "V"));
    

    I hope there are no syntax errors, but you should get the idea.

    Edit: I see you are manually setting the ResetSeqNum field on the Logon message. This is discouraged. quickFIX/n should deal with this when you set ResetSeqNum=Y in the settings (you already have that setting).