Overview
For each change of session state, FIXEdge creates a new internal FIX message (35=C | 49=fake | 56=fake ) and sends this message into the business layer to notify about the changes.
The tag 147 in this message is automatically filled by the pattern: [<Category>] <SenderCompID:TargetCompID> <Actual Session state>.
In order to track session state it is required to perform the following steps:
parse tag 147 using JavaScript;
save session state to history.
Message parsing
In order to get a session state, it is recommended to use the script below. It allows parsing tag 147 in the 35=C message which contains the session name and actual session state.
As the result of the script execution we get three tags: 56 - TargetCompID, 49 - SenderCompID, 147 - State.
|
|---|
status = getStringField(147);
var regexp = /.*\s+(\S+):(\S+)\s+(.*)/g;
match = regexp.exec(status);
if (match != null)
{
target = match[1];
sender = match[2];
state = match[3];
//print("[DEBUG] matched target = " + target + " sender = " + sender + " state = " + state);
setStringField(56, target);
setStringField(49, sender);
setStringField(147, state);
}
|
ODBC history
Database configuration
In order to save session state to the database it is required to perform the following steps::
Create a corresponding table to store session statuses;
Create a stored procedure that allows writing data into the table.
Please find an example below. In this case, the PostgreSQL database is used.
|
|---|
create table session_actions(
id serial PRIMARY KEY,
_SenderCompId varchar(64) NOT NULL,
_TargetCompId varchar(64) NOT NULL,
_OrigTime varchar(21) NOT NULL,
_SessionState varchar(20) NOT NULL
);
CREATE OR REPLACE FUNCTION insertSessionStatus
(
_SenderCompId varchar(64),
_TargetCompId varchar(64),
_OrigTime varchar(21),
_SessionState varchar(20)
)
RETURNS void
AS $$
BEGIN
insert into session_actions(SenderCompId, TargetCompId, OrigTime, SessionState) values ( _SenderCompId, _TargetCompId, _OrigTime, _SessionState);
END;
$$
LANGUAGE plpgsql;
|
FIXEdge configuration
In order to save the session state into the database, BL-Rules should be configured on the FIXEdge side:
The rule for history definition: history name, database parameters, fields definitions.
The rule for saving to history: get the message 35 = C, get the session status using JavaScript, save to history (database).
|
|---|
<?xml version="1.0" encoding="UTF-8"?>
<!--
<!DOCTYPE FIXEdge SYSTEM "BusinessLayer.dtd">
-->
<FIXEdge>
<BusinessLayer>
<!-- DB Table with Session Status -->
<History
Name="SessionStatus"
StorageType="ODBC"
TableName="FIXEdge.dbo.SessionStatus"
ConnectionString="DSN=FIXEdgeDB;UID=user;PWD=password;"
UseStoredProcForInsert="true"
StoredProcName="insertSessionStatus"
>
<KeyField ColumnName="_SenderCompId">49</KeyField> <!-- SenderCompId -->
<KeyField ColumnName="_TargetCompId">56</KeyField> <!-- TargetCompId -->
<KeyField ColumnName="_OrigTime">42</KeyField> <!-- OrigTime -->
<KeyField ColumnName="_SessionState">147</KeyField> <!-- Session's State -->
</History>
<!-- Save Events in 35=C messages notifing about session state to DB -->
<Rule>
<Source>
<FixSession SenderCompID=".*" TargetCompID=".*" />
</Source>
<Condition>
<MatchField Field="35" Value="C"/>
<MatchField Field="147" Value=".*:.*"/> <!-- Assume sender and target in 147 field is divided by ':'. The rest of the messages are redundant -->
<Exclusion>
<MatchMessage Value=".*147=.* AttemptToConnect.*"/>
</Exclusion>
</Condition>
<Action>
<Script Language="JavaScript" FileName="FIXEdge1/conf/prepareSessionState.js"/>
<SaveToHistory Name="SessionStatus"/>
</Action>
</Rule>
<DefaultRule>
<Action>
<DoNothing/>
</Action>
</DefaultRule>
</BusinessLayer>
</FIXEdge>
|
The tag (42) OrigTime is saved as a string. If it is needed to save it as Datetime type it is required to convert it to the specific format via JavaScript.
E.g. from 'YYYYMMDD-hh:mm:ss' to 'YYYYMMDD hh:mm:ss':
setStringField(42, getStringField(42).replace("-", " "));
File history
FIXEdge configuration
In order to save the session state into the history file, BL-Rules should be configured on the FIXEdge side:
The rule for history definition: history name, history file parameters, fields definitions.
The rule for saving to history: get message 35 = C, get session status using JavaScript, save to history (file).
|
|---|
<?xml version="1.0" encoding="UTF-8"?>
<!--
<!DOCTYPE FIXEdge SYSTEM "BusinessLayer.dtd">
-->
<FIXEdge>
<BusinessLayer>
<!-- File history with Session Status -->
<History
Name="SessionStatus"
StorageType="File"
WorkingDirectory="FIXEdge1/conf/"
StorageFileName="SessionStatus">
<KeyFields>49, 56, 42, 147</KeyFields>
</History>
<!-- Save Events in 35=C messages notifing about session state to the file -->
<Rule>
<Source>
<FixSession SenderCompID=".*" TargetCompID=".*" />
</Source>
<Condition>
<MatchField Field="35" Value="C"/>
<MatchField Field="147" Value=".*:.*"/> <!-- Assume sender and target in 147 field is divided by ':'. The rest of the messages are redundant -->
<Exclusion>
<MatchMessage Value=".*147=.* AttemptToConnect.*"/>
</Exclusion>
</Condition>
<Action>
<Script Language="JavaScript" FileName="FIXEdge1/conf/prepareSessionState.js"/>
<SaveToHistory Name="SessionStatus"/>
</Action>
</Rule>
<DefaultRule>
<Action>
<DoNothing/>
</Action>
</DefaultRule>
</BusinessLayer>
</FIXEdge>
|
As a result, FIXEdge creates a history file with session statuses:
|
|---|
<Record valid='Y' size='/' data='SENDER1 TARGET1 20160920-13:41:32 Established'/> <Record valid='Y' size='/' data='SENDER2 TARGET2 20160920-13:41:32 Established'/> <Record valid='Y' size='8' data='SENDER1 TARGET1 20160920-21:00:01 Terminated correctly'/> <Record valid='Y' size='8' data='SENDER2 TARGET2 20160920-21:00:01 Terminated correctly'/> |