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:
- Client <-> FIXEdge (FIX session 1)
- 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
<FIXEdge> <BusinessLayer> <!-- Rules for messages routing --> <Rule Description="Route messages from SENDER to REPORTER"> <Source> <FixSession SenderCompID="SENDER" TargetCompID=".*"/> </Source> <Action> <Send> <FixSession SenderCompID="FIXEDGE" TargetCompID="REPORTER"/> </Send> </Action> </Rule> <Rule Description="Route messages from REPORTER to SENDER"> <Source> <FixSession SenderCompID="REPORTER" TargetCompID=".*"/> </Source> <Action> <Send> <FixSession SenderCompID="FIXEDGE" TargetCompID="SENDER"/> </Send> </Action> </Rule> <!-- Rules for rejects routing --> <OnSessionLevelRejectEvent> <Source> <FixSession SenderCompID="REPORTER" TargetCompID=".*"/> </Source> <Action> <Script Language="JavaScript" FileName ="../FIXEdge1/conf/enrichReject.js"/> <Send> <FixSession SenderCompID="FIXEDGE" TargetCompID="SENDER"/> </Send> </Action> </OnSessionLevelRejectEvent> <DefaultRule> <Action> <DoNothing/> </Action> </DefaultRule> </BusinessLayer> </FIXEdge>
JavaScript
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:
8=FIX.4.4|9=209|35=D|49=FIXEdge|56=FIXCLIENT|34=4|52=20180412-09:49:37.737|11=E2017000000000000000001|453=3|448=TestValue1|447=D|452=11|448=TestValue2|447=D|452=122|448=XYZT|447=D|452=17|1=EPAM-TEST|55=USD/CNH|15=USD|58=TEXT|10=078|
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|