OnixS C++ FIX Engine  4.11.0
API Documentation
Dictionary-independent FAST coding and decoding

This section describes a dictionary-independent mode of FAST encoder and decoders.

Understanding of dictionary-independent mode

Examples of usage

Preparing FAST-template to use within dictionary-independent mode

Understanding of dictionary-independent mode

Following notes are belonged to FAST decoder (OnixS::FIX::FAST::Decoder class), but all the same considerations are applicable to FAST Encoder (OnixS::FIX::FAST::Encoder) and Event-Based FAST Decoder (OnixS::FIX::FAST::EventBasedDecoder).

Normally initialization of FAST decoder needs to prepare two XML files: the FAST template itself and FIX dictionary. The first one describes the rules, which are applied to binary data, and the second one describes the allowed structures of messages. Each message consists of fields and each field has literal ("name") and numeric ("id" or "tag") attributes attached. These attributes are defined in the mentioned XMLs:

Here is an important point: each name has to be mapped to the unique number and vice versa. That's why it is possible to retrieve the name by the numeric id and numeric id by the name.

The dictionary-independent mode is an approach where only a single XML document has to be used, that is the FAST template itself. The FIX dictionary becomes generated on the base of the FAST template content and particular FIX protocol version, which is used as a "base dictionary". Since standard FIX protocol descriptions are incorporated within the FIX Engine, this approach significantly simplifies the usage of the FAST decoder. Also, a generated dictionary usually works slightly faster than the separately defined one. A user should prepare just a proper FAST template (see Preparing FAST-template to use within dictionary-independent mode) and have to specify the correct version of the base FIX protocol (FIX 4.4, FIX 5.0 SP1, etc.). It is possible to omit the choice of the FIX protocol, but note, that FIX 4.0 will be used by default, that in turn could affect on compatibility between FIX-messages, retrieved from decoder, and FIX-messages, provided by a particular provider. The base dictionary defines how the resulted FIX message will be exposed in string representation, and which representations could be successfully parsed. In particular, this affects the value of tag 8: "8=FIX4.4" for FIX 4.4, "8=FIXT.1.1" for FIX 5.0 and above, etc. That's why the base protocol has to be chosen carefully.

Identifier of the generated FIX dictionary will be created within one of two ways:

The generated dictionary is accessible after the creation of appropriate FAST tool using fixDictionary() method. It is possible to retrieve the identifier of the dictionary and use it to subsequent initialization of OnixS::FIX::Dictionary instances.

These approaches are illustrated in the next section.

Examples of usage

Following snippets illustrates the usage of the OnixS::FIX::FAST::Decoder class but all the same considerations are applicable to OnixS::FIX::FAST::Encoder and OnixS::FIX::FAST::EventBasedDecoder. Instructions of the Engine initializations are omitted also.

Create the decoder in the simplest way, using FIX 4.0 as a base dictionary:

using namespace OnixS::FIX::FAST;
using namespace OnixS::FIX::FAST;
std::string fastDecodingTemplates = readEntireFastTemplateAsSingleString("mytemplate.xml");
bool decodeEachMessageIndependently = true;
Decoder decoder(fastDecodingTemplates, decodeEachMessageIndependently, inputDataTraits); // FIX40 is specified implicitly

Create the decoder using a particular FIX version (FIX 5.0) as a base dictionary:

using namespace OnixS::FIX;
using namespace OnixS::FIX::FAST;
std::string fastDecodingTemplates = readEntireFastTemplateAsSingleString("mytemplate.xml");
bool decodeEachMessageIndependently = true;
Decoder decoder(version, fastDecodingTemplates, decodeEachMessageIndependently, inputDataTraits);

Create the decoder, using a particular FIX version (FIX 5.0) as a base dictionary, and providing custom dictionary name:

using namespace OnixS::FIX;
using namespace OnixS::FIX::FAST;
std::string fastDecodingTemplates = readEntireFastTemplateAsSingleString("mytemplate.xml");
bool decodeEachMessageIndependently = true;
std::string customDictionaryId = "MyDictionary_50";
Decoder decoder(version, fastDecodingTemplates, customDictionaryId, decodeEachMessageIndependently, inputDataTraits);

Accessing the generated dictionary and recreating it in a separate context:

std::string generatedDictionaryId; //Assume global variable
using namespace OnixS::FIX;
using namespace OnixS::FIX::FAST;
std::string fastDecodingTemplates = readEntireFastTemplateAsSingleString("mytemplate.xml");
bool decodeEachMessageIndependently = true;
Decoder decoder(version, fastDecodingTemplates, decodeEachMessageIndependently, inputDataTraits);
generatedDictionaryId = decoder.fixDictionary().id();
// ...
// That is exactly the same dictionary as it was used for decoder.
// It is correspond to mytemplate.xml content and FIX 5.0 base version.
Dictionary dictionary(generatedDictionaryId.c_str());

Preparing FAST-template to use within dictionary-independent mode

The FAST template should satisfy the following requirements:

  1. Each field definition should contain both attributes: "id" and "name". In particular, cases "id" could be missed, if a corresponding name is present within the chosen base dictionary.
  2. It is possible to have several definitions for the single message type, but a particular name should specify a simple field or sequence of all occurrences. A field type, a FAST operator and other parts of the FAST specification have no matter.
CorrectWrong
<template id="100" name="Msg1">
    <int32 name="Price" id="5200"><copy/></int32>
    <int32 name="Amount" id="5201"/>
</template>

<template id="105" name="Msg2">
    <decimal name="Price" id="5200"><default/></decimal>
    <int32 name="Amount" id="5201"><delta/></int32>
</template>
<!– Template with simple fields –>
<template id="100" name="Msg1">
    <int32 name="NoProducts" id="5300"><copy/></int32>
    <string name="Products" id="5301"><copy/></string>
</template>

<!– Template with sequence –>
<template id="105" name="Msg2">
    <sequence name="Products" id="5301">
        <length name="NoProducts" id="5300">
    </sequence>
</template>