FIX Protocol Customization and ValidationFIX Antenna .NET Programmer's Guide

In this chapter we will describe approaches developers can use to customize the structure of FIX messages to meet specific business requirements.

User Defined Fields

If your application can use standard message types, provided by FIX Protocol specifications, but requires several additional fields, we suggest you to use user defined fields.

Custom tags can be added by using numbers in the range 5000-9999 for industry-wide solutions or greater then 10000 for solutions used internally in your company. See FIX Messages.

int theCustomTag = 5000; // reserved for User Defined Fields

// create a new message
FixMessage msg = FixMessage.Create(FixVersion.FIX44, "D");

msg.SetField(theCustomTag , "0.15"); // set the tag's value
Console.WriteLine("msg: " + msg);

If you use Decorators (see Using Decorators) the code to access user defined fields will be exactly the same, because SetField and GetField methods were implemented in the base StructuredMessage class with the same semantics, that they have in com.b2bits.FIXAntennaFixMessage class.

Note Note

User defined fields in the range 5000-9999 are published on official site here

User Defined Messages

User defined messages are messages of the type starting with "U-". By using them one can create completely custom application-level message classes.

FIX Antenna makes no difference between user defined messages and standard FIX messages. You can work with both of them using the same com.b2bits.FIXAntennaFixMessage class. In user defined messages you can use standard tags, repeating groups and user defined fields.

You will not be able to use any of existing Decorators for user defined messages, but you may implement your own decorator class inherited from StructuredMessage

See an example of using user-defined messages below

// create new skel of the message
FixMessage msg = FixMessage.Create( FixVersion.FIX44, "U-MyMsg" );

// set other required fields
msg.SetField( Tag.Symbol, "symbol" );
msg.SetField( Tag.Side, "1" );
msg.SetField( Tag.TimeInForce, "0" );
msg.SetField( Tag.HandlInst, "1" );
msg.SetField( Tag.OrderQty, 10 );
msg.SetField( Tag.OrdType, "1" );
msg.SetField( Tag.TransactTime, "20060101-10:00:00" );

// user defined field
msg.SetField( 5000, "12345" );

// serialize object to FIX string
Console.WriteLine( msg.ToString() );
Note Note

In order to let your user messages to pass FIX validation, you need to describe user defined massages in the file, reffered by the Validation.AdditionalFieldsFileName configuration property, see next chapter for more details.

Validating User Defined Fields and User Defined Message Types

You can not only add new user defined fields and messages, as was described above, but also validate them in the same way that is used for standard fields validation.

Use the Validation.AdditionalFieldsFileName property in file to define the path to the XML file that describes schema of user defined fields and messages.

Note Note

If Validation.AdditionalFieldsFileName is not set, or not all user-defined fields or message types are specified in XML file, an attempt to send or receive fix messages using this fields or types will cause validation errors. You can switch off validation by setting MessageMustBeValidated = false parameter in FixEngine's configuration file

. However, setting MessageMustBeValidated = false is not recommended in production environment and should be used for debugging purposes only.

Below is an example of XML file that describes additional fields. For a more complex example, please open ICE sample application, and find additional.xml file.

<?xml version="1.0" encoding="UTF-8"?>
        <fixdic fixversion="4.4" title="ICE Trade Capture FIX 4.4" date="20090306">

                <!-- simple user defined field  -->
                <fielddef tag="9403" name="OptionsSymbol" type="String"/>

                <!-- change validation of standard field by defining a list of possible values  -->
        <fielddef tag="447" name="PartyIDSource" type="char">
                    <item val="1">Broker/trader trading for own account</item>
                    <item val="2">Broker/trader trading for house or prop account</item>
                    <item val="3">Broker/trader trading for the account ofanother broker/trader </item>
                    <item val="4"> Broker/trader trading for any other customer's account that does not have direct
                            trading access.</item>
                    <item val="S">Segregated</item>
                    <item val="N"> Non-segregated</item>
                    <item val="H">House</item>
                    <item val="L">Local</item>
                    <item val="D">Default</item>
                    <item val="A">Allocated</item>
                    <item val="*">Split</item>
                    <item val="U">Unassigned</item>
                    <item val="G">Gas associate</item>
                    <item val="C">Customer</item>

                <!-- user defined field that should be validated against a list of possible values  -->
                <fielddef tag="9200" name="StripType" type="int">
                    <item val="0">Hourly</item>
                    <item val="1">Spot</item>
                    <item val="2">Same Day</item>
                    <item val="3">Within Day</item>
                    <item val="4">Next Day</item>
                    <item val="5">Day Ahead</item>
                    <item val="6">Bal Week</item>
                    <item val="7">Next Saturday</item>
                    <item val="8">Next Sunday</item>
                    <item val="9">Weekend</item>
                    <item val="10">Next Week</item>
                    <item val="11">Bal Month</item>
                    <item val="12">Month</item>
                    <item val="13">Custom</item>
                    <item val="14">Period</item>
                    <item val="15">Quarter</item>
                    <item val="16">Year</item>
                    <item val="17">Spread</item>
                    <item val="18">Cash</item>
                    <item val="19">Bal Quarter</item>
                    <item val="20">Bal Year</item>
                    <item val="22">Half Month</item>
                    <item val="22">Today</item>
                    <item val="23">Tplus</item>
                    <item val="24">Yesterday</item>
                    <item val="25">Bundle</item>
                    <item val="100">Rolling</item>

                <!-- change validation rules of standard message  -->
        <msgdef msgtype="AE" name="Trade Capture Report">
                    <field tag="487" req="Y"/>
                    <field tag="828" req="N"/>
                    <field tag="17" req="Y"/>
                    <field tag="9403" req="N"/>
                    <field tag="9018" req="Y"/>
                    <field tag="9022" req="Y"/>
                    <field tag="552" req="N"/>
                    <group nofield="552" startfield="54">
                        <field tag="453" req="N"/>
                        <group nofield="453" startfield="448">
                            <field tag="447" req="N"/>
                            <field tag="452" req="N"/>

                    <field tag="555" req="N"/>
                    <group nofield="555" startfield="600">
                        <field tag="9019" req="N"/>
                        <field tag="9023" req="N"/>
                        <field tag="9020" req="N"/>
                        <field tag="9021" req="N"/>
                        <field tag="538" req="N"/>
                        <group nofield="538" startfield="524">
                            <field tag="525" req="N"/>
                            <field tag="538" req="N"/>



         <!-- new user-defined message type  -->
        <msgdef msgtype="U-MyMsg" name="My user defined message">
                    <field tag="487" req="Y"/>
                    <field tag="828" req="N"/>
                    <field tag="17" req="Y"/>
                    <field tag="9403" req="N"/>
                    <field tag="552" req="N"/>

Note Note

In the previous versions of FixAntenna, Validation.AdditionalFields was used to define all additional fields in one line

This syntax was not convenient, especially when you need to support many user defined fields and repeating groups.

# This parameter is obsolete - the Validation.AdditionalFieldsFileName should be used instead.
Validation.AdditionalFields = FIX42:Ug:6146(6311,6308);FIX42:8:639?,204?;FIX44:r:534(528?,5001?);FIX42:i:232(233,234?),232=>539(524,525?);FIX44:i:296=>295(423?,218?,220?,221?,222?,662?,663?,699?,761?,63?,30028?),296=>295=>232(233,234?),296=>295=>539(524,525?,538?,804?)

In the current version Validation.AdditionalFields is considered obsolete; one should use Validation.AdditionalFieldsFileName instead.

See Also

Other Resources