Routing Rules and Session Events: XML Transformation Language

Routing Rules and Session Events: XML Transformation Language

Overview

Routing rules are main elements in FIXEdge configuration file. They contain FIXEdge instructions for:

  • Routing of incoming and outgoing FIX messages (via the correspondence between ClientID and FIX Session).

  • Filtering of incoming and outgoing FIX messages.

  • Transformation of incoming and outgoing FIX messages

More than one rule can be applied to a message. It is also possible to route one message to multiple destinations or to the same destination multiple times. See section 'Cases of Routing Rules' for details. All rules are applied to each FIX message separately (independently) in the order set in the configuration file. Even if a set of transformation actions is applied to messages, the next rule will be applied to the original message. Details are described in the Rule element section.

Session Events are a special kind of business rules that handle events launched during execution. The following FIXEdge events can be processed:

Be careful, while Routing rules mechanism is very flexible, you can even implement loops, and, as a case infinite loops. For example, you create a route message from client "The client" - > "Some another client" - > "The client". And if "The client" is able to process its own message and output is the same or meet the rule above, you will take a risk to get infinite loop. To take more detailed description and ways to avoid such behavior, see the 'BL loops and finite control' section.

Rule element

Element <Rule> is meant to describe one Routing rule. Each <Rule> element consists of 3 sections (XML elements):

Name

Section Description

Name

Section Description

<Source>

Mandatory section. This section defines instructions for primary filtering of messages. <Source> element defines a source from which the FIX message can come. If the message source coincides with the source defined in the section <Source> then the rule will be applied to the message. See part 'Source element' for details.

<Condition>

Optional section. This section contains a set of pre-defined criteria. The application checks FIX messages on the criteria and if the criteria is met the instructions are to be executed; otherwise section <Action> is ignored. See part 'Condition element' for details.

<Action>

Mandatory section. The section denotes the instructions that must be performed when a Rule is being applied to a message. It must contain at least one instruction. See part 'Action element' for details.

<Rule>  element has two attributes:

Attribute

Description

Attribute

Description

Enabled

Optional. Possible values "true" or "false". <Rule Enabled=”false”> disables rule parsing by Business Layer and the rule is not loaded into the memory. By default the attribute value has a "true" value.

Description

Optional. Used for naming of rules

Example:

<Rule Enabled="true" Description="Save order data"> <Source> <!-- Source (FIX session or Transport Client) definition --> </Source> <Condition> <!-- conditions definition --> </Condition> <Action> <!-- actions definition --> </Action> </Rule>

Note: Any XML comments cannot be inside <Rule> structure, only outside the rule. If the formed rules do not meet the syntax requirements, FIXEdge stops loading and records an error message in the log file.

Source element

Source from which the FIX message can come for processing, defines either a FIX Session or a Transport Client (i.e. Transport Adaptor Session) by means of one of 3 variants:

  • by the element FIXSession

Defines FIX session as a source; FIX session is identified either by the pair of attributes "SenderCompID" and "TargetCompID" or by the set of attributes "SenderCompID",  "TargetCompID" and "SessionQualifier".

Example:

<Source> <FixSession SenderCompID="Sender" TargetCompID="Target" SessionQualifier="Q1" /> </Source>

The values of the attributes have to coincide with values defined for properties: FixLayer.FixEngine.Session.<Name>.SenderCompID and FixLayer.FixEngine.Session.<Name>.TargetCompID (and optionally FixLayer.FixEngine.Session.<Name>.SessionQualifierValue) which were configured for FIX Sessions.

  • by the element Client

Defines Transport Client as source; The attribute "name" of the element <Client> is used

Example:

<Source> <Client Name="TestClient"/> </Source>

See also configuring Transport Adaptors (for example: property TransportLayer.SmtpTA.SMTPSessions)

  • by the attribute "Name"

Defines the identifier of FIX session or Transport Client as source; The attribute "name" of the element <Source> is used

Example:

<Source Name="SourceID"/>

Note: It is possible to use the rule for all configured sessions. In this case it is necessary to use pair of symbols ".*" in the attributes' values.

For example:

<!-- Messages from any transport adaptors will be processed --> <Source> <Client Name=".*"/> </Source>   <!-- Messages from any FIX sessions related to TargetCompID="Target" will be processed --> <Source> <FixSession SenderCompID=".*" TargetCompID="Target"/> </Source>

Note: Source identifier has the following restrictions:

  •  

    • The name of source identifier must be unique for each FIX session;

    • The source identifier of TA client must be represented as Client ID;

    • It must contain characters with codes from ASCII [30] to ASCII [128];

    • It must begin with a letter, digit or underlining symbol ‘_’ ;

Whitespace characters in the beginning or in the end of name will be ignored by rule parsing.

Condition element

The <Condition> element is not required for the routing rule. But if the element is required, it may contain several criteria described below in this part.  In fact, each criterion (specified as an XML element) is a function which can be applied to the whole FIX message as well as to particular fields of the FIX message. The function returns "true" or "false". Input variables of this function are defined via XML element's attributes: 'Field', 'Value', etc.  <Condition> is met when all the criteria  (functions) return "true". It means that condition criteria are joined by "AND".

Example:

<Rule> <Source Name=".*"/> <Condition> <!-- set of criteria, criteria are joined by "AND" --> <NotExistField Field="41" /> <MatchField Value="G|AC" Field="35"/> <EqualDestination Value="CME1" Strategy="OrderFlow100"/> </Condition> <Action> <!-- any action ... --> </Action> </Rule>

Condition element extensions

Combine conditions by "OR"

If it is necessary to join several criteria by "OR", another <Condition> element has to be added into the business rule.

Example: Condition 1 and Condition 2 are joined by "OR" 

<Rule Description="Condition: ORed"> <Source> <FixSession SenderCompID="Target42" TargetCompID="Sender42" /> </Source> <Condition> <!-- Condition 1 --> <!-- set of criteria for Condition 1 --> <MsgType> <Val>F</Val> </MsgType> <MsgType> <Val>D</Val> </MsgType> </Condition> <Condition> <!-- Condition 2 --> <FieldLengthGreaterOrEqual Field="55" Length="3" /> </Condition> <Action> <!-- any set of actions --> </Action> </Rule>

The added <Condition> element can be empty, for example:

<Rule Description="Condition: ORed"> <Source> <FixSession SenderCompID="Target42" TargetCompID="Sender42" /> </Source> <Condition> <!-- Condition 1 --> <!-- set of criteria for Condition 1 --> <MsgType> <Val>F</Val> </MsgType> <MsgType> <Val>D</Val> </MsgType> </Condition> <Condition> <!-- Condition 2 --> <FieldLengthGreaterOrEqual Field="55" Length="3" /> </Condition> <Condition/> <!-- Condition 3 is empty --> <Action> <!-- any set of actions --> </Action> </Rule>

Inclusion and Exclusion blocks within Condition element

There are two XML-elements for grouping of criteria (functions) inside the <Condition>: <Inclusion> and <Exclusion>. XML-element <Exclusion> is used in the <Condition> to invert the result of set of criteria specified in the section <Exclusion>. I.e. <Exclusion> is a logical negation.

The element <Exclusion> can be used separately or in combination with <Inclusion>.  The lement <Inclusion> is used for grouping of set of the rest criteria when <Exclusion> is used. Usage of <Inclusion> separately from <Exclusion> is not needed.

<Condition> <Inclusion> <!-- function A "AND" function B --> <A/> <B/> </Inclusion> <Exclusion> <!-- NOT (function C "AND" function D) --> <C/> <D/> </Exclusion> </Condition> <!-- Result = (A AND B) AND NOT (C AND D) -->

Examples:









<Condition> <EqualField Field="35" Value="D"/> </Condition>

Means (35 = “D”)

<Condition> <Inclusion> <EqualField Field="35" Value="D"/> </Inclusion> </Condition>

Means the same as previous example

<Condition> <Exclusion> <EqualField Field="55" Value="MSFT"/> <EqualField Field="40" Value="2"/> </Exclusion> </Condition>

Means NOT(55 = “MSFT” AND 40 = “2”)

  <Condition> <Inclusion> <EqualField Field="35" Value="D"/> </Inclusion> <Exclusion> <EqualField Field="55" Value="MSFT"/> <EqualField Field="40" Value="2"/> </Exclusion> </Condition>

Means (35=”D” AND NOT(55 = “MSFT” AND 40 = “2”))

Functions of Condition element

EqualField

Compares two values as strings and returns "true" when they are equal:

<EqualField Field="35" Value="D" />

Allowed to use a list of values for comparison. In this case xml-element <Val> has to be used, hereinafter "<Val> list". Returns "true" if given 'Field' is equal one of the value from given <Val> list:

<EqualField Field = "35"> <Val>D</Val> <Val>G</Val> <Val>F</Val> </EqualField>

NotEqualField

 Compares two values as strings and returns "true" when they are not equal:

<NotEqualField Field="35" Value="asd"/>

Allowed to use a list of values for comparison. In this case the function returns "true" if the 'Field' is not equal to any value from the given <Val> list:

<NotEqualField Field = "35"> <Val>D</Val> <Val>G</Val> <Val>F</Val> </NotEqualField>

FieldIsLessThan

Compares two values as float numbers and returns "true" when given 'Field' less than 'Value':

<FieldIsLessThan Field="44" Value="100"/>

Absence of the tag defined by “Field” does not cause fail, but returns "false".

FieldIsGreaterThan

Compares two values as float numbers and returns "true" when given 'Field' greater than 'Value':

<FieldIsGreaterThan Field="44" Value="100"/>

Absence of the tag defined by 'Field' does not cause fail, but returns "false".

Note: Both of functions can be used for date comparison. For example:

<FieldIsLessThan Field="60" Value="20121231-10:00:00"/> <FieldIsGreaterThan Field="60" Value="20121231-10:00:00"/>

MatchField

Compares two values treating value as a regular expression and returns "true" when they are equal:

<MatchField Field="35" Value=".*"/>

NotMatchField

 Compares two values as a regular expression and returns "true" when they are not equal:

<NotMatchField Field="35" Value="[1-9]$"/>

Note: It is recommended to use EqualField (NotEqualField) rather than MatchField (NotMatchField), when applicable. Although MatchField is more flexible, it may decrease the performance.

FieldContains

Returns "true" if string value in the given 'Field' contains one of the value from given <Val> list:

<FieldContains Field="18"> <Val>R</Val> <Val>T</Val> </FieldContains>

Optional attribute “Delimiter” can be used to treat the given 'Field' as multi value string. The “Delimiter” attribute contains the delimiter used in multi value string.

<FieldContains Field="58" Delimiter="|"> <Val>R</Val> <Val>T</Val> </FieldContains>

MsgType

Checks the FIX message type (tag = "35") , returns "true" when the current FIX message type is equal to one of the value from given <Val> list:

<MsgType> <Val>D</Val> <Val>G</Val> <Val>F</Val> </MsgType>

Note: Actually this function does the same as the functional EqualField but a bit faster.

FieldIsToday

Returns "true" when 'Field' contains date/time value in UTC and equals to current date:

<FieldIsToday Field = "42"/>

FieldBeginsWith 

Checks if 'Field' begins with one of the substring from given <Val> list from the position that pointed out 'StartPos', and returns "true" when at least one coincidence is exists.

<FieldBeginsWith Field = "11" StartPos= "6" CaseSensitive= "true" <Val>L</Val> <Val>N</Val> <Val>BC</Val> </FieldBeginsWith>

'Field' and 'StartPos' attributes are required. The “StartPos” attribute refers the position within a string from 0.

'CaseSensitive' attribute is implied, default value = "true".

FieldLengthGreaterOrEqual

Returns "true" if the length of the 'Field' greater or equal to the 'Length' attribute. Both attributes are required:

<FieldLengthGreaterOrEqual Field="6780" Length="7"/>

FieldCheckBits

Treats the 'Field' as integer. Returns "true" if the 'Field' contains the HEX value defined by the 'Value' attribute. Bitwise "AND" operation is used within the check:

<FieldCheckBits Field="34" Value="0x02"/>

ExistField

Checks the 'Field' presence in FIX message and returns "true" if it exists:

<ExistField Field="35"/>

Allowed to use <Val> list for checking. Returns "true" when there is at least one field from given <Val> list in the FIX message:

<ExistField> <Val>11</Val> <Val>41</Val> </ExistField>

NotExistField

 Checks the field presence in FIX message, returns "true" if it does not exist:

<NotExistField Field="58"/>

Allowed to use <Val> list for checking. Returns "true" when no any fields from given <Val> list in the FIX message:

<NotExistField> <Val>11</Val> <Val>391</Val> </NotExistField>

MatchMessage

 Applies regular expression in attribute 'Value' to FIX message, returns "true" if regular expression is matched:

<MatchMessage Value=".*?55=10.*?"/>

NotMatchMessage

 Applies regular expression in attribute 'Value' to FIX message, returns "true" if regular expression is not matched:

<NotMatchMessage Value=".*?55=test_1.*?"/>

IsSessionActive

Checks is the FIX Session Established, returns "true" if FIX Session is established:

<IsSessionActive Name="SESSION_NAME"/>

EqualDestination

Locates FIX message destination session according to the specified automatic routing strategy and returns "true" when the located destination session is equal to the one specified in action:

<EqualDestination Strategy="OrderFlowStrategy100" Value="Client"/>

NotEqualDestination

Locates FIX message destination session according to the specified automatic routing strategy and returns "true" when the located destination session is not equal to the one specified in action:

<NotEqualDestination Strategy="OrderFlowStrategy100" Value="Client"/>

MatchDestination

 Locates FIX message destination session according to the specified automatic routing strategy and returns "true" when the located destination session is matched to the specified pattern: 

<MatchDestination Strategy="OrderFlowStrategy100" Value="FIXSession.*"/>

NotMatchDestination 

Locates FIX message destination session according to the specified automatic routing strategy and returns "true" when the located destination session is not matched to the specified pattern:

<NotMatchDestination Strategy="OrderFlowStrategy100" Value="FIXSession.*"/>

Script

This function is used when the criterion cannot be described via existed functions. 

Applies JavaScript condition to the FIX message:

<Script Language="JavaScript" FileName ="testScript.js"/>

 

<!ELEMENT Script (Param)* > <!ATTLIST Script Language (Javascript | XSLT) #REQUIRED Field CDATA #IMPLIED LengthField CDATA #IMPLIED FileName CDATA #REQUIRED >

Detailed information can be found here: How to use JavaScript as a condition or action in the Business Rule

LDAPAuthenticate

Tries to login on LDAP server with given user/password and returns "true" if succeed otherwise "false". Can be used, for example, to authenticate a session via LDAP.

Please note: this condition is supported only in Linux, openldap package is required

Available starting FIXEdge 5.10

<Condition> <LDAPAuthenticate URL="ldaps://ldapserver.domain.com:636" TemplateDN="cn=%USER%,dc=my-domain,dc=com" UserField="553" PasswordField="554" /> </Condition>

where

XML Attrubute

Required/
default value

Description

XML Attrubute

Required/
default value

Description

URL

required

LDAP server URL

TemplateDN

required

Template of LDAP Distinguished Name to bind to.
The %USER% mark will be replaced with contents of UserField

UserField

"553"

User tag

PasswordField

"554"

Password tag

Action element

The section denotes instructions (as XML elements) that must be performed when a Rule is being applied to a message. <Action> is a required section and must contain at least one of the instructions described below. Each instruction is a command executed with the given message. Before applying the instructions, the FixEdge creates a copy of the initial FIX message, and the instructions are applied to this copy of the FIX message.

The instructions are applied to the copy sequentially, in order set in <Action> element. If the copy of the FIX message was transformed by the one instruction, the next instruction is applied to the changed message. So, the copy of the FIX message can be transformed step by step by applying the instructions, and then the transformed message can be sent to the required destination.

If the instruction (command) cannot be executed then the error will occur.

ActionIfTrue and ActionIfFalse elements

<ActionIfTrue> and <ActionIfFalse> xml-elements can be used instead of <Action> section. These elements allow user to define the processing of incoming message when <Condition> = true as well as when <Condition> = false:

<Rule> <Source> <!-- ... --> </Source> <Condition> <EqualField Field="35" Value="D"/> </Condition> <Action> <SetField Field="50" Value="Updated_message"/> <CopyField SourceField="49" TargetField="9999" IsRequiredField="Y"/> </Action> </Rule>

Using <Action> element:

Instructions in <Action> section will be applied to FIX message only when <Condition>=true

<Rule> <Source> <!-- ... --> </Source> <Condition> <EqualField Field="35" Value="D"/> </Condition> <ActionIfTrue> <SetField Field="50" Value="Updated_message"/> <CopyField SourceField="49" TargetField="9999" IsRequiredField="Y"/> </ActionIfTrue> </Rule>

Using <ActionIfTrue> element:

It means the same as using <Action> element in the previous example.  

<Rule> <Source> <!-- ... --> </Source> <Condition> <EqualField Field="35" Value="D"/> </Condition> <ActionIfTrue> <SetField Field="50" Value="Updated_message"/> <CopyField SourceField="49" TargetField="9999" IsRequiredField="Y"/> </ActionIfTrue> <ActionIfFalse> <CopyField SourceField="56" TargetField="49" IsRequiredField="Y"/> <MoveField SourceField="9999" TargetField="56"/> </ActionIfFalse> </Rule>

Using <ActionIfTrue> and <ActionIfFalse> jointly:

Instructions in <ActionIfTrue> section will be applied to FIX message when <Condition>=true.

When <Condition>=false the instructions in <ActionIfFalse> section will be applied to FIX message

<Rule> <Source> <!-- ... --> </Source> <Condition> <EqualField Field="35" Value="D"/> </Condition> <ActionIfFalse> <CopyField SourceField="56" TargetField="49" IsRequiredField="Y"/> <MoveField SourceField="9999" TargetField="56"/> </ActionIfFalse> </Rule>

Using <ActionIfFalse> element:

Only one <ActionIfFalse> block is also allowed

Session instructions

StartSession

Executes sync FIX session create/connect by means of one of 3 variants:

  • by SenderCompID/TargetCompID which are taken from routed message:

    <StartSession />
  • by specified SenderCompID/TargetCompID:

    <StartSession SenderCompID="Sender" TargetCompID="Target" />
  • by specified SenderCompID/TargetCompID/SessionQualifier :

    <StartSession SenderCompID="Sender" TargetCompID="Target" SessionQualifier="Q1" />
  • by the session name:

    <StartSession Name="SESSION_NAME" />

DisconnectSession

Executes async FIX session disconnect:

  • by SenderCompID/TargetCompID which are taken from routed message:

    <DisconnectSession Reason="Manual disconnect" />
  • by specified SenderCompID/TargetCompID:

     <DisconnectSession SenderCompID="Sender" TargetCompID="Target" Reason="Manual disconnect" />
  • by the session name:

    <DisconnectSession Name="SESSION_NAME" Reason="Manual disconnect" />

TerminateSession

Executes async FIX session terminate:

  • by SenderCompID/TargetCompID which are taken from routed message:

    <TerminateSession Reason="Manual disconnect" />
  • by specified SenderCompID/TargetCompID:

     <TerminateSession SenderCompID="Sender" TargetCompID="Target" Reason="Manual disconnect" />
  • by the session name

    <TerminateSession Name="SESSION_NAME" Reason="Manual disconnect" />

Note please:

  1. The session will not be visible in FIXICC or manageable (start, disconnect, etc) from FIXICC/BL/JS/scheduler.

  2. The termination and the disconnection occur with async way after rule completion. In case of fail <OnRuleFailEvent> will be called.

Sending instructions

Send

Sends a  FIX message to a specified destination. Destination, like the <Source> element, can define  FIX Session or a Transport Client (i.e. Transport Adaptor Session) by means of one of 3 variants:

FixSession is identified by SenderCompID and TargetCompID pair or by SenderCompID/TargetCompID/SessionQualifier set. If parameter is not specified, it is taken from corresponding tag of the routed message:

<Send><FixSession SenderCompID="Sender" TargetCompID="Target"/></Send>

<Send><FixSession SenderCompID="Sender" </Send> <!—TargetCompID is taken from Tag56 -->

<Send><FixSession TargetCompID="Target"/></Send> <!—SenderCompID is taken from Tag49 -->

<Send><FixSession /></Send> <!—SenderCompID is taken from Tag49, TargetCompID is taken from Tag56 -->

<Send> <Client Name="TestClient"/> </Send>
  • by the attribute "Name" (for FIX Sessions only!)

<Send Name="TestClient" />

SystemCommand

Executes system command or script.

Executed only together with next Send action. Receives FIX message as input, output FIX message should be stored to the sysCmdOut__05311141284571.msg file in the bin directory. The file is temporary and will be removed after the action completed.

<SystemCommand Command="runSystemCommand.bat"/> <Send> <!-- ... --> </Send>

StrategySend

Applies a specified automatic routing strategy to the handled message, locates a destination session and sends the message to the required session:

<StrategySend Name="OrderFlowStrategy100"/>

See Routing strategies description for details.

Instructions for modifying Fields 

SetField

Assigns the given 'Value' to a specified 'Field'. If the 'Field' is not present in a FIX message, it is created with given value:

<SetField Field="50" Value="Ordinary Sender SubID"/>

CopyField

Copies the value from 'SourceField' to 'TargetField'. If the 'TargetField' is not present in a FIX message, it is created with given value. "CopyField" action can have several attributes:

Attribute

Required

Valid Values

Default Value

Description

Attribute

Required

Valid Values

Default Value

Description

IsRequiredField

N

Y / N

N

  • If IsRequiredField="Y", it means that the 'SourceField' has to be present in a FIX message:

    <CopyField SourceField="55" TargetField="58" IsRequiredField="Y"/>
  • If IsRequiredField="N", it means that the 'SourceField' is not necessary, and, when 'SourceField' is not present the required value has to be set in attribute 'DefaultValue'

    <CopyField SourceField="55" TargetField="58" DefaultValue="N"/>

DefaultValue

N

-

-

To be specified in case "IsRequiredField" is set to "N"

Method

N

  • UTCToLocalDate

  • Trim

  • toNanosecPrecision

  • toMicrosecPrecision

  • toMillisecPrecision

  • toSecPrecision

Precision methods are available since FIXEdge 6.2.0

-

The optional attribute 'Method' is used for specifying of conversion during copying:

  1. If Method="UTCToLocalDate", it means that the conversion from UTC time to LocalDate will be performed:

    <CopyField SourceField="126" TargetField="432" Method="UTCToLocalDate"/>
  2. If Method="Trim", it means that spaces and tabs from 'SourceField' has to be trimmed before copying:

    <CopyField SourceField="18" TargetField="18" Method="Trim"/>
  3. Below are methods which are used in order to transmit the messages from the session with one timestamp precision to the session with another timestamp precision in a proper way:

  4.  

    1. If Method="toNanosecPrecision", it means that the conversion from any other timestamp precision to nanosecond precision (e.g. YYYYMMDD-HH:MM:SS.sssssssss) will be performed:

      <CopyField SourceField="52" TargetField="52" Method="toNanosecPrecision"/>
    2. If Method="toMicrosecPrecision", it means that the conversion from any other timestamp precision to microsecond precision (e.g. YYYYMMDD-HH:MM:SS.ssssss) will be performed:

      <CopyField SourceField="60" TargetField="60" Method="toMicrosecPrecision"/>
    3. If Method="toMillisecPrecision", it means that the conversion from any other timestamp precision to millisecond precision (e.g. YYYYMMDD-HH:MM:SS.sss) will be performed:

      <CopyField SourceField="52" TargetField="52" Method="toMillisecPrecision"/>
    4. If Method="toSecPrecision", it means that the conversion from any other timestamp precision to second precision (e.g. YYYYMMDD-HH:MM:SS) will be performed:

      <CopyField SourceField="60" TargetField="60" Method="toSecPrecision"/>

Note that precision methods are intended to be applied to the tags which contain timestamp values (i.e. which have the formats UTCTimestamp , UTCTimeonly , TZTimestamp , TZTimeOnly). It is not recommended to use them with any other type of fields.



MoveField

Moves the value from  'SourceField' to 'TargetField'. If the 'TargetField' is not present in a message, it is created with given value.

<MoveField SourceField="50" TargetField="53"/>

RemoveField