How to route session level rejects through the FIXEdge

Solution overview

The diagram shows a configuration in which FIXEdge is a router between Client and Exchange. 

FIXEdge works with two sessions:

  1. Client <-> FIXEdge (FIX session 1) 
  2. FIXEdge <-> Exchange (FIX session 2)

Expected message flow: messages from the Client are routed to the Exchange and messages from the Exchange are routed back to the Client.
Sequences in such sessions FIX session 1 and FIX session 2 don't match. If the Exchange rejects a message from the client with session Reject (35=3), the Client often wants to get information about the rejected message. However, the value from RefSeqNum (45) tag doesn't refer to the original message from FIX Session 1.
As session-level messages aren't routed by BL rules, additional processing of session level Reject (35=3) is required to pass information about a rejected message back to the sender.

The following example shows how to use BL Rules and JavaScript to achieve it.

BL Rules configuration

Session level Rejects (35=3) trigger OnSessionLevelRejectEvent action on BL.

In OnSessionLevelRejectEvent action can be called a JavaScript preparing a reject message for sending to the required session. In this case, it is SENDER

  <!-- Rules for messages routing -->
  <Rule Description="Route messages from SENDER to REPORTER">
    <FixSession SenderCompID="SENDER" TargetCompID=".*"/>
     <FixSession SenderCompID="FIXEDGE" TargetCompID="REPORTER"/>
  <Rule Description="Route messages from REPORTER to SENDER">
    <FixSession SenderCompID="REPORTER" TargetCompID=".*"/>
     <FixSession SenderCompID="FIXEDGE" TargetCompID="SENDER"/>

  <!-- Rules for rejects routing -->
    <FixSession SenderCompID="REPORTER" TargetCompID=".*"/>
    <Script Language="JavaScript" FileName ="../FIXEdge1/conf/enrichReject.js"/>
     <FixSession SenderCompID="FIXEDGE" TargetCompID="SENDER"/>



The JavaScript does the following:

1. Stores all data from the original reject to some variables

2. Gets rejected message from the session logs with getMsgBySeqNum(<SenderCompId>, <TargetCompId> , <SeqNum>) function.

3. Serializes to the text serializeMessage(<tagDelimiter>)

4. Creates new reject message again with transform(<target protocol>, <target message type> )

5. Fills stored data from #1

6. Adds information about the rejected message. In this example Text (58) tag is used for it.

The message is ready. It will be sent to the session later.

// getting information from reject;
var RefSeqNum = new Number(getNumField(45));
RefMsgType = getStringField(372);
Text = getStringField(58);
RefTagID = getNumField(371); // Session Reject (35=3) only
SessionRejectReason = getNumField(373); // Session Reject (35=3) only
//getting rejected message from the storage.
sender = getStringField(56); // Get SenderCompId as TragetCompId in Reject message
target = getStringField(49); // Get TragetCompId as SenderCompId in Reject message
n = Number(RefSeqNum); // convering RefSeqNum to integer from JSVAL
getMsgBySeqNum(sender, target, n);
msg = serializeMessage("|"); // convert rejected message to plaintext.
// prepare reject and fill it with information from original one
transform("FIX.4.4", "3");
if (RefSeqNum != null) 
    setNumField(45, Number(RefSeqNum));
if (RefMsgType != null) 
    setStringField(372, RefMsgType);
if (RefTagID != null) 
    setNumField(371, Number(RefTagID));
if (SessionRejectReason != null) 
    setNumField(373, Number(SessionRejectReason));

// add information about rejected message to Text (58) field.
if (Text == null) {
    Text = "";
Text = Text + "   Original message:" + msg;
setStringField(58, Text);

SENDER session can get information about the rejected message from the Text (58) field:

Message example

Sent message: 


Received SessionLevelReject message:

8=FIX.4.4|9=245|35=3|49=FIXCLIENT|56=FIXEdge|34=4|52=20180412-09:49:37.738|45=4|371=452|372=D|373=6|58=Field value '122' does not meet ValBlock dictionary conditions in tag 452[Group tag=453, Entry #=1] in message New Order - Single (D) with sequence number 4.|10=210|