Configuring Managed Queue
Overview
FIXEdge routes messages (e.g. orders, cancels) from source systems to destination systems and it is a common case that a destination system accepts messages at the time interval when a session is established. But in certain business configurations destination system may work as a broker that owns a gateway to exchanges, that are ultimate destinations for messages. Ultimate destination may be closed (work on schedule base) while a broker is running. In such cases, messages will be rejected by the broker. Thus there is a need to store them in a queue and release them at a specific time, according to an exchange schedule.
To meet these needs Managed Queue solution provides a way:
- To store messages in the queue during off-hours (the market is closed)
- To release messages stored in the queue at the time market is open
- To pass through messages during “market is open” hours
- To define multiple queues for different order types
- To distribute incoming orders among the queues relating to order type - to route only messages that can be accepted by a certain destination system.
- To apply smart logic for orders stored in the queue (cancel and cancel/replace)
Manage Queue feature description
Design
Logically FIXEdge server is a router that routes messages from a source system to a destination system. The following diagram demonstrates data flow for the case managed queue is used. Messages from a source system are parsed and put into the business layer. BL rule is executed and messages that fit the rule are moved to a certain virtual session. Each virtual session is actually a queue. If a virtual session is open (connected to a target session) the message is moved to the target session immediately. If a virtual session is closed (disconnected from a target session) then the message is stored in the queue. The smart logic is applied. The virtual session connects to a target session or disconnects from a target session according to a schedule configured for a virtual session. The target session may also have a schedule. If the target session is not established then messages stay in the queue and are released when the target session is established.
All messages are persistently stored in SQLite database.
SQLite database schema
SQLite database is used to store queued messages. Default DB name is fe.db. The filename and the path to it can be configured with property FixLayer.<managed_queue_name>.Storage.SQLite.FileName
Messages of all queues, sent to all sessions, are stored within a single table – “QueueStorage”. Messages that are delivered or removed are marked in corresponding columns.
Factual removal of messages from the table can be done manually or by a script using SQLite utilities.
Table “QueueStorage” is described below:
Table Column Name | Data Type | Description |
---|---|---|
| INTEGER | Unique identifier of a message in the table |
| TEXT | Manager Queue Name (the same as virtual session name) |
| TEXT | Message Type - taken from tag 35 of a queued message |
| TEXT | Source System identity (e.g. SAP) – taken from tag 49 of a queued message |
| TEXT | Client order ID - taken from tag 11 of a queued message |
| TEXT | Raw FIX message |
ParserName | TEXT | Name of the parser originally used to parse the message |
ApplVer | INTEGER | Application version id of the message, internal id that is mapped to the particular FIX application version |
| INTEGER | The time when the incoming message was stored in the queue |
| INTEGER | 0 – message was not released (must stay in the queue) 1 – message was released (is sent to a target session) |
| INTEGER | The time when the message was released |
| INTEGER | 0 - the message was not removed from a queue by Order Cancel 1 - message was removed from a queue by Order Cancel |
| INTEGER | The time when the message was removed by Order Cancel |
Database schema:
CREATE TABLE QueueStorage (GlobalMessageID INTEGER PRIMARY KEY, QueueID TEXT, MsgType TEXT, ClientID TEXT, ClOrdID TEXT, RawMessageText TEXT, ParserName TEXT, ApplVer INTEGER, TimestampEnqueued INTEGER, IsDone INTEGER, TimeStampDone INTEGER, IsRemoved INTEGER, TimestampRemoved INTEGER); CREATE INDEX idx_QueueStorage_QueueID ON QueueStorage (QueueID, IsDone, IsRemoved); CREATE INDEX idx_QueueStorage_ClOrdID ON QueueStorage (QueueID, ClientID, ClOrdID, IsDone, IsRemoved);
Queue releasing process
Queued messages are released when a virtual session is connected to a target session and a target session is established. Messages are released according to FIFO (First In First Out) logic. If some non-queued messages from the source system are passed to a target session simultaneously with queue release first go the queued messages and then other messages according to the FIFO principle.
Configuration
Please pay special attention to the changes in the behavior depending on CheckVersionOfOutgoingMessages in the engine.properties file.
The value of the ParserVersion property in force for the session at the time when messages were put to the messages queue is stored along with messages in the queue and is used to parse messages stored and therefore it must be still valid (the parser should remain configured) at the time when messages are released from the queue.
To use Managed Queue functionality user must configure the BL rule in BL_Config.xml and manage queue and session properties in FIXEdge.properties files.
Configuring BL
From the routing perspective, the BL rule for routing to a virtual session is similar to an ordinary BL routing configuration.
The example of BL rule for routing from RestAcceptorClient_Queueing source to MQDEST-XMIC-PreOpen virtual session:
<Rule Description="Route XMIC Limit orders to XMIC preopen (MQDEST) "> <Source> <Client Name="RestAcceptorClient_Queueing"></Client> </Source> <Condition> <MatchField Field="35" Value="D|F|G"></MatchField> <MatchField Field="207" Value="XMIC" ></MatchField> <MatchField Field="40" Value="2" ></MatchField> </Condition> <Action> <Send Name="MQDEST-XMIC-PreOpen"></Send> </Action> </Rule>
Configuring managed queue
Manages queue properties description:
Property | Description |
---|---|
FixLayer.<managed_queue_name>.Storage.Type | Type of storage where incoming messages are stored. |
FixLayer.<managed_queue_name>.Storage.SQLite.FileName | The filename of storage. It's a relative path from the FIXEdge root directory specified with the parameter FIXEdge.RootDir |
FixLayer.<managed_queue_name>.Storage.SQLite.BusyTimeoutMs | Timeout in milliseconds to wait before the set busy condition of the DB in case of concurrent access. The default value is the SQLite default, usually 30 seconds. Optional. |
Example
Managed Queue properties example:
FixLayer.ManagedQueue.Storage.Type = SQLite FixLayer.ManagedQueue.Storage.SQLite.FileName = fe.db
Configuring virtual session
The message is routed from the source connected to the virtual session.
Virtual session properties description:
Property | Description |
---|---|
| Name of a virtual session |
| Destination FIX session for routing a message from a virtual session or any other source. |
| Schedule name for virtual session schedule |
Virtual session schedule properties description:
Property | Description |
---|---|
| Time Zone |
| The time when messages stored in the queue are released |
| The time when the session stops sending messages to a target session and starts to store messages in the queue. |
Virtual session properties example (source= RestAcceptorClient_Queueing, virtual session= MQDEST-XMIC-PreOpen):
FixLayer.ManagedQueue.Sessions = MQDEST-XMIC-PreOpen ... FixLayer.ManagedQueue.Session.MQDEST-XMIC-PreOpen.TargetSession = MQTARGET FixLayer.ManagedQueue.Session.MQDEST-XMIC-PreOpen.Schedule = MQTEST-XMIC-PRE
Virtual session schedule properties example:
FixLayer.ManagedQueue.Schedules.MQTEST-XMIC-PRE.TimeZone = America/New_York FixLayer.ManagedQueue.Schedules.MQTEST-XMIC-PRE.ConnectTime = 0 20 18 * * * FixLayer.ManagedQueue.Schedules.MQTEST-XMIC-PRE.DisconnectTime = 0 25 18 * * *
When the ConnectTime trigger is on a message is routed to the target session MQTARGET.
Configuring target session
The target session is configured as an ordinary FIX session.
Target session properties example:
FixLayer.FixEngine.Sessions = MQTARGET ... FixLayer.FixEngine.Session.MQTARGET.Version = FIX44 FixLayer.FixEngine.Session.MQTARGET.SenderCompID = FIXEDGE FixLayer.FixEngine.Session.MQTARGET.TargetCompID = MQDEST FixLayer.FixEngine.Session.MQTARGET.Role = Initiator FixLayer.FixEngine.Session.MQTARGET.StorageType = persistent FixLayer.FixEngine.Session.MQTARGET.IntradayLogoutTolerance = true FixLayer.FixEngine.Session.MQTARGET.RecreateOnLogout = true FixLayer.FixEngine.Session.MQTARGET.TerminateOnLogout = false FixLayer.FixEngine.Session.MQTARGET.IgnoreSeqNumTooLowAtLogon = true FixLayer.FixEngine.Session.MQTARGET.ForceSeqNumReset = 0 FixLayer.FixEngine.Session.MQTARGET.Schedule = MQTEST FixLayer.FixEngine.Session.MQTARGET.HBI = 60 FixLayer.FixEngine.Session.MQTARGET.Host = 10.11.11.111 FixLayer.FixEngine.Session.MQTARGET.Port = 8901
Target session schedule example:
Schedules.MQTEST.StartTime = 0 0 18 * * * Schedules.MQTEST.ConnectTime = 0 05 18 * * * Schedules.MQTEST.DisconnectTime = 0 55 19 * * * Schedules.MQTEST.TerminateTime = 0 59 19 * * *
Order flow scenarios
Order is queued in trade-off hours, released when the market is open
Order goes through without queueing
Cancel eliminates order in the queue
Cancel is queued (no corresponding order in the queue)
Cancel/replace is received, Cancel Reject generated, Order stays in the queue
Smart logic features
Smart Logic is a handler, that can play specialized logic for incoming messages, like canceling orders, sending notifications, and so on.
The FIXEdge package has an example of the smart logic plugin (located in plugins/libb2b_fixserver_plugin_queue_observer.so or plugins/b2b_fixserver_plugin_queue_observer.dll ).
The implemented features in this plugin:
- Matching incoming Cancel with queued Order, deleting both, and sending confirmation to BL.
- Cancel/Replace queued Order – send Cancel Reject message, the order stays in the queue
For details see order flow scenarios.
Logic in the module is hardcoded, but it can be replaced via the FIXEdge plugin system. Smart logic can be turned on/off for all sessions simultaneously.
Property | Description |
---|---|
| Turn on the smart logic plug-in (currently, for order cancel and cancel/replace) <ServiceName> is given by user To turn off plug-in remove or comment this property string |
Since the FIXEdge release 6.11.5, it is possible to enable/disable smart logic per FIX session.
A new parameter with the default value "false" is introduced
FixLayer.ManagedQueue.Session.<session name>.SmartOrderProcessing = true|false.
Troubleshooting
To access SQLite storage, use the sqlite3_analyzer program or other command-line tools for managing SQLite database files from the SQLite Download Page.
The SQLite database file location is configured with the parameter FixLayer.<managed_queue_name>.Storage.SQLite.FileName.
How to list names of tables matching LIKE pattern TABLE
Inside SQLite, the Command-Line Shell runs the below command.
sqlite> .tables QueueStorage
How to show the structure of a table is to use the following PRAGMA command.
Inside SQLite, the Command-Line Shell runs the below command.
sqlite> .header on sqlite> .mode column sqlite> pragma table_info('QueueStorage');
Example of structure output of QueueStorage table
sqlite> pragma table_info('QueueStorage'); cid name type notnull dflt_value pk --- ----------------- ------- ------- ---------- -- 0 GlobalMessageID INTEGER 0 1 1 QueueID TEXT 0 0 2 MsgType TEXT 0 0 3 ClientID TEXT 0 0 4 ClOrdID TEXT 0 0 5 RawMessageText TEXT 0 0 6 ParserName TEXT 0 0 7 ApplVer INTEGER 0 0 8 TimestampEnqueued INTEGER 0 0 9 IsDone INTEGER 0 0 10 TimeStampDone INTEGER 0 0 11 IsRemoved INTEGER 0 0 12 TimestampRemoved INTEGER 0 0