Page tree
Skip to end of metadata
Go to start of metadata

Overview

In some cases, it's needed to create several sessions with the same SenderCompId/TargetCompId pair. Starting from version 6.5.0 of FIXEdge an extra string identifier called SessionQualifier has been introduced in addition to SenderCompId/TargetCompId pair to distinguish between such sessions.

To establish several sessions with the same SenderCompId and TargetCompId, both Initiator and Acceptor should create several session objects which differ from each other by SessionQualifier property. SessionQualifier property on Initiator side must be the same as SessionQualifier property of the corresponding session on acceptor side. When Initiator connects to Acceptor, it sends SessionQualifier along with SenderCompId and TargetCompId in Logon message. The SessionQualifier tag in Logon message is optional and can be configured in FIXEdge.properties file. When Acceptor receives Logon message with the SessionQualifier it searches for registered session with SessionId corresponding to received TargetCompId, SenderCompId and SessionQualifier. If the session is found it is associated with the incoming connection, otherwise connection is rejected.

If user creates session by passing only SenderCompId and TargetCompId parameters (without SessionQualifier), the SessionId structure is created and stored internally with empty qualifier_ property. If Acceptor registers a session without SessionQualifier it won't accept any incoming connection with SessionQualifier defined in logon message. And vice versa, if Acceptor has registered a session or several sessions with qualifiers, it won't accept connections from Initiators without SessionQualifier.

If Acceptor application doesn't use FIX Antenna library it may define its own rules on how to determine correspondence between sessions on Initiator and Acceptor side. For example, it may distinguish sessions based on TCP port which they are connected to. In this case, passing SessionQualifier in Logon message is not necessary and may even lead to rejection by Acceptor side.

Configuring FIXEdge.properties to use SessionQualifier

To use SessionQualifier two new parameters have been added to FIXEdge.properties: 

  • SessionQualifierValue (for defining SessionQualifier name); 
  • LogonMessageSessionQualifierTag (for defining a tag containing SessionQualifier name).

Session Identification

Both the Initiator and the Acceptor have own logical textual identifiers that must be bilaterally agreed between counterparties. If SessionQualifier is used there will be a set of three identifiers in each FIX message: SenderCompID (49), TargetCompID (56) and SessionQualifier (*Custom tag set by LogonMessageSessionQualifierTag*). This "triple" identification relates both to Registered and Unregistered FIXEdge Sessions.

Business rules (configuring BL_Config.xml)

FIX session definitions in BL_Config.xml are enhanced with SessionQualifier in addition to SenderCompId/TargetCompId combination.

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 the element FIXSession. FIX session is identified 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, FixLayer.FixEngine.Session.<Name>.TargetCompID and FixLayer.FixEngine.Session.<Name>.SessionQualifierValue which were configured for FIX Sessions.

Session instructions

Session instructions such as StartSession, DisconnectSession, TerminateSession are enhanced with SessionQualifier. E.g. StartSession instruction executes FIX session defined by specified SenderCompID/TargetCompID/SessionQualifier combination:


<StartSession SenderCompID="Sender" TargetCompID="Target" SessionQualifier="Q1" />

Sending instructions

Sending instructions can refer to sessions with the use of SessionQualifier as well:

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

Routing rules for incoming messages from TA client

The routing approach for handling the incoming messages from TA client is the same as for incoming messages from FIX sessions, except for one difference: the source is always a Client ID. FIX messages from TA clients are routed to the requisite FIX sessions based on the SenderCompID, TargetCompID and SessionQualifier fields.

 Example: 

<Rule>
    <Source>
        <Client Name="TestClient"/>
    </Source>
    <Condition>
        <MatchField Field="35" Value=".*"/>
        <MatchField Field="571" Value="IST-\\d+"/>
    </Condition>
    <Action>
        <Send>
            <FixSession SenderCompID="TestSender" TargetCompID="TestTarget" SessionQualifier="Q1"/>
        </Send>
    </Action>
</Rule>

JS

All these JS functions now support SessionQualifier as a parameter to identify a session:

send(<SenderCompId>,<TargetCompId>,<SessionQualifier>)
getMsgBySeqNum(<SenderCompId>,<TargetCompId>,<SessionQualifier>,<SeqNum>)
disconnectSession(<SenderCompId>,<TargetCompId>,<SessionQualifier>,<Reason>)
terminateSession(<SenderCompId>,<TargetCompId>,<SessionQualifier>,<Reason>)
startSession(<SenderCompId>,<TargetCompId>,<SessionQualifier>)

New function getSourceSessionQualifier() has been added. Function returns the name of SessionQualifier (String) in case if SessionQualifier is available for source session.

Changes in logs

Any outputs of SenderCompId/TargetCompId combination have been enhanced with SessionQualifier.

Session state internal notifications include SessionQualifier as separate tag SenderSubID (50):

50=SessionQualifier^147=[WARN] Target:Sender AttemptToConnect^33=4^58=W^58=4^58=Target:Sender^58=Established

Example usage in BL_config.xml:

<Rule Description="Description">
      <Source>
        ..
      </Source>
      <Condition>
		<EqualField Field="35" Value="C" />
  		<MatchMessage Value=".*50=SessionQualifier.*"/>
      </Condition>
      <Action>
		<Script Language="JavaScript" FileName="FIXEdge1/conf/JS.js"/>  
      </Action>
</Rule>

Using in FIXICC

In FIXICC SessionQualifier (SessionQualifierValue) and SessionQualifier Tag (LogonMessageSessionQualifierTag) parameters has been supported since version 2.9.9. They can be set in the corresponding fields of "New Session" and "Edit Session" dialog windows. FE SessionID will be changed automatically reflecting defined SenderCompID/TargetCompId/SessionQualifier.


How-to #1. Setup several Acceptor sessions with the same SenderCompId and TargetCompId 

To establish several Acceptor sessions with the same SenderCompId and TargetCompId it's needed to define SessionQualifier property as well as SessionQualifier tag (SessionQualifierValue and LogonMessageSessionQualifierTag parameters respectively in FIXEdge.properties file). 

FIXEdge.properties:

FixLayer.FixEngine.Session.Session#1.Role = Acceptor
FixLayer.FixEngine.Session.Session#1.SenderCompID = Target_Example1
FixLayer.FixEngine.Session.Session#1.TargetCompID = Sender_Example1
FixLayer.FixEngine.Session.Session#1.SessionQualifierValue = A1
FixLayer.FixEngine.Session.Session#1.LogonMessageSessionQualifierTag  = 553
 
FixLayer.FixEngine.Session.Session#2.Role = Acceptor
FixLayer.FixEngine.Session.Session#2.SenderCompID = Target_Example1
FixLayer.FixEngine.Session.Session#2.TargetCompID = Sender_Example1
FixLayer.FixEngine.Session.Session#2.SessionQualifierValue = A2
FixLayer.FixEngine.Session.Session#2.LogonMessageSessionQualifierTag  = 553

BL_config.xml:

<FIXEdge>
 <BusinessLayer>
        <Rule>
            <Source>
                <FixSession SenderCompID="Target_Example1" TargetCompID="Sender_Example1" SessionQualifier="A2"/>
            </Source>
            <Action>
                <Script Language="JavaScript" FileName="FIXEdge1/conf/getQualifier.js" />   
            </Action>
        </Rule>
  	<DefaultRule>
  	    <Action>
    		<DoNothing/>
   	    </Action>
 	</DefaultRule>
 </BusinessLayer>
</FIXEdge>

getQualifier.js:

qualifier = getSourceSessionQualifier();
sessId = getSourceSessionId();
setStringField(553, "Your session qualifier is: " + qualifier);
send(sessId);

How-to #2. Setup several Initiator sessions with the same SenderCompId and TargetCompId 

To establish several Initiator sessions with the same SenderCompId and TargetCompId it's needed to define SessionQualifier property (SessionQualifierValue parameter in FIXEdge.properties file). 

FIXEdge.properties:

FixLayer.FixEngine.Session.Session#1.Role = Initiator
FixLayer.FixEngine.Session.Session#1.SenderCompID = Sender_Example2
FixLayer.FixEngine.Session.Session#1.TargetCompID = Target_Example2
FixLayer.FixEngine.Session.Session#1.SessionQualifierValue = A1
FixLayer.FixEngine.Session.Session#1.LogonMessageSessionQualifierTag  = 553
 
FixLayer.FixEngine.Session.Session#2.Role = Initiator
FixLayer.FixEngine.Session.Session#2.SenderCompID = Sender_Example2
FixLayer.FixEngine.Session.Session#2.TargetCompID = Target_Example2
FixLayer.FixEngine.Session.Session#2.SessionQualifierValue = A2
FixLayer.FixEngine.Session.Session#2.LogonMessageSessionQualifierTag  = 553

BL_config.xml:

<FIXEdge>
 <BusinessLayer>
  <Rule>
       <Source>
           <FixSession SenderCompID="Target_Example2" TargetCompID="Sender_Example2" SessionQualifier="A1"/>
       </Source>
       <Action>
           <Script Language="JavaScript" FileName="FIXEdge1/conf/disconnect.js" />
       </Action>
   </Rule>
  	<DefaultRule>
  	    <Action>
    		<DoNothing/>
   	    </Action>
 	</DefaultRule>
</FIXEdge>

disconnect.js:

disconnectSession("Sender_Example2","Target_Example2", "A2", "Disconnect by message")

How-to #3. Setup several Initiator sessions with the same SenderCompId and TargetCompId using Transport adaptor.

When transport adaptor is used in the message exchange chain, it's convenient to use significant identifying tags values as SessionQualifier names to distinguish between 2 sessions with common SenderCompID/TargetCompID pair.

Another approach is binding one session qualifier with some order identifier (e.g. enriching message content with unique value of ClOrdID related to the session): 

In this case the properties and configuration like in the following examples with RMQ Adaptor are used.

FIXEdge.properties:

FixLayer.FixEngine.Session.Session#1.Role = Initiator
FixLayer.FixEngine.Session.Session#1.SenderCompID = Sender_Example3
FixLayer.FixEngine.Session.Session#1.TargetCompID = Target_Example3
FixLayer.FixEngine.Session.Session#1.SessionQualifierValue = A1
FixLayer.FixEngine.Session.Session#1.LogonMessageSessionQualifierTag  = 553
 
FixLayer.FixEngine.Session.Session#2.Role = Initiator
FixLayer.FixEngine.Session.Session#2.SenderCompID = Sender_Example3
FixLayer.FixEngine.Session.Session#2.TargetCompID = Target_Example3
FixLayer.FixEngine.Session.Session#2.SessionQualifierValue = A2
FixLayer.FixEngine.Session.Session#2.LogonMessageSessionQualifierTag  = 553
 
TransportLayer.TransportAdapters = TransportLayer.RMQTA
 
TransportLayer.RMQTA.DllName = libUniversalTADll-gcc44-MD-x64.so
TransportLayer.RMQTA.Description = RMQ Transport Adaptor
TransportLayer.RMQTA.JVMOptionsFile = ../FixEdge1/conf/JVM_Options.jvmopts
TransportLayer.RMQTA.JavaClass = com.epam.fe.jms.jni.JMSAdaptor
TransportLayer.RMQTA.AllowRejectMessages = true
TransportLayer.RMQTA.ConnectionNames = Connection1
TransportLayer.RMQTA.ClientNames = TradeFlowMQProducer, TradeFlowMQConsumer
  
TransportLayer.RMQTA.Connection.Connection1.ProviderURI = amqp://127.0.0.1:5672
TransportLayer.RMQTA.Connection.Connection1.User = sam1203
TransportLayer.RMQTA.Connection.Connection1.Password = test
TransportLayer.RMQTA.Connection.Connection1.Reconnect = true
TransportLayer.RMQTA.Connection.Connection1.ReconnectTries = 300
TransportLayer.RMQTA.Connection.Connection1.ReconnectInterval = 30000
  
TransportLayer.RMQTA.Client.TradeFlowMQProducer.ConnectionName = Connection1
TransportLayer.RMQTA.Client.TradeFlowMQProducer.StorageDir = ../FixEdge1/log
TransportLayer.RMQTA.Client.TradeFlowMQProducer.SessionType = Producer
TransportLayer.RMQTA.Client.TradeFlowMQProducer.DestinationURI = TradeFlow
TransportLayer.RMQTA.Client.TradeFlowMQProducer.ExchangeName = exchange.OUT
TransportLayer.RMQTA.Client.TradeFlowMQProducer.HeartBeat.Enable = true
TransportLayer.RMQTA.Client.TradeFlowMQProducer.HeartBeat.Interval = 20
TransportLayer.RMQTA.Client.TradeFlowMQProducer.HeartBeat.MessageFile = ../FixEdge1/conf/rabbitMQHB.msg
TransportLayer.RMQTA.Client.TradeFlowMQProducer.MessageProcessingOnMQDisconnect = reject
TransportLayer.RMQTA.Client.TradeFlowMQProducer.StartTime= 09:00
TransportLayer.RMQTA.Client.TradeFlowMQProducer.EndTime= 18:00
  
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.ConnectionName = Connection1
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.StorageDir = ../FixEdge1/log
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.SessionType = Consumer
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.DestinationURI = TradeFlow
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.HeartBeat.Enable = true
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.HeartBeat.Interval = 20
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.HeartBeat.MessageFile = ../FixEdge1/conf/rabbitMQHB.msg
TransportLayer.RMQTA.Client.TradeFlowMQConsumer.HeartBeat.MissedCountBeforeDisconnect = 3

BL_config.xml:

<FIXEdge>
 <BusinessLayer>
 
            <Rule>
                <Source>
                        <FixSession SenderCompID=".*" TargetCompID=".*" SessionQualifier=".*"/>
                </Source>
                <Condition>
                        <MatchField Field="35" Value="D|G|F|n" />
                </Condition>
                <Action>
		           		<Script Language="JavaScript" FileName="FIXEdge1/conf/bindWithQualifier.js" />
                        <Send Name="TradeFlowMQProducer" />
                </Action>
            </Rule>
            <Rule>
                <Source Name="TradeFlowMQConsumer"/>
                <Condition>
                         <MatchField Field="35" Value="8|9|j|n" />
                </Condition>
                <Action>           		
					<Script Language="JavaScript" FileName="FIXEdge1/conf/sendToQualifier.js" />
                </Action>
            </Rule>

  	<DefaultRule>
  	    <Action>
    		<DoNothing/>
   	    </Action>
 	</DefaultRule>
</FIXEdge>

bindWithQualifier.js:

bindWithQualifier.js
qualifier = getSourceSessionQualifier();
ClOrdID = getStringField(11) + "-" + qualifier; 
setStringField(11, ClOrdID); // enrich message with session identifier 11=<ClOrdId>-<session qualifier>

sendToQualifier.js:

sendToQualifier.js
qualifier = "";  // no qualifier by default
ClOrdID = getStringField(11);
// 11=<ClOrdId>-<session qualifier>
var regexp = /(.*)-([\w-]+)/g;
match = regexp.exec(ClOrdID);
if (match != null) // get qualifier from the ClOrdId tag.
{
    qualifier = match[2]; 
}
send("Sender_Example3", "Target_Example3", qualifier);

Troubleshooting

As any custom tag can be used to send SessionQualifier in Logon message, the used dictionary should contain this tag in Logon message or ProhibitUnknownTags should be set to "false". In other cases this tag will be unknown and FIXEdge rejects messages with unknown tags.

Known Issue

For a particular session with specified LogonMessageSessionQualifierTag a default value from engine.properties is used anyway.

Example:

If in engine.properties:
Session.Default.LogonMessageSessionQualifierTag = 50
and in FIXEdge.properties:
FixLayer.FixEngine.Session.Session#1.LogonMessageSessionQualifierTag  = 553
the SessionQualifier tag will be 50 for Session#1.


  • No labels