This article is deprecated.
Introduction
In a general sense, feed handlers are a broad class of applications and frameworks that parse, process, aggregate, and/or store market data. Different kinds of market data feeds may supply different kinds of data, such as quote or trade data, orders and order books, yield curves, etc. Some feeds originate directly at the exchanges (NYSE, LSE, …), others are aggregated from multiple sources by third-party institutions and redistributed using a normalized representation.
The eXtremeDB Feed Handler receives market data using industry standard frameworks and stores it in an eXtremeDB database.
Market instrument subscriptions are configurable on a feed-by-feed basis. It is possible to subscribe only to the relevant instruments.
The database schema is flexible and configurable, thus allowing users to store only the data relevant to their needs. The data can be accessed and manipulated using ordinary SQL expressions with xSQL. The user is free to choose a persistent or an in-memory database depending on performance and data persistence requirements.
Currently, the eXtremeDB Feed Handler is only available for 64-bit Linux, Mac OS and Windows systems.
The Feed Handler Application Programming Interface allows the users to create their own extension modules that handle market data feeds not currently supported by the eXtremeDB Feed Handler.
Application Structure
The Feed Handler application consists of the primary executable and loadable modules. The executable is responsible for the Feed Handler configuration file and command line parsing, logging, launching and controlling market data handler modules. The loadable modules implement shared functionality and market data handlers.
The market data handler modules are components that use third-party frameworks (SMDS, TR RFA) to subscribe to, receive and handle market data, and store it in the database. The eXtremeDB Feed Handler includes modules for Refinitiv (formerlyThomson Reuters) RFA and Vela SMDS frameworks, as well as a test module provided for demonstration of the Feed Handler Module API.
Supported Frameworks
Vela (formerly SRLabs) SMDS
From the vendor’s website: “Vela’s SMDS market data solution is a software-based feed handler that can be used in process or deployed as a stand-alone application.” SMDS supports more than 130 feeds and provides uniform access to market data originating from different vendors.
The full list of supported feeds is available in the SMDS User Guide.
Thomson Reuters Enterprise Platform
Thomson Reuters (TR) supplies a wide range of financial products. Its Enterprise Platform (TREP) facilitates implementation of services compatible with the TR infrastructure. The same Enterprise Platform underlies many of TR’s own products. TREP’s Open Message Model (OMM) is the common object model used by the platform’s applications, which enables interoperability between components potentially supplied by multiple vendors.
Data feed solutions from Refinitiv include:
- Reuters Data Feed (RDF): consolidated data feed; superseded by Elektron Real Time Feed.
- Reuters Data Feed Direct (RDF-D): ultra low latency feed that supplies data directly from an exchange (i.e. non-consolidated).
- Elektron Real Time: consolidated, real-time feed, which provides access to over 500 exchanges all over the world. Three delivery options are available:
- Managed
- Deployed
- Connect
- Elektron Direct Feed: FPGA-accelerated real-time feed that supplies data directly from an exchange.
TREP infrastructure can be accessed using a number of frameworks supplied by Refinitiv . The eXtremeDB Feed Handler uses the Robust Foundation API (RFA) and the Elektron Message API (EMA) C++ frameworks from Refinitiv (formerly Thomson Reuters).
Getting Started
The Feed Handler application is distributed as a part of the eXtremeDB Financial Edition package.
Quick Start Guide
The eXtremeDB Financial Edition package contains EMA redistributable libraries, EMA market data generator, and sample configuration files that make it possible to quickly get started with the Feed Handler application and explore its features. Below is a simple step-by-step guide to launching the application. For more detailed discussion of the application, its prerequisites, configuration and execution refer to the chapters below.
First of all, extract the eXtremeDB distribution archive. For brevity, file and directory paths below will be given relative to the eXtremeDB root directory, e.g.:
/home/user/eXtremeDBThe Feed Handler demonstration setup includes the following key components:
- The Feed Handler application:
target/bin/fh
- The EMA market data generator:
target/feedhandler/EMA_redistributable/Generator/generator
- xSQL:
target/bin/xsql
Launching the Market Data Generator
The generator requires the RDM dictionary files (RDMFieldDictionary and enumtype.def) to run. These files can be obtained from the Elektron SDK distribution. Please place them in the Generator directory prior to running the application.
Change the current directory to the market data generator subdirectory and launch the generator:
cd target/feedhandler/EMA_redistributable/Generator ./generatorOn Windows, the generator is launched similarly:
cd target\feedhandler\EMA_redistributable\Generator generator.exeUpon a successful launch, the following message appears:
OmmProvider readyLaunching the Feed Handler
When the Generator is ready, the Feed Handler application is ready to run. Open a second console window, change directories to the directory containing sample EMA scripts and start the Feed Handler:
cd target/feedhandler/scripts/EMA ./feedhandler.sh -c feed_inmem.cfgOn Windows, use the provided
feedhandler.bat
wrapper script:cd target\feedhandler\scripts\EMA feedhandler.bat -c feed_inmem.cfgThe files
feedhandler.sh
andfeedhandler.bat
are wrapper scripts that set up necessary environment variables, prepare symbolic links for shared libraries and start the Feed Handler application. The script’s command line arguments are passed to the Feed Handler application. The configuration filefeed_inmem.cfg
contains settings for an in-memory database. There is alsofeed_disk.cfg
, a configuration file in the same directory, which can be used to evaluate the Feed Handler with a persistent database.When the application is run, you’ll see log output like the following:
2017-01-18 01:55:32 INFO consumer.cpp:115: market data clients ready
Examining Database Content
The market data produced by the Generator application is collected and stored in the eXtremeDB database. It is recommended to use xSQL to connect to the database and execute SQL queries against it.
Open a console window, change directories to the eXtremeDB root directory and launch xSQL:
./target/bin/xsql @localhost:5001When xSQL is run and connected to the database, you’ll see the
XSQL>
command prompt:Now, you can use SQL queries to explore the database contents. For example:
Get the number of Level 1 entries in table MarketPrice:
XSQL>select count(*) from MarketPrice; #1 ------------------------------------------------ 1500 Selected records: 1Get the RICs present in table MarketPrice:
XSQL>select distinct RIC from MarketPrice; RIC ------------------------------------------------ ACN.N IBM.N TRI.N Selected records: 3Read some records:
XSQL>>select RIC, BID, ASK from MarketPrice where RIC='TRI.N' limit 10; RIC BID ASK ---------------------------------------------------------------------- TRI.N 18 19 TRI.N 17 19 TRI.N 21 22 TRI.N 20 21 TRI.N 25 28 TRI.N 22 24 TRI.N 20 21 TRI.N 21 23 TRI.N 17 19 TRI.N 19 20 Selected records: 10Explore the MarketByOrder domain summary data:
XSQL>select RIC, CURRENCY, TRD_UNITS, PR_RNK_RUL, RDN_EXCHD2 from MarketByOrderSummary; RIC CURRENCY TRD_UNITS PR_RNK_RUL RDN_EXCHD2 ------------------------------------------------ TRI.ARC USD INT NOR ASE Selected records: 1
Using Web Console to Examine Application and Database Status
You may use a web browser to examine application status, database schema and performance indicators. In order to do that, launch the browser and type the Feed Handler web console’s default address:
http://localhost:8082
Shutting Down
To leave xSQL, type “
exit
” (or simply press Control-D). You’ll see the Linux command prompt again:XSQL>exit user@ubuntu:~/eXtremeDB$To stop the Feed Handler, press Control-C in the console window (on Linux you may also send it a
SIGTERM
signal using the “kill” command). Since the Feed Handler was configured to use an in-memory database, its contents are lost when the application shuts down. To prevent accidental data loss, the Feed Handler application requests the user to repeat the Control-C key combination before shutting down the database. Until the confirmation is received, the database remains intact and can be accessed using xSQL:^C 2017-01-18 02:15:48 INFO app.cpp:188: stopped 2017-01-18 02:15:49 WARNING app.cpp:230: shutting down Feed handler, in-memory database will be destroyed; press Ctrl-C again or issue "kill 20189" command to complete shutdownWhen the Feed Handler is stopped, the Generator can be stopped as well, using the same Control-C key combination.
Prerequisites
The handler modules of the Feed Handler application require the corresponding frameworks: Vela SMDS, Refinitiv RFA and Refinitiv EMA.
The Feed Handler application was designed to be used with the following versions of the frameworks:
- Vela SMDS: 4.1.0
- Thomson Reuters RFA: 8.1.0
- Refinitiv EMA: 1.3.1
Failing to meet the framework version requirements may result in abnormal functioning.
Environment variables
The following environment variables need to be set:
MCO_ROOT
: path to the eXtremeDB directorySMDS_ROOT
: path to the Vela SMDS directory, if neededEMA_ROOT
: path to the Refinitiv EMA directory, if neededLD_LIBRARY_PATH
must include paths to:
- eXtremeDB shared libraries ($
MCO_ROOT/target/bin.so
)- SMDS shared libraries (e.g. $
SMDS_ROOT
/lib/LINUX-2.6/rhel/gcc41/64/opt
)- EMA shared libraries (e.g. $
EMA_ROOT
/Libs/RHEL6_64_GCC444
)ELEKTRON_ROOT
: path to the Refinitiv Elektron SDK directory, if needed
ELEKTRON_ARCH
: Elektron libraries architecture, if needed (e.g. RHEL6_64_GCC444; all available architectures can be found in the$ELEKTRON_ROOT/Cpp-C/Ema/Libs
directory)ELEKTRON_CONF
: Elektron libraries configuration, if needed (Debug or Optimized)Please note that the frameworks may contain multiple sets of shared libraries for different target operating systems and compilers. For example, RFA may contain shared libraries for CentOS (Libs/OL7_64_GCC482) and Red Hat Enterprise Linux (Libs/RHEL6_64_GCC444). Be careful to point the LD_LIBRARY_PATH entries to the correct directories.
Building the Feed Handler
If you have an eXtremeDB Financial Edition source code package, you can build the Feed Handler application from source. The build procedure is described in section "Building the Feed Handler from Source Code".
Running the Feed Handler
The application executable file is named
fh
. It is located in thetarget/bin
subdirectory of the eXtremeDB Financial Edition package.Before launching the application, make sure that the
LD_LIBRARY_PATH
environment variable contains entries for eXtremeDB and SMDS shared library directories - noLD_LIBRARY_PATH
settings are required for the EMA module, since it is linked statically with the Elektron API libraries. On Windows, thePATH
environment variable can be used.To launch the application, prepare the required configuration files and launch the Feed Handler executable file. For information on Feed Handler command line arguments and configuration files, refer to the sections below.
To gracefully shut down the Feed Handler running in the foreground, press Ctrl-C. It is also acceptable to send it the
SIGTERM
signal on Linux (using the “kill <PID>
” command), which is helpful when the application runs in the background, or as a daemon. The application will also stop on conditions making its further functioning impossible, such as running out of memory when using in-memory database.Unlike a shared-memory database, the conventional in-memory database is destroyed upon application exit. In order to prevent data loss, if the application uses a non-persistent database in conventional memory and its embedded RSQL server is enabled, it will pause and require confirmation before shutting down the database in order to make it possible for the user to export database contents, if needed. Refer to the “Accessing Feed Handler database contents” section for further information.
Accessing Feed Handler database contents
The Feed Handler application allows the user to set various parameters of the eXtremeDB database such as: choose a persistent (disk) or in-memory database, set database size, file paths, etc.
The recommended approach to accessing the database is to enable the embedded RSQL server in the Feed Handler application configuration file. In this case the database can be accessed from RSQL-enabled clients, as well as from xSQL.
When the Feed Handler application is running and its RSQL server is enabled, the user can connect to the database and execute SQL queries using xSQL. For instance, if the RSQL server is configured to use
port 5001
and the Feed Handler is running onlocalhost
:$ xsql @localhost:5001 xsql started Runtime configuration Remote node(s) : localhost:5001 Runtime : Debug XSQL>select count(*) from MyQuotes; #1 ------------------------------------------------- 248361 Selected records: 1For more information on RSQL server configuration, refer to the “database” section of the “Feed Handler Configuration” section. For information on xSQL, refer to the eXtremeSQL Quick Start.
Using the Feed Handler Web Console to Examine Application and Database Status
The Feed Handler application has an embedded web console that allows the user to examine the following:
- Application status and errors
- Feed states and statistics
- Database configuration and statistics
- Database tables, their schemas and data rates
- Log and configuration files
The web console is always enabled. Its address and port are specified in the Feed Handler application configuration file’s “database” section (see the “Feed Handler Configuration” section for details). In order to access the console, launch a web browser and enter the address and port of the console in the address bar, e.g.:
http://localhost:8082
Vertical Storage Support in Feed Handler
The Feed Handler is able to store incoming data in vertical storage, i.e. using eXtremeDB sequences. Please see the Vertical Storage Table Configuration section below for configuration details.
Sequence data buffering
It is inefficient to append elements to sequences one by one. Hence, the Feed Handler buffers the incoming records in a temporary "flat" table, and then moves them to the target table. The number of the buffered records is defined by the
sequenceBufferSize
parameter.Ordered sequences
The common limitations for ordered sequences apply:
- the first field (or fields) of the table must be the primary key;
- only one sequence can be ordered, and it must be the first sequence.
The Feed Handler checks the database table configuration upon startup and rejects it unless these requirements are met.
If no sequence order is defined, the records will be stored in the order of their arrival.
To define an ordered sequence, set the
sequenceOrder
parameter of the respective field toasc
ordesc
, as needed.Out-of-order record handling
It is possible for some records to arrive in the wrong order, breaking the ordering rule defined by the configuration. The Feed Handler supports optional recovery of the records' order.
If the order cannot be recovered, the records are stored in the "out-of-order" table ("OO table" for brevity). This is a regular (i.e. "flat") table that has the same name as the data table, with an _OO_ prefix.
No recovery
This is the default behavior. The out-of-order records will be moved to the OO table.
Sequence order recovery
Due to the constraints of the out-of-order sequence element insertion, the Feed Handler will attempt to insert out-of-order records one by one. Those that still fail to be inserted will be moved to the OO table.
This approach will obviously carry a performance penalty, but it can be convenient if out-of-order records are relatively rare.
Feed Handler Configuration
The Feed Handler application is configured using command line arguments and a configuration file.
Command Line Arguments
Currently, only one command line argument is supported.
- -c <path_to_config_file>: optional, contains the path to the Feed Handler application configuration file; default: “
feed.cfg
”.
Configuration File
The Feed Handler application configuration file is a text file that contains generic application settings and database parameters, specifies frameworks to be used (EMA, SMDS), subscriptions, database schema definitions, etc. It is structured as a JSON file with a few extensions:
- It allows hexadecimal (0x[0-9A-F]), octal (0[0-7]) and decimal numbers.
- Numbers allow suffixes 'k', 'K' (kilo), 'm', 'M' (mega) and 'g', 'G' (giga). (For example, "100m" means 100*1024*1024.)
- Quotes are not mandatory for strings without whitespace and/or special symbols.
- Symbols after the '#' are comments (up to the end of the line).
Apart from the Feed Handler application configuration file, the supported third-party frameworks (SMDS, EMA) also require separate configuration files in their own formats. The paths to these files are set in the application configuration file. Refer to the following sections for details.
Refer to the examples below that demonstrate usage off application configuration files.
The configuration file has the following structure:
- The "application" Section
- The "logging" subsection
- The "handler" section
- The “config” subsection
- The “tables” subsection
- The “dataSources” subsection
- The “subscriptions” subsection
- The “database” section
The contents of each of these sections and subsections are described below.
The "application" Section
This section contains settings for the application itself.
The "logging" subsection
This subsection contains a list of loggers. Each logger has the following parameters:
- type: type of the logger (“
file
” or “stdout
”)- level: minimal log severity level (“
DEBUG
”, “INFO
”, “WARNING
”, “ERROR
”)- filename: name of the file for a “
file
” loggerThe "handler" section
This section contains settings for market data retrieval, processing and storage.
- name: name of the market data handler module (e.g. “
smdsfeed
”,"trfeed"
or “emafeed
”)The “config” subsection
This subsection contains handler module-specific settings.
For the SMDS module:
- configPath: path to the folder containing the SMDS configuration file
- configFile: name of the SMDS configuration file
For the Refinitiv EMA module:
- configPath: path to the folder containing the EMA configuration file
- configFile: name of the EMA configuration file
- login: EMA login domain settings:
- userName: username for authentication
- appId: application ID (if required by the provider)
- position: application position (if required by the provider)
- password: password (optional)
For the Refinitiv RFA module:
- useAppLog: use the Feed Handler application log for RFA event logging
- configPath: path to the folder containing the RFA configuration file
- configFile: name of the RFA configuration file
- extraConfig: additional RFA configuration files; a single JSON object (or an array of objects) containing these fields:
- path: path to the folder containing the file
- file: name of the file
- namespace: RFA configuration namespace (“default” if left empty)
- sessionName: RFA session name, must match settings in the RFA configuration file
- consumerName: RFA OMM consumer name, must match settings in the RFA configuration file
- connStatsReportPeriod: network connection statistics reporting period (seconds); set to 0 to disable
- login: RFA login domain settings:
- userNameType: type of the username field (USER_NAME, USER_EMAIL_ADDRESS or USER_TOKEN; “USER_NAME” by default)
- userName: username for authentication
- appId: application ID (if required by the provider)
- position: application position (if required by the provider)
- appAuthToken: authorization token (optional)
- appName: name of the application (optional)
- instanceId: application instance identifier (optional)
- password: password (optional)
The “tables” subsection
This subsection defines the mapping of the market data records’ fields to the database tables. Each table is described by a JSON object that contains the following fields:
- type: type of the table contents (see module-specific table configuration sections)
- name: name of the table (must be a unique and valid SQL table name)
sequenceBufferSize
: the size of the sequence buffer (for sequence fields)sequenceOrderRecovery
: if set to true, enable sequence order recovery mechanism- fields: array of feed records’ fields to database column mappings; each mapping contains:
- source: name of the source field (names are pre-defined for each market data source, see SMDS- and EMA-specific table configuration sections)
- target: name of the target field (must be unique per table and valid SQL field name)
sequence
: if set to true, this field will be stored in a sequencesequenceOrder
: order of the sequence,asc
ordesc
(undefined by default)- indexes: list of table indexes; each index description is a JSON object that contains:
- name: name of the index to be created in the database (must be a unique and valid SQL index name)
- fields: list of fields included in this index (as defined in the “fields” subsection; specify one or more “target” field names here)
- unique: “unique” index flag (“
true”
or “false
”)
Please note that fields’ SQL types are not specified in the “fields” array. For SMDS feeds, these types are fixed and correspond to the types of fields of SMDS entity classes (
MDQuote
,MDTrade
, etc.) For TR OMM-based feeds (RFA and EMA), the field types are retrieved from the provider's service dictionary.Vertical Storage Table Configuration
Sequences are declared in the table mappings, together with the related settings. For example:
"tables": [ { "name": "MyQuotes", "sequenceBufferSize": 300, "sequenceOrderRecovery": "true", "fields": [ { "source": "symbol", "target": "symbol" }, { "source": "timestamp", "target": "timestamp", "sequence": "true", "sequenceOrder": "asc" }, { "source": "bid", "target": "bid", "sequence": "true" }, { "source": "ask", "target": "ask", "sequence": "true" }, ], "indexes": [{ "name": "pk", "unique": "true", "fields": ["symbol"] }] } ]The “dataSources” subsection
This subsection contains a list of “data sources” in the given feed. For SMDS feeds, this must contain a list of session managers corresponding to the SMDS configuration file. For TR feeds, the services required by the user are listed here; these services must be available in the RFA Source Directory. Each data source is described by a JSON object that contains the following fields:
- type: type of the data source
- name: name of the data source
For the SMDS module, the “type” field must specify a valid SMDS session manager type name (e.g. “
CTASessionMgr
”, “ITCH5SessionMgr
”). The list of available SMDS session managers is available in the SMDS User Guide. The “name” field must correspond to the session manager name specified in the session manager configuration section of the SMDS configuration file.For the RFA and EMA modules, the “type” field should be left empty, and the “name” field must contain the name of the service available in the provider's Source Directory (i.e. “
DIRECT_FEED
”). The list of available service names depends on the market data provider.The “subscriptions” subsection
This subsection describes subscriptions to be made.
Each subscription is described by a JSON object that contains the following fields:
- dataSource: name of the data source for this instrument (as defined in the “name” field of the data source in the “dataSources” subsection)
- sym: either a single instrument name, or a JSON array of instrument names
- symListFile: symbol list file (see below*)
- domain: data domain (if required by the handler module)
SMDS feeds support “wildcard” subscriptions: it is possible to subscribe to all symbols provided by a data source by passing an asterisk (‘*’) for the instrument name.
Instrument subscriptions for the RFA and EMA feeds must list symbol names (RICs) explicitly, as wildcard subscriptions are not supported.
*For convenience, it is possible to specify symbol lists for subscriptions in external files using the “symListFile” field, which must contain the path to the symbol list file. This file uses JSON syntax (same as the Feed Handler application configuration files) and should contain a single array called “symbols”. This array must contain strings representing symbol names, e.g.:
"symbols": [ "SYM1", "SYM2" ]If both the “
sym
” and “symListFile
” fields are set, their symbol lists are merged. Duplicate symbol names are ignored.The “database” section
This section contains eXtremeDB database settings for the Feed Handler.
- transactionManager: eXtremeDB transaction manager (“
mursiw
” or “mvcc
”)- useSharedMemory: if set to “
true
”, the database will be created in shared memory; if set to “false
”, the database will be created in the private memory region of the application (only makes sense for in-memory databases)- useDiskDatabase: if set to “
true
”, the database and its tables will be persistent (i.e. stored in a persistent database)- databaseName: name of the eXtremeDB database; if the database does not exist, it will be created
- databaseSize: database size in bytes
- freeMemoryThreshold: minimum percentage of free memory remaining in the in-memory database; when this threshold is reached, the application is stopped (defaults to 5% if not set)
- databaseFileName: filename for a persistent database (only used if “
useDiskDatabase
” is set to “true”)- databaseLogFileName: filename for a persistent database log file (only used if “
useDiskDatabase
” is set to “true
”)- diskCacheSize: size of the database cache in bytes (only used if “
useDiskDatabase
” is set to “true
”)diskPageSize: size of the disk page in bytes (only used if “
useDiskDatabase
” is set to “true
”)mainMemPageSize: size of the memory page in bytes
maxDictSize: maximum size of the database dictionary
maxClasses: maximum number of classes
maxIndexes: maximum number of indexes
logType: type of the database log (“
none
”, “undo
” or “redo
”)redoLogLimit: max redo log size, in bytes
defaultCommitPolicy: default commit policy (“
sync_flush
”, “buffered
”, “delayed
” or “no_sync
”)transSchedPolicy: transaction scheduling policy (“
fifo
”, “reader_favor
” or “writer_favor
”)- SQLstatements: SQL statements to execute upon database startup (a single string, statements should be separated with semicolons)
- SQLscripts: array of SQL script names to run upon database startup
An example of the “
database
” section specifying an in-memory database in conventional memory:"database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "false", "databaseName": "RFA_inmem_db", "databaseSize": "1073741824" }Please note that a persistent database will require additional parameters:
"database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "true", "databaseName": "RFA_inmem_db", "databaseSize": "1073741824", "databaseFileName": "RFA_db.dbs", "databaseLogFileName": "RFA_db.log", "diskCacheSize": "1073741824", }Running SQL statements and scripts upon database startup:
"database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "false", "databaseName": "RFA_inmem_db", "databaseSize": "1073741824" "SQLstatements": "create table test (t int);", "SQLscripts": ["create_tables.sql", "import_assets.sql"] }The “RSQLserver” subsection
This subsection contains settings for the RSQL server.
If enabled, the Feed Handler application will start an embedded RSQL server. It will then be possible to access the database contents using the eXtremeDB RSQL protocol, e.g. using the xSQL, or a custom RSQL client (see eXtremeSQL and xSQL documentation for more details).
- enable: if set to “true”, RSQL server will be enabled (“
false
” by default)- port: RSQL port for incoming connections (must be set explicitly)
An example of an RSQL server configuration for an in-memory database:
"database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "false", "databaseName": "RFA_inmem_db", "databaseSize": "1073741824", "RSQLserver": { "enable": "true", "port": 5001 } }The “WebConsole” subsection
This subsection contains settings for the Feed Handler web console.
The embedded web console is used to examine application status and statistics in real time.
- addr: address of the web console (default:
0.0.0.0
)- port: port of the web console (default:
8082
)An example of web console configuration subsection in the “database” section:
"database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "false", "databaseName": "RFA_inmem_db", "databaseSize": "1073741824", "WebConsole": { "addr": "0.0.0.0", "port": 8082 } }
Vela SMDS-Specific Database Schema Configuration
SMDS provides multiple kinds of data through its
MDListener
interface callbacks. Except for “Custom Event” data, SMDS provides all of its records as C++ classes with fixed layout. SMDS module tables store data provided by theMDListener
callbacks. The supported table types and their fields (as specified in the “source” field of the “fields” array of a table definition) are:
- Quote ("condition", "isNBBO", "slowBid", "slowAsk", "status", "numBuyOrders", "numSellOrders", "bid", "ask", "bexchange", "oexchange", "bidSize", "askSize", "ibidSize", "iaskSize", "addnQuoteCondition", "isFINRANBBO", "participantTimeSeconds", "participantTimeMicro", "participantTimestamp")
- Trade ("side", "crossType", "compositeParticipantID", "tradeQualifier", "lastPrice", "status", "visibility", "lastSize", "cumVolume", "userField", "orderId", "subMktID", "vwap", "participantTimeSeconds", "participantTimeMicro", "participantTimestamp")
- Order ("numParts", "side", "size", "oldSize", "price", "oldPrice", "status", "orderId", "display", "extra1", "extra2")
- OrderReplace (“oldOrderId”, “newOrderId”)
- Imbalance ("when", "side", "regulatory", "crossType", "price", "farPrice", "nearPrice", "bidPrice", "askPrice", "bidSize", "askSize", "size", "pairedSize", "totalImbalance", "marketImbalance")
- BestPrice (same fields as in Quote)
- SecurityStatusChange (“newState”)
- TradingIndicationAlert ("financialStatus", "corporateAction", "securityStatus", "adjustment", "pDenom", "bid", "ask", "bidP", "askP")
- TradeDisseminationTimeAlert ("financialStatus", "corporateAction", "securityStatus", "tradeDisseminationTime", "tradeDisseminationSec", "tradeDisseminationMicro", "tradeDisseminationTimestamp")
- Custom Event tables (see below for detailed explanation)
An example of a table containing Quote data:
{ "type": "Quote", "name": "MyQuotes", "fields": [ { "source": "bid", "target": "bid" }, { "source": "ask", "target": "ask" }, { "source": "condition", "target": "condition" } ] }For a more detailed explanation of these classes and their fields, refer to the SMDS API Guide and SMDS User Guide. Refer to the feed specific information in the SMDS User Guide for information on data provided by certain feeds.
Fields Supported By Multiple Tables
Besides the table-specific fields listed above, all tables (except for OrderReplace) support the following fields from the
InstrumentDef
SMDS class: “symbol”, “exchange”.All of the tables corresponding to SMDS classes derived from
MDBaseData
(i.e. all but OrderReplace and SecurityStatusChange) also support the following fields: "exchTimeSec", "exchTimeMicro", "exchTimestamp", "recvTimeSec", "recvTimeMicro", "recvTimestamp", "MDRCRecvTimeSec", "MDRCRecvTimeMicro", "MDRCRecvTimestamp".All of the tables listed above may also include DB write timestamp fields: "DBTimestamp".
Thus, the table definition for Quotes may contain such common fields, e.g.:
{"source": "symbol", "target": "symbol"}, {"source": "exchTimeSec", "target": "exchTimeSec"}, {"source": "exchTimeMicro", "target": "exchTimeMicro"}, {"source": "DBTimestampSec", "target": "DBTimestampSec"}, {"source": "DBTimestampMicro", "target": "DBTimestampMicro"}
Custom Event Tables
Apart from well-defined records provided by the
MDListener
callbacks in the form of C++ classes, SMDS supports “custom” events, i.e. events that cannot be represented as any of these classes. These custom events are represented internally in SMDS as data structures containing event type code and a dynamic array of fields.SMDS custom events are stored in database tables just like other records, except for this limitation: custom event field data is always stored in textual (string) form.
All table type names for custom events have the following structure: “Custom.” prefix followed by custom event type string, i.e. “
Custom.CE_OPN_CLS_HG_LW_STL_PRICE
”. Event type strings correspond to the enumeration values defined inMDCustomEvent::EventType
enumeration in the SMDS MDCustomEvent.h header.Custom event field names correspond to the enumeration values defined in the
MDCustomEvent::EventFields
enumeration in the SMDS MDCustomEvent.h header, i.e. “CF_AUCTION_PRICE
”.The exact number and names of custom event fields for each custom event type depend on the feed. They are specified in the feed-specific information section of the SMDS User Guide.
Below is an example of a “custom event” table containing information on close prices for the CTA feed, corresponding to the description in the SMDS User Guide:
{ "type": "Custom.CE_OPN_CLS_HG_LW_STL_PRICE", "name": "MyClosePrice", "fields": [ { "source": "symbol", "target": "symbol" }, { "source": "exchange", "target": "exchange" }, { "source": "CF_PREVCLOSE_PRICE", "target": "prevClosePrice" }, { "source": "CF_PREV_CLOSE_DATE", "target": "prevCloseDate" } ] }For more information on the structure of custom events, refer to the SMDS API Guide.
Refinitiv RFA- and EMA-Specific Database Schema Configuration
Unlike SMDS, the content of TR OMM-based feed records is not predefined. For instance, MarketPrice refresh messages contain a list of fields (RDM
FieldList
), which may vary depending on the data source. The types of the fields are not known beforehand as well: they must be retrieved from the Refinitiv RFA and EMA dictionary. This makes it impossible to know the database structure beforehand. Thus, for TR OMM-based feeds, the database schema is not created until a connection to the service is established.The Refinitiv RFA and EMA handler modules currently supports data provided by MarketPrice and MarketByOrder RDM domains. So, the supported table types for TR OMM-based feeds are “MarketPrice”, “MarketByOrder.Summary” and “MarketByOrder.Entries”.
The field mappings in the table definitions for TR OMM-based feeds contain field names as specified in the RDM dictionary of the service (e.g. “RDNDISPLAY”, “RDN_EXCHID”, etc.), e.g.:
"fields": [ { "source": "RDNDISPLAY", "target": "RDNDISPLAY" }, { "source": "RDN_EXCHID", "target": "RDN_EXCHID" }, { "source": "DIVPAYDATE", "target": "DIVPAYDATE" } ]For the structure of the MarketPrice and MarketByOrder messages, refer to the RDM Usage Guide. For exact contents and data structure of the records, please consult your service provider.
Refinitiv RFA and EMA do not allow its users to perform “wildcard” subscriptions to all symbols provided by an exchange. The list of symbols must be specified explicitly in the “subscriptions” subsection of the configuration file.
Feed Handler-Defined Table Fields
In addition to the fields defined in the RDM dictionary, Feed Handler defines some additional fields that are specific to certain table types and are described in the sections below.
Further, all TR tables may also include DB write
timestamp
fields: "DBTimestamp".MarketPrice Tables
Tables of the MarketPrice type contain L1 market data provided by the MarketPrice domain of the RDM. Apart from the fields defined in the RDM dictionary, these tables may also contain the following fields:
- RIC: instrument RIC (Reuters Instrument Code)
- respTypeNum: response type number as defined in the “MarketPrice update” subsection of the “MarketPrice Domain” section of RDM Usage Guide (may indicate quote, trade, alerts, etc.)
An example of a MarketPrice table definition:
{ "type": "MarketPrice", "name": "MyMarketPrice", "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "respTypeNum", "target": "respTypeNum" }, { "source": "RDNDISPLAY", "target": "RDNDISPLAY" }, { "source": "RDN_EXCHID", "target": "RDN_EXCHID" }, { "source": "DIVPAYDATE", "target": "DIVPAYDATE" } ] }MarketByOrder.* Tables
Tables of the MarketByOrder.* type store L2 order books provided by the MarketByOrder domain of the RDM. Currently, two table types are supported for this domain: “MarketByOrder.Summary” and “MarketByOrder.Entries”. The former stores the summary data provided in the “summary” section of the MarketByOrder refresh message. The latter stores data provided in the MarketByOrder update messages.
MarketByOrder.Summary tables may contain the following fields in addition to the RDM fields:
- RIC: instrument RIC
MarketByOrder.Entries tables may contain the following fields in addition to the RDM fields:
- RIC: instrument RIC
- orderID: order identification string
- entryAction: latest update to the record: ADD, UPD or DEL, corresponding to addition, update, or deletion of the order in the order book
An example of a summary and a data table for MarketByOrder data:
{ "type": "MarketByOrder.Summary", "name": "MyMarketByOrderSummary", "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "PROD_PERM", "target": "PROD_PERM" }, { "source": "CURRENCY", "target": "CURRENCY" }, { "source": "TRD_UNITS", "target": "TRD_UNITS" }, ], }, { "type": "MarketByOrder.Entries", "name": "MarketByOrderEntries", "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "orderId", "target": "orderId" }, { "source": "entryAction", "target": "entryAction" }, { "source": "ORDER_PRC", "target": "ORDER_PRC" }, { "source": "ORDER_SIDE", "target": "ORDER_SIDE" }, { "source": "ORDER_SIZE", "target": "ORDER_SIZE" }, { "source": "QUOTIM_MS", "target": "QUOTIM_MS" }, ], }
Third-Party Frameworks Configuration
Vela SMDS and Refinitiv RFA and EMA frameworks require additional configuration files in their own formats. Paths to these configuration files must be specified in the Feed Handler application configuration file. For a brief description of the structure and contents of these files, please refer to the framework-specific subsections below.
Refinitiv RFA Configuration File
The Refinitiv RFA configuration file has a custom format. This file contains session and connection settings, logging parameters, etc. The format and the contents of this file are described in the RFA Configuration Guide (supplied as a part of the RFA distribution). For an example of an RFA configuration file, refer to Appendix D.
The Feed Handler application requires at least one RFA configuration file to be present. Its location should be specified using the “configPath” and “configFile” keys of the “handler.tr” subsection in the Feed Handler configuration. All configuration nodes defined in this file are imported into the Default namespace of the RFA configuration database. However, it is possible to define additional configuration files and optionally import their contents into custom RFA namespaces. For further information, refer to the “Feed Handler Configuration” chapter.
Refinitiv EMA Configuration File
The Refinitiv EMA configuration file is an XML file. This file contains session and connection settings, logging parameters, etc. The format and the contents of this file are described in the EMA Configuration Guide (supplied as a part of the EMA distribution). For an example of an EMA configuration file, refer to Appendix B.
Vela SMDS Configuration File
The SMDS configuration file is an XML file. Its structure is described in the SMDS User Guide. It contains both generic SMDS settings (license file location, logging, etc.) and feed-specific settings (session managers, connections, etc.). For an example of a SMDS configuration file, refer to Appendix D.
Appendices
Please note that all configuration files are provided for demonstration purposes only. Configuration settings must be chosen carefully on a case-by-case basis. Discussion of SMDS and Refinitiv RFA and EMA configuration files is beyond the scope of this document.
Appendix A - Sample Configurations
Below are some examples of the Feed Handler configuration sections. Parameters are explained inline.
Application Settings
The “application” section describes generic application settings. Below are settings for terminal log output and release mode:
"application": { "logging": [ # Print log messages with priorities "INFO" and above to the terminal { "type": "stdout", "level": "INFO" } ] }To write log messages of DEBUG severity and above to a log file, add the corresponding line to the “logging” array:
"application": { "logging": [ { "type": "stdout", "level": "INFO" }, { "type": "file", "level": "DEBUG", "filename": "feedhandler.log" }, ] }Database Settings
The “database” section contains eXtremeDB database settings. Below is an example of an in-memory database. RSQL server is enabled to allow for connecting to the database using xSQL and RSQL-enabled applications.
"database": { "transactionManager": "mvcc", # Transaction manager "useSharedMemory": "false", # Don't use shared memory "useDiskDatabase": "false", # Don't use disk database "databaseName": "inmem_db", # Database name "databaseSize": "1073741824", # Size of the database, bytes # RSQL server parameters "RSQLserver": { "enable": "true", # Enable RSQL server "port": 5001, # Port number for incoming RSQL connections }, }To create a persistent (disk) database, add corresponding settings (RSQL server is still enabled for remote access):
"database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "true", # Use disk database "databaseName": "disk_db", "databaseSize": "1073741824", "databaseFileName": "RFA_db.dbs", # Name of the database file "databaseLogFileName": "RFA_db.log", # Name of the database log file "diskCacheSize": "1073741824", # Disk cache size, bytes "RSQLserver": { "enable": "true", "port": 5001, }, }Additionally, custom SQL statements and scripts can be run upon database startup:
"database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "false", "databaseName": "inmem_db", "databaseSize": "1073741824", "SQLstatements": "create table test (t int);", "SQLscripts": ["create_tables.sql", "import_assets.sql"] }Handler Module Settings
These settings describe which Feed Handler modules are used to connect to the market data sources, their specific settings (e.g. locations of configuration files, authentication settings), database tables, etc.
An example of a Refinitiv RFA listener that subscribes to Level 1 (MarketPrice domain) data from the DIRECT_FEED service of the provider and stores it in table MarketPrice:
# Handler Module settings "handler": { # Module name: TR RFA module "name" : "trfeed", # Module-specific settings "config": { "useAppLog": "false", # Don't send RFA log messages to the Feed Handler application log "configPath": "./", # Directory containing RFA configuration file "configFile": "RFA.cfg", # Name of the RFA configuration file "sessionName": "RFA_session", # RFA session name (must correspond to the settings in the # RFA configuration file) "consumerName": "RFA_OMM_Consumer", # RFA consumer name "connStatsReportPeriod": 5, # Period of connection statistics reporting, seconds # Login settings "login": { "userName": "user1", # username "appId": "123", # application identifier }, }, # Database tables configuration "tables": [ { "type": "MarketPrice", # Table contents' type: MarketPrice domain data "name": "MarketPrice", # Table name # Mapping of fields from the incoming data stream to the database table's columns "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "BID", "target": "BID" }, { "source": "ASK", "target": "ASK" } ], } ], # Data sources: data provider's services to request data from "dataSources": [ { "type": "", # Data source type: must be empty for TR feeds "name": "DIRECT_FEED" # Service name }, ], # Level 1 subscriptions (MarketPrice domain) "subscriptions": [ { "dataSource": "DIRECT_FEED", # Service name to request data from "sym": ["TRI.N","IBM.N","ACN.N"], # List of symbols to subscribe to "domain": "MarketPrice", # OMM MARKET_PRICE domain }, ], }An example of a Vela SMDS listener that subscribes to Quote data from the CQS session manager (which must be defined in the SMDS configuration file):
"handler": { # Module name: Vela SMDS module "name" : "smdsfeed", # Module-specific settings "config": { "configPath": "./", # location of the SMDS configuration file "configFile": "config.xml" # name of the SMDS configuration file }, # Database tables configuration "tables": [ { "type": "Quote", # Table contents' type: Quotes "name": "MyQuotes", # Table name # Mapping of fields from the incoming data stream to the database table's columns "fields": [ { "source": "symbol", "target": "symbol" }, { "source": "bid", "target": "bid" }, { "source": "ask", "target": "ask" } ], } ], # Data sources: types and names of the Session Managers defined in the # SMDS configuration file "dataSources": [ { "type": "CTASessionMgr", # type of the Session Manager "name": "cqs" # name of the session manager } ], # Market data subscriptions "subscriptions": [ { "dataSource": "cqs", # name of the datasource defined above "sym": "*", # wildcard subscription } ], }An example of a Refinitiv EMA listener that subscribes to Level 1 (MarketPrice domain) data from the DIRECT_FEED service of the provider and stores it in table MarketPrice:
"handler": { # Module name: Refinitiv EMA handler "name" : "emafeed", # Module-specific settings "config": { "configFile": "ema.xml" # name of the EMA configuration file }, # Database tables configuration "tables": [ { "type": "Quote", # Table contents' type: MarketPrice domain data"name": "MarketPrice", # Table name # Mapping of fields from the incoming data stream to the database table's columns "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "BID", "target": "BID" }, { "source": "ASK", "target": "ASK" } ], } ], # Data sources: data provider's services to request data from"dataSources": [ { "type": "", # Data source type: must be empty for EMA feeds "name": "DIRECT_FEED" # Service name } ], # Level 1 subscriptions (MarketPrice domain) "subscriptions": [ { "dataSource": "DIRECT_FEED", # Service name to request data from "sym": ["TRI.N","IBM.N","ACN.N"], # List of symbols to subscribe to"domain": "MarketPrice", # OMM MARKET_PRICE domain } ], }Putting It All Together
Below is a sample configuration file for a Refinitiv RFA handler using an in-memory eXtremeDB database. The handler subscribes to both Level 1 and Level 2 market data (MarketPrice and MarketByOrder domains). Please note that the settings must be adjusted according to the usage scenarios. Please also note that the RFA configuration file is not provided in this appendix.
A valid configuration file, along with an RFA configuration file, is also available in the target/feedhandler/scripts/TR_RFA subdirectory of the eXtremeDB for HPC package.
{ # Application settings "application": { "logging": [ # Print log messages with priorities "INFO" and above to the terminal { "type": "stdout", "level": "INFO" } ] }, # Handler module settings "handler": { # Module name: TR RFA module "name" : "trfeed", # Module-specific settings "config": { "useAppLog": "false", # Don't send RFA log messages to the Feed Handler application log "configPath": "./", # Directory containing RFA configuration file "configFile": "RFA.cfg", # Name of the RFA configuration file "sessionName": "RFA_session", # RFA session name (must correspond to the settings in # the RFA configuration file) "consumerName": "RFA_OMM_Consumer", # RFA consumer name "connStatsReportPeriod": 5, # Period of connection statistics reporting, seconds # Login settings "login": { "userName": "user1", # username "appId": "123", # application identifier }, }, # Database tables configuration "tables": [ { "type": "MarketPrice", # Table contents' type: MarketPrice domain data "name": "MarketPrice", # Table name # Mapping of fields from the incoming data stream to the database table's columns "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "RDN_EXCHID", "target": "RDN_EXCHID" }, { "source": "BID", "target": "BID" }, { "source": "ASK", "target": "ASK" } ], }, { "type": "MarketByOrder.Summary", # Table contents' type: # MarketByOrder domain summary data "name": "MarketByOrderSummary", # Table name # Mapping of fields from the incoming data stream to the database table's columns "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "CURRENCY", "target": "CURRENCY" }, { "source": "TRD_UNITS", "target": "TRD_UNITS" } ], }, { "type": "MarketByOrder.Entries", # Table contents' type: # MarketByOrder domain order data "name": "MarketByOrderEntries", # Table name # Mapping of fields from the incoming data stream to the database table's columns "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "orderId", "target": "orderId" }, { "source": "entryAction", "target": "entryAction" }, { "source": "ORDER_PRC", "target": "ORDER_PRC" }, { "source": "ORDER_SIDE", "target": "ORDER_SIDE" }, { "source": "ORDER_SIZE", "target": "ORDER_SIZE" }, { "source": "QUOTIM_MS", "target": "QUOTIM_MS" }, ], }, ], # Data sources: data provider's services to request data from "dataSources": [ { "type": "", # Data source type: must be empty for TR feeds "name": "DIRECT_FEED" # Service name }, ], # Level 1 and Level 2 subscriptions (MarketPrice and MarketByOrder domains) "subscriptions": [ { "dataSource": "DIRECT_FEED", # Service name to request data from "sym": ["TRI.N","IBM.N","ACN.N"], # List of symbols to subscribe to "domain": "MarketPrice", # OMM MARKET_PRICE domain }, { "dataSource": "DIRECT_FEED", # Service name to request data from "sym": "TRI.ARC", # Symbol to subscribe to "domain": "MarketByOrder", # OMM MARKET_BY_ORDER domain }, ], }, # Database configuration "database": { "transactionManager": "mvcc", # Transaction manager "useSharedMemory": "false", # Don't use shared memory "useDiskDatabase": "false", # Don't use disk database "databaseName": "RFA_inmem_db", # Database name "databaseSize": "1073741824", # Size of the database, bytes # RSQL server parameters "RSQLserver": { "enable": "true", # Enable RSQL server "port": 5001, # Port number for incoming RSQL connections }, }, }
Appendix B - Testing the Refinitiv EMA Handler Module Using the Feed Handler EMA Generator application
It is possible to use the bundled Generator application instead of a real market data feed for EMA handler evaluation purposes.
The Generator is a C++ application based on the EMA C++ Interactive Provider samples. It implements a simplistic OMM Provider that emits pseudo-random market data. The Feed Handler application can subscribe to this data stream and store it just like “real” data, which is useful for evaluating and learning to use the Feed Handler application.
Running the Generator
The Generator binary is available in the
$(MCO_ROOT)/target/feedhandler/EMA_redistributable/Generator
directory. It requires the RDM dictionary files (RDMFieldDictionary and enumtype.def) to run. These files can be obtained from the Elektron SDK distribution. Please place them in the Generator directory prior to running the application.A sample EMA configuration file,
EmaConfig.xml
, is available in the Generator directory. It will be used by the EMA runtime by default.Run the Generator application from the Generator directory:
./GeneratorIf the application launches successfully, the following line will be printed:
OmmProvider readyConfiguring the Feed Handler
As described in this document, the Feed Handler application itself needs a configuration file. Furthermore, the EMA framework module needs its own configuration file. Examples of these files are given in the sections below.
Feed Handler Application Configuration File
Create a plain text file named "feed.cfg" in the directory from which you will launch the Feed Handler application. You can use the following configuration for testing:
{ "application": { "logging": [ { "type": "stdout", "level": "INFO" } ] }, "handler": { "name" : "emafeed", "config": { "configFile": "ema.xml"}, "tables": [ { "type": "MarketPrice", "name": "MarketPrice", "fields": [ { "source": "RIC", "target": "RIC" }, { "source": "BID", "target": "BID" }, { "source": "ASK", "target": "ASK" } ], },], "dataSources": [ { "type": "", "name": "DIRECT_FEED" }, ], "subscriptions": [ { "dataSource": "DIRECT_FEED", "sym": "TRI.N", "domain": "MarketPrice" } ], }, "database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "true", "databaseName": "intradaydb", "databaseSize": "1073741824", "databaseFileName": "EMA.dbs","databaseLogFileName": "EMA.log","diskCacheSize": "1073741824","RSQLserver": { "enable": "true", "port": 5001 }, }, }Note a few important details.
- The handler.name parameter is set to “emafeed”, which corresponds to the Refinitiv EMA handler module
- The handler.config subsection contains important EMA-specific settings, such as the configuration file name (this file is discussed below)
- Only one table is defined; it is called MarketPrice and it will store the MarketPrice domain data emitted by the Generator
- The handler.dataSources subsection contains a single entry: “DIRECT_FEED” which corresponds to the only service that the Generator application provides by default
- The handler.subscriptions subsection lists a single subscription for the “TRI.N” symbol from the “DIRECT_FEED” service
- The database section defines a persistent database called “intradaydb” that will be stored in the “EMA.dbs” file and uses file “EMA.log” for the transaction log
- The database section defines the RSQL server which allows the user to access database contents
EMA Framework Configuration File
For detailed information on the EMA framework configuration file structure and contents, please refer to the EMA Configuration Guide (supplied with the EMA distribution archive).
As we have defined in the Feed Handler application file, the EMA configuration file must be named ema.xml. Create a plain-text file called “ema.xml” in the same directory as the “feed.cfg” file with the following contents:
<?xml version="1.0" encoding="UTF-8"?> <EmaConfig> <ConsumerGroup> <DefaultConsumer value="Consumer_1"/> <ConsumerList> <Consumer><Name value="Consumer_1"/><Channel value="Channel_1"/><Logger value="Logger_1"/><Dictionary value="Dictionary_1"/><XmlTraceToStdout value="0"/></Consumer><ConsumerList></ConsumerGroup><ChannelGroup><ChannelList><Channel><Name value="Channel_1"/><ChannelType value="ChannelType::RSSL_SOCKET"/> <CompressionType value="CompressionType::None"/> <GuaranteedOutputBuffers value="5000"/> <ConnectionPingTimeout value="30000"/> <TcpNodelay value="1"/> <Host value="localhost"/> <Port value="14002"/> </Channel></ChannelList> </ChannelGroup> <LoggerGroup> <LoggerList> <Logger> <Name value="Logger_1"/> <LoggerType value="LoggerType::Stdout"/> <LoggerSeverity value="LoggerSeverity::Success"/> </Logger> </LoggerList></LoggerGroup> <DictionaryGroup> <DictionaryList> <Dictionary> <Name value="Dictionary_1"/> <DictionaryType value="DictionaryType::ChannelDictionary"/> </Dictionary> </DictionaryList> </DictionaryGroup></EmaConfig>Note that the <Port> value corresponds to the port configured in the <Server> section of the Generator configuration file.
Discussion of all possible configuration keys and values is beyond the scope of this document. For more information please refer to the EMA Configuration Guide.
Running the Feed Handler
Once all configuration files are ready and the Generator is launched successfully, one can start the Feed Handler application. To start it from the command line, change the current directory to the one containing the feed.cfg and ema.xml configuration files and launch the fh binary:
/home/user/eXtremeDB/target/bin/fhIf no errors are reported, one can connect to the database using xSQL and examine the data being stored:
/home/user/eXtremeDB/target/bin/xsql @localhost:5001For more information on xSQL, refer to the eXtremeSQL Quick Start documentation.
Appendix C - Testing the Refinitiv RFA Handler Module Using the RFA Provider_Interactive Sample
It is possible to use the RFA Provider_Interactive sample (called “Provider” for brevity hereafter in this document) instead of a real market data feed for RFA handler evaluation purposes.
The Provider is a C++ application that is a part of the RFA C++ framework. It implements a simplistic OMM Provider that emits pseudo-random market data. The Feed Handler application can subscribe to this data stream and store it just like “real” data, which is useful for evaluating and learning to use the Feed Handler application.
Building the Provider
The Provider application can be found in the Examples/Provider_Interactive subdirectory of the RFA distribution. It must be built and run according to the instructions in its Readme file, as well as the RFA Readme file. In general, it is sufficient to:
- Extract the RFA distribution archive
- Configure dynamic linker bindings (pass actual path to the RFA shared libraries):
ldconfig -n /home/user/rfa8/Libs/RHEL6_64_GCC444
- Build RFA Provider_Interactive sample:
cd /home/user/rfa8/Examples/Provider_Interactive makeOnce the build process finishes, the binary can be found in a newly created subdirectory (typically named “RHEL6_64_GCC444”), alongside symbolic links to configuration files and dictionaries.
Configuring the Provider
Prior to launching the Provider application, one should edit its configuration files: ExampleRFA.cfg and Provider_Interactive.cfg. The former contains the session and connection parameters for the Provider (host, port, etc.). The latter file contains Provider-specific configuration (list of provided symbols, RDM domains, update frequency, etc.).
The Provider_Interactive.cfg file contains a line with Provider session name which will be needed a bit later, e.g.:
\Session = "SessionOMMProv"The ExampleRFA.cfg file contains settings for this session, alongside other settings:
[...] \Connections\Connection_OMMProv\connectionType = "RSSL_PROV" \Connections\Connection_OMMProv\rsslPort = "<rsslPort-for listening>" [...] \Sessions\SessionOMMProv\connectionList = "Connection_OMMProv"Note that the settings for the Provider’s session (called “SessionOMMProv”) are located in the \Sessions\SessionOMMProv branch of the configuration file (other Sessions for other examples are configured in this file as well). The connectionList configuration key contains the single connection for this session: Connection_OMMProv, whose parameters we need to change in the \Connections\Connection_OMMProv branch of this file.
The “rsslPort” parameter of the Connection_OMMProv must be set to an actual value instead of the placeholder. It must be set to any valid port value corresponding to an unoccupied TCP port on the machine (typically larger than 1023 on Linux systems); the Provider application will accept incoming connections on this port. Thus, this is the port the Feed Handler application will connect to.
For demonstration purposes, we set the port number to 30000:
\Connections\Connection_OMMProv\rsslPort = "30000"When the configuration is done, one can start the Provider by simply launching its executable file with the command line:
./provider_interactiveIf the Provider launches successfully, one will see a log output ending with text similar to this:
Logger message comes from: RSSL_Adapter Log Id: 10114 Event Type: 1 Message Text: [Tue Nov 10 17:00:00 2016]: (ComponentName) RSSL_Adapter: (Severity) Information: Connection "Connection_OMMProv" listen socketID 10 success on port 30000 Logger message comes from: RSSL_Prov_Adapter Log Id: 7012 Event Type: 1 Message Text: [Tue Nov 10 17:00:00 2016]: (ComponentName) RSSL_Prov_Adapter: (Severity) Information: Listen Connection Status Changed, Connection: Default::Connection_OMMProv State: Up StatusCode: None StatusText: Connection up Listen Connection Connection_OMMProv - Up: Connection upNote that the port number that we configured appears in the message above:
“Connection "Connection_OMMProv" listen socketID 10 success on port 30000”.
Configuring the Feed Handler
As described in this document, the Feed Handler application itself needs a configuration file. Furthermore, the RFA framework module needs its own configuration file. Examples of these files are given in the sections below.
Feed Handler Application Configuration File
Create a plain text file called “feed.cfg” in the directory from which you will launch the Feed Handler application. You can use the following configuration for testing:
{ "application": { "logging": [ { "type": "stdout", "level": "INFO" } ] }, "handler": { "name" : "trfeed", "config": { "useAppLog": "false", "configPath": "./", "configFile": "tr.cfg", "sessionName": "TR_app_session", "consumerName": "TR_OMM_Consumer", "connStatsReportPeriod": 5, "login": { "userName": "user1", "appId": "123" } }, "tables": [ { "type": "MarketPrice", "name": "MyMarketPrice", "fields": [ { "source": "DBTimestampSec", "target": "DBTimestampSec" }, { "source": "DBTimestampMicro", "target": "DBTimestampMicro" }, { "source": "RIC", "target": "RIC" }, { "source": "respTypeNum", "target": "respTypeNum" }, { "source": "RDNDISPLAY", "target": "RDNDISPLAY" }, { "source": "RDN_EXCHID", "target": "RDN_EXCHID" }, { "source": "DIVPAYDATE", "target": "DIVPAYDATE" }, { "source": "TRDPRC_1", "target": "TRDPRC_1" }, { "source": "BID", "target": "BID" }, { "source": "ASK", "target": "ASK" }, { "source": "ACVOL_1", "target": "ACVOL_1" }, { "source": "NETCHNG_1", "target": "NETCHNG_1" }, { "source": "ASK_TIME", "target": "ASK_TIME" }, ], } ], "dataSources": [ { "type": "", "name": "DIRECT_FEED" } ], "subscriptions": [ { "dataSource": "DIRECT_FEED", "sym": "TRI.N", "domain": "MarketPrice" }, ], }, "database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "true", "databaseName": "intradaydb", "databaseSize": "1073741824", "databaseFileName": "TR.dbs", "databaseLogFileName": "TR.log", "diskCacheSize": "1073741824", "RSQLserver": { "enable": "true", "port": 5001, }, }, }Note a few important details.
- The handler.name parameter is set to “trfeed”, which corresponds to the TR RFA handler module
- The handler.config subsection contains important RFA-specific settings, such as the configuration file name (this file is discussed below) and user name (corresponding to the Provider application’s configuration)
- Only one table is defined; it is called MyMarketPrice and it will store the MarketPrice domain data emitted by the Provider
- The handler.dataSources subsection contains a single entry: “DIRECT_FEED” which corresponds to the only service that the Provider application provides by default
- The handler.subscriptions subsection lists a single subscription for the “TRI.N” symbol from the “DIRECT_FEED” service
- The database section defines a persistent database called “intradaydb” that will be stored in the “TR.dbs” file and uses file “TR.log” for the transaction log
- The database section defines the RSQL server which allows the user to access database contents
RFA Framework Configuration File
For detailed information on the RFA framework configuration file structure and contents, please refer to the RFA Configuration Guide (supplied with the RFA distribution archive).
As we have defined in the Feed Handler application file, the RFA configuration file must be named tr.cfg. Create a plain-text file called “
tr.cfg
” in the same directory as the “feed.cfg
” file with the following contents:\Sessions\TR_app_session\connectionList = "Connection_TR_app" \Connections\Connection_TR_app\connectionType = "RSSL" \Connections\Connection_TR_app\rsslPort = "30000" \Connections\Connection_TR_app\hostName = "localhost" \Logger\AppLogger\useInternalLogStrings = TrueNote that the “
rsslPort
” value corresponds to the port we have set for the Provider. Also note that the session name (TR_app_session) corresponds to what we set in the Feed Handler application configuration file.Discussion of all possible configuration keys and values is beyond the scope of this document. For more information please refer to the RFA Configuration Guide.
Running the Feed Handler
Once all configuration files are ready and the Provider is launched successfully, one can start the Feed Handler application. To start it from the command line, change the current directory to the one containing the feed.cfg and tr.cfg configuration files and launch the fh binary:
/home/user/eXtremeDB/target/bin/fhIf no errors are reported, one can connect to the database using xSQL and examine the data being stored:
/home/user/eXtremeDB/target/bin/xsql @localhost:5001For more information on xSQL, refer to the eXtremeSQL Quick Start documentation.
Appendix D - Testing the Vela SMDS Handler Module Using Feed Data Dumps
The SMDS framework is able to “replay” binary dumps of market data traffic. This feature is useful for SMDS handler evaluation.
Market data “playback” is configured in the SMDS configuration file.
Configuring the Feed Handler
As described in this document, the Feed Handler application itself needs a configuration file. Furthermore, the SMDS framework needs its own configuration file. Examples of these files are given in the sections below.
Feed Handler Application Configuration File
Create a plain text file called “
feed.cfg
” in the directory from which you will launch the Feed Handler application. You can use the following configuration for testing:{ "application": { "logging": [ { "type": "stdout", "level": "INFO" } ] }, "handler": { "name" : "smdsfeed", "config": { "configPath": "./", "configFile": "config.xml" }, "tables": [ { "type": "Quote", "name": "MyQuotes", "fields": [ { "source": "symbol", "target": "symbol" }, { "source": "exchange", "target": "exchange" }, { "source": "DBTimestampSec", "target": "DBTimestampSec" }, { "source": "DBTimestampMicro", "target": "DBTimestampMicro" }, { "source": "bid", "target": "bid" }, { "source": "ask", "target": "ask" }, ], }, { "type": "Custom.CE_OPN_CLS_HG_LW_STL_PRICE", "name": "MyClosePrice", "fields": [ { "source": "symbol", "target": "symbol" }, { "source": "exchange", "target": "exchange" }, { "source": "CF_PREVCLOSE_PRICE", "target": "prevClosePrice" }, { "source": "CF_PREV_CLOSE_DATE", "target": "prevCloseDate" }, ], }, ], "dataSources": [ { "type": "CTASessionMgr", "name": "cqs" } ], "subscriptions": [ { "dataSource": "cqs", "sym": "*", }, ], }, "database": { "transactionManager": "mvcc", "useSharedMemory": "false", "useDiskDatabase": "true", "databaseName": "intradaydb", "databaseSize": "1073741824", "databaseFileName": "SMDS.dbs", "databaseLogFileName": "SMDS.log", "diskCacheSize": "1073741824", "RSQLserver": { "enable": "true", "port": 5001, }, }, }Note a few important details:
- The handler.name parameter is set to “smdsfeed”, which corresponds to the SMDS handler module
- The handler.config subsection contains the SMDS configuration file location (this file is discussed below)
- Two tables are defined; one is called MyQuotes and will store quote data, another is called MyClosePrice and will store custom event data provided in the SMDS custom events of type
CE_OPN_CLS_HG_LW_STL_PRICE
- The handler.dataSources subsection contains a single entry: “
cqs
” data source of type “CTASessionMgr” which corresponds to the SMDS CTA session manager- The handler.subscriptions subsection lists a single wildcard subscription for the “
cqs
” session manager- The database section defines a persistent database called “intradaydb” that will be stored in the “SMDS.dbs” file and uses file “SMDS.log” for the transaction log
- The database section defines the RSQL server that allows the user to access database contents
SMDS Framework Configuration File
For information on the SMDS framework configuration file structure and contents please refer to the SMDS User Guide.
As we have defined in the Feed Handler application file, the SMDS configuration file must be named “
config.xml
”. Create a plain-text file called “config.xml
” in the same directory as the “feed.cfg
” file with the following contents:<config> <License file="PATH_TO_THE_LICENSE_FILE" /> <MDLibraryList> <MDLibrary name="libmd-cta.so" /> </MDLibraryList> <Logger file="smds.log" level="debug" max-size-in-mb="300" /> <Resources> <Resource type="CTASessionMgr" name="cqs" lb-type="exchange-dictated" record="false" conn-type="file" pb-file="cqsE1-2015-11-03-4.1.0-record.1446568260.pb.gz" pb-buffer="1048576"> <MDConnections> <MDConnection max-record-size="1000" max-q-size="200000" name="CTA-GRP-2"> <MDLineHandler source="CQS" name="CQS-L1" primary-mc-channel="233.200.79.32:61032" secondary-mc-channel="233.200.79.48:61048"/> <MDLineHandler source="CQS" name="CQS-L2" primary-mc-channel="233.200.79.33:61033" secondary-mc-channel="233.200.79.49:61049"/> <MDLineHandler source="CQS" name="CQS-L3" primary-mc-channel="233.200.79.34:61034" secondary-mc-channel="233.200.79.50:61050"/> <MDLineHandler source="CQS" name="CQS-L4" primary-mc-channel="233.200.79.35:61035" secondary-mc-channel="233.200.79.51:61051"/> <MDLineHandler source="CQS" name="CQS-L5" primary-mc-channel="233.200.79.36:61036" secondary-mc-channel="233.200.79.52:61052"/> <MDLineHandler source="CQS" name="CQS-L6" primary-mc-channel="233.200.79.37:61037" secondary-mc-channel="233.200.79.53:61053"/> <MDLineHandler source="CQS" name="CQS-L7" primary-mc-channel="233.200.79.38:61038" secondary-mc-channel="233.200.79.54:61054"/> <MDLineHandler source="CQS" name="CQS-L8" primary-mc-channel="233.200.79.39:61039" secondary-mc-channel="233.200.79.55:61055"/> <MDLineHandler source="CQS" name="CQS-L9" primary-mc-channel="233.200.79.40:61040" secondary-mc-channel="233.200.79.56:61056"/> <MDLineHandler source="CQS" name="CQS-L10" primary-mc-channel="233.200.79.41:61041" secondary-mc-channel="233.200.79.57:61057"/> <MDLineHandler source="CQS" name="CQS-L11" primary-mc-channel="233.200.79.42:61042" secondary-mc-channel="233.200.79.58:61058"/> <MDLineHandler source="CQS" name="CQS-L12" primary-mc-channel="233.200.79.43:61043" secondary-mc-channel="233.200.79.59:61059"/> </MDConnection> </MDConnections> </Resource> </Resources> </config>Note that this file should be edited prior to launching the feed handler.
A few important details:
- A valid license file must be specified in the <License /> key (instead of the PATH_TO_THE_LICENSE_FILE placeholder)
- “libmd-cta.so” library is listed in the “MDLibraryList” section; this is an SMDS module that implements CTA support
- The CTASessionMgr session manager is defined in the <Resource> subsection of the <Resources> section; it is important that:
- The “name” parameter value (“cqs”) in the <Resource> section must correspond to the name of the data source defined in the “dataSources” section
- The “pb-file” parameter in the <Resource> section must point to a valid feed data dump file
- A number of <MDLineHandler> subsections are defined in the <MDConnection> section; these define addresses and ports of actual multicast channels and will vary from feed to feed
The SMDS configuration file is complex. Different session managers have different sets of supported settings. Discussion of all possible configuration keys and values is beyond the scope of this document. For more information please refer to the SMDS User Guide.
Running the Feed Handler
Once all configuration files are ready, one can start the Feed Handler application. To start it from the command line, change the current directory to the one containing the feed.cfg and config.xml configuration files and launch the fh binary:
/home/user/eXtremeDB/target/bin/fhWhen the Feed Handler application is started, it loads the SMDS framework, which, in turn, loads its configuration file and begins playback of the feed data dump file. The Feed Handler receives the records extracted from the data dump file and stores them in the database.
If no errors are reported, one can connect to the database using xSQL and examine the data being stored:
/home/user/eXtremeDB/target/bin/xsql @localhost:5001For more information on xSQL, refer to the eXtremeDB xSQL documentation.
Appendix E - Building the Feed Handler Application from Source Code
The Feed Handler application consists of the primary executable and loadable modules. All of these are built using a single makefile in the application’s root directory.
Prerequisites
In addition to the framework libraries required for the application to run, the corresponding C++ header files are required for compilation as well. These are included in the framework distribution archives supplied by their vendors.
Environment Variables
The environment variables must be set according to the instructions in the “Prerequisites” section of the “Getting Started” chapter.
If the
SMDS_ROOT
orRFA_ROOT
environment variables are not set, the corresponding handler modules will be skipped during the build process.Building the Application
When the third-party frameworks are prepared and the environment variables are set, one can build the Feed Handler simply by issuing make in the root folder of the application:
cd /home/user/eXtremeDB/target/feedhandler makeIf some Feed Handler modules should not be built, one can remove them from the
FEED_MODULES
list in the root makefile.On Windows, Visual Studio project files can be used to build the Feed Handler application and the modules.
Appendix F - Testing the Feed Handler Application Using the Test Data Provider
It's possible to use the provided test data provider with the Feed Handler application. It may be useful to evaluate software without any need for external dependencies, for assessing hardware, measuring hardware capabilities, etc.
The test provider can generate test trades and quotes. It will start a thread for each table, and perform inserts at maximum speed.
Generated tables and fields are:
Table Field name Data type Quote symbol string exch char qtime int8 bid float ask float bidsz int4 asksz int4 mode char Trade symbol string exch char ttime int8 price float size int4 stop bool condition char To use the test provider, include the following snippet into the feed handler configuration file:
# Market data handler module configuration "handler": { # Use Test generator "name" : "testfeed", # Database tables subsection "tables": [ # Table definition subsection for storage of quote data { # Type of the table. Depends on feed module. "type": "Quote", # Name of the table in the database "name": "MyQuotes", # Array of field mappings "fields": [ { "source": "symbol", "target": "symbol" }, { "source": "exch", "target": "exchange" }, { "source": "bid", "target": "bid" }, { "source": "ask", "target": "ask" }, ], }, # Another table definition subsection for storage of # trade data { "type": "Trade", "name": "MyTrades", "fields": [ { "source": "price", "target": "lastPrice" }, { "source": "size", "target": "lastSize" }, ], }, ], }This will load the test generator, define 2 tables in the output database and define some field mappings.
Appendix G - References
- RDM Usage Guide: available in the RFA C++ distribution archive, in Docs/RDMUsageGuide.pdf
- RFA Configuration Guide: available in the RFA C++ distribution archive, in Docs/RFA_ConfigGuide.pdf
- RFA Developers Guide: available in the RFA C++ distribution archive, in Docs/RFA_DevelopersGuide.pdf
- SMDS User Guide, SMDS API Guide: provided by Vela upon request