FIX 4.2 Grammar Defined
In order to bring out syntax features of the FIX message I am defining the FIX grammar. I am
using the ISO-standardized EBNF notation whose description can be found
here. I do this,
however, merely to be succinct and precise and this does not constitute my endorsement for use
of a heavy language analysis apparatus in this case involving language lexer, parser etc.

Two essential remarks before jumping into the FIX grammar:

    1. The equals (=) metasybol is asymmetric and signifies that the left side symbol may
    always be replaced with the right side symbol and, generally, not the other way around.

    2. The FIX message in reality consists of terminal symbols only. That means the higher-
    level constructs data-duo and group are represented in the real message by their
    field-level expansions that in turn expand into field components.

The general FIX message structure consists of a
message-independent framing including
header and trailer, and a message-specific body part. The message type is carried by
field f35 of the header.

    fix-msg  =  header , body , trailer ;

Message header can be defined as a concatenation of fixed beginning and variable ending.

    header = header-fixed-part ,  header-variable-part ;        

The fixed part of the header consists of fields 8, 9 and 35 (
BeginString, BodyLength and
MsgType).

    header-fixed-part = f8 , f9 , f35 ;        

The header-variable-part part consists of 4 mandatory fields (MsgSeqNum,
SenderCompID, SendingTime
and TargetCompID ) and 19 optional nodes (fields or duos) in any
order.
A specific node can only appear once.

   header-variable-part =  
               { header-optional-node }  ,
                 header-variable-mandatory-field  ,
               { header-optional-node }  ,
                 header-variable-mandatory-field  ,
               { header-optional-node }  ,
                 header-variable-mandatory-field  ,
               { header-optional-node }  ,
                 header-variable-mandatory-field  ,
               { header-optional-node }  ;        

   header-variable-mandatory-field =
                 f34  |  f49  |  f52  |  f56  ;

   
header-optional-node =
                 f43   |  f50   |  f57   |  d90   |  d95   |
                 f97   |  f115  |  f116  |  f122  |  f128  |
                 f129  |  f142  |  f143  |  f144  |  f145  |
                 
d212  |  f347  |  f369  |  f370  ;

    where:      d# is a data-duo beginning with tag #.

The message trailer consists of optional Signature data duo and mandatory CheckSum
field.
    trailer = [ d93 ] , f10 ;

The field can be defined as follows:

    field = tag , '=' , value , fix-delimiter ;

    tag = positive-integer ;

    positive-integer = non-zero-digit , { digit } ;

    non-zero-digit = '1' | '2' | '3' | '4' | '5' |
                    '6' | '7' | '8' | '9' ;

    digit = '0' | non-zero-digit ;

There are two kinds of fields that differ in types of values they can accommodate:

    field = ordinary-field | data-field ;   (* redundant *)

    value = ordinary-value | data-value ;

    ordinary-value =
            printable-character , { printable-character } ;

    data-value = any-character , { any-character } ;

    any-character =
            printable-character | non-printable-character ;

The data-field can only be a part of a data-duo defined below and all other fields
are
ordinary-fields defined as following:

    ordinary-field =
           tag , '=' , ordinary-value , fix-delimiter ;

    ordinary-field =
           f8 | f9 | f35 | f34 | f49 | f52 | f56 | f43 |
           f50  | f57  | f97  | f115 | f116 | f122 | f128 |
           f129 | f142 | f143 | f144 | f145 | f347 | f369 |
           f370 | ordinary-body-field | f10 ;

The data-duo node can be rewritten as:

    data-duo = length-field , data-field ;

where the length-field is a subtype of the ordinary-field specialized to carry a
number, the length of data

    ordinary-field = length-field ;        (* redundant *)

    length-field = tag , '=' , length-value, fix-delimiter ;

    length-field = f90 | f95 | f212 |
                  body-defined-length-field | f93 ;

    ordinary-value = length-value ;        (* subtype   *)

    length-value = positive-integer ;

and the data-field carries the value defined above that includes the ordinary-
values:

    data-field = tag , '=' , data-value , fix-delimiter ;

    data-field = d-f91 | d-f96 | d-f213 |
                 body-data-field | d-f89 ;

The following are data-duos known to FIX:

    data-duo = d90 | d95 | d212 | body-data-duo | d93 ;

where:

    d90  = f90  , d-f91  ;
    d95  = f95  , d-f96  ;
    d212 = f212 , d-f213 ;
    d93  = f93  , d-f89  ;

The  fix-delimiter is a non-printable SOH control character of ASCII hex code 01. It
serves as a reliable delimiter when scanning for all
ordinary-values , and it is present
also in
data-fields. In the latter case, however, the data-value cannot be extracted
based on detection of the delimiter and instead the data length pre-specified by the
length-
value
of the preceding length-field must be used. The reason for that is the fact that
data-value
may include the fix-delimiter at any position.

And now, lets consider the grammar of FIX message body. In addition to business nodes
specific to a given message type it may contain some
special-nodes that may be added by
securities exchange and should normally be ignored by the end-user. These are generally some
simple fields used for technical purposes.

    body =  { body-node } ;

    body-node = body-mandatory-node | body-optional-node ;

The message body can be considered a series of nodes. Although, each particular message
has a specific order of
body nodes the order is inconsequential and therefore conceptually the
message
body would be better described as a 'set of nodes'. The nodes are mostly fields but
may also form higher level syntactic constructs such as
data-duo or group called in here
the
compound nodes as opposed to simple field node. The compound nodes have their internal
structure and specific order of their component
nodes. The data-duo has already been
defined above.

The group is a more advanced construct that only can be a part of message body and makes
the FIX syntax more like that of a programming language due to its recursiveness. The
group
may itself consist of other compound nodes including other
groups. The number of group
occurances is specified in the first field of the
group the occurance-count field. The
structure of that field is syntactically identical with the earlier defined
length-field, part of
the
data-duo. Each group occurance must begin with a node designated as a
primary-node. The remainder of group occurance may consist of any permutation of
ordinary-member-node
s any number of which may be mandatory or optional. Neither
the order of
ordinary-member-nodes nor their presence must be consistent in group
occurances.

    body-node = field | data-duo | group ;

    group = occurance-count , occurance , { occurance } ;

    occurance-count =
           tag , '=' , count-value , fix-delimiter ;

    count-value = positive-integer;

    occurance =

       primary-node , { ordinary-member-node } ;

    primary-node = body-node ;

    ordinary-member-node = body-node ;



    Sample structure of a group as defined in message type 'C', e-mail.




















    The sample group with 2 occurances of different lengths ('|' serves as substitute depiction
    of the FIX delimiter).

    33=2|58=First Line Of Text|354=10|355=.a..5.
    |δҗą|58=Second Line Of Text|

    Field names:
    Tag 33 – LinesOfText, Tag 58 – Text, Tag 354 – EncodedTextLen, Tag 355 -
    EncodedText



© 2009, Jerzy "Yorick" Ignaczak