Below is a step-by-step explanation of how a dictionary can be defined, using the XML-based description that is used by C++ FIX Engine. For a complete reference of the definition capabilities, take a look at dictionaries definition XML schema.
Enhancing Message with New Field
To add a new field to a FIX Message, add the corresponding <Field>
entity to the description of the FIX message in the dictionaries descriptions file.
- Note
- Inclusion of
<Field>
element, for the already registered (e.g. standard) field or Group, causes OnixS C++ FIX Engine to overwrite its attribute. In this way, existing field attributes can be modified. This behavior allows to make a mandatory field or group to be optional, and vice versa.
Separately, the same approach gives the opportunity to replace existing FIX repeating groups with regular fields, and vice versa.
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 xmlns=
"https://ref.onixs.biz/fix/dialects" 4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation=
"https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.18.xsd">
10 <
Field tag=
"526" name=
"SecondaryClOrdID" isRequired=
"true"/>
12 <
Field tag=
"21" name=
"HandlInst" isRequired=
"false"/>
Enhancing Message with Repeating Group
To add a new repeating group to a FIX message, add the corresponding <Group>
entity to the FIX dictionary description file. The same approach is used to add new fields into an existing repeating group.
- Note
- In the case of a new group definition, the first field (subgroup) will be used as a leading tag (tag which separates repeating groups entries). If the current definition describes changes to an existing group, then the original leading tag remains operative.
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 xmlns=
"https://ref.onixs.biz/fix/dialects" 4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation=
"https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.18.xsd">
10 <
Group numberOfInstancesTag=
"78" name=
"NoAllocs">
11 <
Field tag=
"79" name=
"AllocAccount"/>
12 <
Field tag=
"661" name=
"AllocAcctIDSource"/>
13 <
Field tag=
"736" name=
"AllocSettlCurrency"/>
Adding Definition of New Message
To define a custom (user-defined) message, add the corresponding <Message>
entity to the FIX dictionary description. Such a user-defined message can be used exactly the same way as the standard FIX Message.
- Note
- OnixS C++ FIX Engine allows to send and receive unknown messages by manipulating validation settings. However, defining custom messages, using the dictionaries definitions, has important benefits:
- OnixS C++ FIX Engine doesn't differentiate between messages, defined using custom FIX dictionaries definitions, from messages, defined by the FIX Protocol. It gives the opportunity to use a strict message validation to check the correctness of incoming and outgoing messages.
- Using custom dictionaries definitions allows to manipulation of messages of the same complexity, as messages, defined by the Standard and in the same way. This includes messages with repeating groups of an arbitrary nesting level.
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 xmlns=
"https://ref.onixs.biz/fix/dialects" 4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation=
"https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.18.xsd">
8 <
Message type=
"UserDefinedMessage_1">
9 <
Field tag=
"100" isRequired=
"true"/>
In code:
Message udm_1("UserDefinedMessage_1", ProtocolVersion::FIX_40);
udm_1.set(100, "Field 100")
.set(101, "Field 101");
udm_1.validate();
std::clog << "UDM: " << udm_1 << std::endl;
Removing Fields, Repeating Groups and Messages
As it was noted previously, the presence of field definition in a dictionary description file substitutes any entity of the same tag number, which is already available in the message, or in an outer repeating group. In such a way, repeating groups can be replaced with regular fields, and vice versa. However, sometimes there's a need to completely exclude a certain field and/or repeating group from a message or another repeating group. Moreover, sometimes it's necessary to completely exclude a certain message from the usage. To satisfy the needs, a dictionary description language offers mode
attribute which allows removing a single field, a repeating group or even the entire message from the dictionary. To achieve the results, "remove"
value must be specified for this attribute in corresponding dictionary entity like <Field>
, <Group>
and <Message>
.
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 xmlns=
"https://ref.onixs.biz/fix/dialects" 4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation=
"https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.18.xsd">
11 <
Field tag=
"14" mode=
"remove"/>
14 <
Group numberOfInstancesTag=
"136" mode=
"remove"/>
18 <
Message type=
"E" mode=
"remove"/>
Overriding Existent Definitions of a Standard FIX Dictionary
A standard FIX dictionary can be overridden using the mode
attribute . Once override
mode is defined for the either FIX version, FIX Engine will replace the entire definition of FIX version with the new one.
In this case, the FIX Dictionary will contain the described application-level messages only. For example, the description of the FIX Dictionary with id="Custom_FIX_5.0" below will not contain any application-level messages at all.
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 <
FIX version=
"5.0" mode=
"override" id=
"Custom_FIX_5.0">
Overriding Existent Definitions of Messages and Repeating Groups
With the help of mode
attribute fields, it can be removed from repeating groups and messages. However, it's often necessary to completely redefine the structure of the message and/or repeating group. Removing standard fields and repeating groups on a one-by-one basis doesn't sound like a simple way to achieve the results. In addition to syntax overhead, this way supposes the knowledge of message and/or repeating group structure. Therefore, to simplify the task, a dictionary description language offers "override"
value for the previously noted mode attribute. Once an override mode is defined for either a message or a repeating group, FIX Engine will replace the entire definition of the message or the repeating group with a new one. In such a case, the message and/or the repeating group will consist only of fields and inner repeating groups, defined by the description.
- Note
- Once the repeating group is overridden, its leading tag will be changed in the same manner, as if it's a newly defined group. That is the first field, defined within the overridden group, will be considered as the leading one.
-
Message overriding doesn't affect a basic message structure. That is all fields, from the standard message header and trailer (like a field which defines the type of message), remain untouched. Therefore, there's no need to include definitions for all such fields, when completely overriding structure of the existent message.
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 xmlns=
"https://ref.onixs.biz/fix/dialects" 4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation=
"https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.18.xsd">
10 <
Message type=
"7" mode=
"override">
11 <
Field tag=
"58" name=
"Text" isRequired=
"true"/>
16 <
Group numberOfInstancesTag=
"555" name=
"NoLegs" mode=
"override">
- Warning
- If the append mode is used and if the declared element has been already presented in the description of the message, it will be removed from its current position and added to the end of the message.
For example, if the standard definition of a message is as follows:
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
And a user has defined their custom definition of this message as follows:
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
The result message definition will be as follows:
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
In order to control tags order, you need to create a custom dictionary and describe all tags in a Message or Repeating group in the necessary order with the override mode.
Using Component Block
You can use the <Component>
entity to describe common components in order to use it in all necessary messages. There is a need to add the name
attribute by which you can identify a particular component and use it in all necessary messages. Component Block can contain <Field>
, <Group>
and even other <Component>
entities. When a Component Block occurs in a message description, all described fields from this component are considered as fields directly described in this message.
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 xmlns=
"https://ref.onixs.biz/fix/dialects" 4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation=
"https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.18.xsd">
10 <
Component name=
"Header">
11 <
Field tag=
"8" name=
"BeginString" isRequired=
"true" />
12 <
Field tag=
"9" name=
"BodyLength" isRequired=
"true" />
13 <
Field tag=
"35" name=
"MsgType" isRequired=
"true" />
14 <
Field tag=
"49" name=
"SenderCompID" isRequired=
"true" />
15 <
Field tag=
"56" name=
"TargetCompID" isRequired=
"true" />
16 <
Field tag=
"115" name=
"OnBehalfOfCompID" />
17 <
Field tag=
"128" name=
"DeliverToCompID" />
18 <
Field tag=
"90" name=
"SecureDataLen" />
19 <
Field tag=
"91" name=
"SecureData" />
20 <
Field tag=
"34" name=
"MsgSeqNum" isRequired=
"true" />
21 <
Field tag=
"50" name=
"SenderSubID" />
22 <
Field tag=
"57" name=
"TargetSubID" />
23 <
Field tag=
"116" name=
"OnBehalfOfSubID" />
24 <
Field tag=
"129" name=
"DeliverToSubID" />
25 <
Field tag=
"43" name=
"PossDupFlag" />
26 <
Field tag=
"97" name=
"PossResend" />
27 <
Field tag=
"52" name=
"SendingTime" isRequired=
"true" />
28 <
Field tag=
"122" name=
"OrigSendingTime" />
32 <
Component name=
"Trailer">
33 <
Field tag=
"93" name=
"SignatureLength" />
34 <
Field tag=
"89" name=
"Signature" />
35 <
Field tag=
"10" name=
"CheckSum" isRequired=
"true" />
40 <
Component name=
"Header" />
41 <
Field tag=
"98" name=
"EncryptMethod" isRequired=
"true" />
42 <
Field tag=
"108" name=
"HeartBtInt" isRequired=
"true" />
43 <
Field tag=
"95" name=
"RawDataLength" />
44 <
Field tag=
"96" name=
"RawData" />
46 <
Component name=
"Trailer" />
- Note
- The
<Component>
entity can have the "isRequired" attribute. When this attribute is true
(by default), all "isRequired" attributes of child nodes (<Field>
, <Group>
, <Component>
) are processed as usual depending on their values. When this attribute is false
, all "isRequired" attributes of child nodes (<Field>
, <Group>
, <Component>
) are ignored, and all child nodes become non-required.
FIX Dictionary Description Example
An example of a custom FIX Dictionary description file:
1 <?
xml version=
"1.0" encoding=
"utf-8"?>
3 xmlns=
"https://ref.onixs.biz/fix/dialects" 4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation=
"https://ref.onixs.biz/fix/dialects https://ref.onixs.biz/fix/dialects/dialects-2.18.xsd">
11 <
Field tag=
"64" name=
"FutSettDate"/>
15 <
Group numberOfInstancesTag=
"146" name=
"NoRelatedSym">
17 <
Field tag=
"64" isRequired=
"true" name=
"FutSettDate"/>
23 <
FIX version=
"4.3" id=
"ForTradeWithNewXMessage">
25 <
Field tag=
"55" name=
"Symbol"/>
26 <
Field tag=
"64" name=
"FutSettDate"/>
34 <
Message type=
"D" mode=
"override">
35 <
Field tag=
"54" name=
"Side" isRequired=
"true"/>
36 <
Field tag=
"55" name=
"Symbol" isRequired=
"true"/>
37 <
Field tag=
"53" name=
"Quantity" isRequired=
"true"/>
41 <
Message type=
"E" mode=
"remove"/>
45 <
Field tag=
"14" mode=
"remove"/>