Using the WSO2 ESB and FIX

Archived Content
This article is provided for historical perspective only, and may not reflect current conditions. Please refer to relevant product page for more up-to-date product information and resources.
  • By Asanka Abeysinghe
  • 16 Jul, 2008

Applies To

WSO2 ESB 1.7
Apache Synapse 1.2

Table of Contents

Introduction

Messaging and transport plays a major role in financial application development. Developing a sophisticated messaging and transport layer is always a challenge in the development of financial applications. Typically, a financial application environment is built with several applications integrated running both internally and externally. We call these components self-contained services. Different services may use different messaging formats with support for different transport media.

Due to these challenges, a common messaging and transport framework is impotent for the financial application developer. The WSO2 ESB comes as a good fit for such a framework, as it supports message routing, smart routing, transformation and persistence.

Abbreviations

FIX (Financial Information eXchange)

FIX is an open specification intended to streamline electronic communications in the financial industry. FIX was initiated in 1992, for equity trading between 'Fidelity Investment' and 'Salomon Brothers'. FIX is governed by fixprotocol.org. FIX messages are constructed with name value pairs that contains a standard header, a body and a trailer. FIX header contains a message type (tag 35) property, to differentiate between messages. FIX messages can be divided into two main categories; they are administration messages and application messages.

FIX communicates by creating sessions between FIX engines. FIX engines use a slimilar model to RM (Reliable Messaging), in that it enables message recovery through sequence numbers attached to messages.

Users benefit by using FIX due to many reasons. FIX specifications are open and free. Therefore, its usage dose not cost the user. FIX is a widely used protocol among every major stock exchange, investment banks, world's largest mutual funds and money managers. Thousands of small investment firms use FIX. FIX supports derivatives like equity, options, FOREX (Foreign Exchange) and fixed incomes, like bonds.

Sample FIX message: Buy 1000 DELL @ MKT

8=FIX.4.0#9=105#35=D#34=2#49=BANZAI#52=20080711-06:42:26#56=SYNAPSE#11=1215758546278#21=1#38=1000#40=1#54=1#55=DELL#59=0#10=253

AMQP (Advanced Message Queuing Protocol)

AMQP is and open protocol for business messaging. AMQP was initiated in 1994 by JPMorgen & Chase Co,. iMatix had a parallel development on Java and C/C++. AMQP is popular in the financial community as a high performance and a reliable middleware solution. There are several AMQP implementations that include OpenAMQ, Apache QPid, RabbitMQ and ZeroMQ. The WSO2 ESB AMQP transport is built using Apache Qpid.

FIX Transport Implementation in WSO2 ESB



 

FIX implementations are done in the transport layer of the WSO2 ESB. Incoming FIX messages comes to a FIX acceptor connection that runs inside a Quickfix/J FIX engine. FIX transport transforms incoming FIX message to a XML infoset. XML infoset is the internal data representation of the original FIX message.

The WSO2 ESB FIX transport layer creates initiator session(s) to dispatch out going FIX messages to external FIX acceptor endpoints. Based on the address endpoint configuration in the ESB configuration, messages will route by handover to the relevant session.

If messages are expected to be dispatched or retrieved through other transport layers, an XML infoset will be handover or generated from the relevant transport implementation.

The WSO2 ESB has implemented the FIX transport layer using a leading open source FIX implementation known as QuickFIX. The Java implementation of QuickFIX is: Quickfix/J.  

FIX Usage with WSO2 ESB - Scenarios

Bridge FIX to HTTP

Business Use Case

FIX messages generated from a FIX-IN source to a Web service hosted in a HTTP based Web application server. FIX-IN source will generate orders, submissions and order instructions such as order amend/cancel, replace and order cancellations. An Order Blotter, OMS (Order Management System), OR (Order Router), ETS (Electronic Trading System) can act as sample FIX-IN sources. Web services that accepts orders can be an OMS, Exchange, an OR or an ETS. Web services that accepts Orders/Submissions/Order instructions will send the executions, acknowledgments and corrections back to the WSO2 ESB via HTTP and the ESB will send these messages to the original FIX endpoint.

System Use Case

WSO2 ESB accepts FIX messages through FIX acceptor session(s), converts message(s) to XML infosets and creates relevant SOAP message(s) based on the ESB configuration.

Example

In this example, FIX messages are generated from the default order blotter that comes with the Quickfix/J bundle "Banzai" and sends these messages to the placeOrder sample Web service hosted in the Axis2 Server. ESB configuration for a sample scenario will look like the following synapse.xml file. To configure the ESB to support FIX, please refer instructions listed in the WSO2 ESB 1.7 documentation.

 

synapse.xml

<definitions xmlns="https://ws.apache.org/ns/synapse">
	<localEntry key="xslt-key-req"
		src="file:repository/conf/sample/resources/transform/fixtransform.xslt" />	
	<proxy name="FIXProxy" transports="fix">
		<target>
			<endpoint>
				<address
					uri="https://localhost:9000/soap/SimpleStockQuoteService" />
			</endpoint>
			<inSequence>
				<log level="full" />
				<xslt key="xslt-key-req" />
				<log level="full" />
			</inSequence>
			<outSequence>
				<log level="full" />				
			</outSequence>
		</target>
		<parameter name="transport.fix.AcceptorConfigURL">
			file:repository/conf/fix-synapse.cfg
		</parameter>
		<parameter name="transport.fix.AcceptorMessageStore">
			file
		</parameter>
		<parameter name="transport.fix.InitiatorConfigURL">
			file:repository/conf/synapse-sender.cfg
		</parameter>
		<parameter name="transport.fix.InitiatorMessageStore">
			file
		</parameter>
	</proxy>
</definitions>

fixtransform.xslt

<xsl:stylesheet version="2.0"
	xmlns:xsl="https://www.w3.org/1999/XSL/Transform"
	xmlns:fn="https://www.w3.org/2005/02/xpath-functions">
	<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
	<xsl:template match="/">
		<m0:placeOrder xmlns:m0="https://services.samples/xsd">
			<m0:order>
				<m0:price><xsl:value-of select="//message/body/field[@id='44']"/></m0:price>
				<m0:quantity><xsl:value-of select="//message/body/field[@id='38']"/></m0:quantity>
				<m0:symbol><xsl:value-of select="//message/body/field[@id='55']"/></m0:symbol>
			</m0:order>
		</m0:placeOrder>
	</xsl:template>
</xsl:stylesheet>

Bridge FIX to AMQP

Business Use Case

FIX messages generated from a FIX-IN source send to order acceptance source that communicates via AMQP. The FIX in source can be a Blotter, OMS or a ETS and service can be again a OMS, OR or an ETS.

System Use Case

The WSO2 ESB accepts FIX messages through FIX acceptor session(s), converts messages to internal XML infoset, loads message payloads to an AMQP message and dispatch to a given Queue/Topic that has already initialized in a AMQP broker.

Example

In this example, a FIX message generated from "Banzai" is sent to an AMQP message consumer through the WSO2 ESB. The consumer application generates executions (full-fill received order) and the WSO2 ESB sends the execution/fill back to the blotter.

synapse.xml

<definitions xmlns="https://ws.apache.org/ns/synapse">
	<localEntry key="xslt-rem-ns"
		src="file:repository/conf/sample/resources/transform/fix-rm-ns.xslt" />
	<proxy name="FIXProxy" transports="fix">
		<target>
			<endpoint>
				<address uri="jms:/QpidStockQuoteService?transport.jms.ConnectionFactoryJNDIName=qpidConnectionfactory&amp;java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFactory&amp;java.naming.provider.url=/home/asankaa/workspace/synapse-1.2-test/repository/conf/server.properties&amp;transport.jms.ReplyDestination=replyQueue"/>     									
			</endpoint>
			<inSequence>		
				<log level="full" />
			</inSequence>
			<outSequence>
			<property name="transport.fix.ServiceName"
					value="FIXProxy" scope="axis2-client" />			
				<log level="full" />
				<xslt key="xslt-rem-ns" />	
				<send />
				<log level="full" />
			</outSequence>
		</target>
		<parameter name="transport.fix.AcceptorConfigURL">
			file:repository/conf/fix-synapse.cfg
		</parameter>
		<parameter name="transport.fix.AcceptorMessageStore">
			file
		</parameter>
		<parameter name="transport.fix.InitiatorConfigURL">
			file:repository/conf/synapse-sender.cfg
		</parameter>
		<parameter name="transport.fix.InitiatorMessageStore">
			file
		</parameter>
	</proxy>
</definitions>

server.properties

#initial context factory

#java.naming.factory.initial =org.apache.qpid.jndi.PropertiesFileInitialContextFactory

# register some connection factories

# connectionfactory.[jndiname] = [ConnectionURL]

connectionfactory.qpidConnectionfactory=amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'

# Register an AMQP destination in JNDI

# destination.[jndiName] = [BindingURL]

destination.directQueue=direct://amq.direct//QpidStockQuoteService

fix-rm-ns.xslt

<xsl:stylesheet version="1.0"
	xmlns:xsl="https://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" indent="no" />

	<xsl:template match="/|comment()|processing-instruction()">
		<xsl:copy>
			<xsl:apply-templates />
		</xsl:copy>
	</xsl:template>

	<xsl:template match="*">
		<xsl:element name="{local-name()}">
			<xsl:apply-templates select="@*|node()" />
		</xsl:element>
	</xsl:template>

	<xsl:template match="@*">
		<xsl:attribute name="{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
	</xsl:template>
</xsl:stylesheet>

 

Switch between FIX Versions

Business Use Case

In a trading environment there can be applications accepting different FIX versions. There can be FIX-IN sources send messages belonging to different FIX versions and there can be FIX-OUT sources that needs to send messages out in different FIX versions.

System Use Case

The WSO2 ESB accepts FIX input via the FIX transport layer and dispatches to another FIX acceptor that accept messages in a different FIX version. e.g. FIX 4.2 to FIX.4.4. The WSO2 ESB converts incoming message using a configured transformation mediator and uses the outgoing FIX session to create the FIX message header. XSLT mediator, script mediator or a POJO can be used to transform the message. An alternate approach to implementing the bridge, is to use compatible FIX specs/data-dictionary in the endpoint FIX engines. As an example, execution message (35=8) of FIX4.0 does not contain tag 150(ExecType) and 151(LeavesQty). Tag 150 and 151 are mandetory fields of FIX4.1, to switch messages from version 4.0 to 4.1 and get the executions back, user can add the tag 150 and 151 to the FIX4.0 specification as optional fields.

Example

In this example messages comming from "Banzai" with FIX4.0 will be send to the "Executor" that act as the order acceptor that accept messages in FIX4.1 format. Banzai is using a custom FIX sepcification by making FIX engine to accept 4.1 messages.

synapse.xml

<definitions xmlns="https://ws.apache.org/ns/synapse">
   <proxy name="OrderProcesserProxy41" transports="fix">
      <target>
         <endpoint>
            <address uri="fix://localhost:19877?BeginString=FIX.4.1&amp;SenderCompID=SYNAPSE&amp;TargetCompID=EXEC"/>
         </endpoint>
         <inSequence><log level="full"/></inSequence>
         <outSequence><log level="full"/><send/></outSequence>
      </target>
      <parameter name="transport.fix.AcceptorConfigURL">file:repository/conf/fix-synapse-m40.cfg</parameter>
      <parameter name="transport.fix.AcceptorMessageStore">file</parameter>               
      <parameter name="transport.fix.InitiatorConfigURL">file:repository/conf/synapse-sender-m.cfg</parameter>
      <parameter name="transport.fix.InitiatorMessageStore">file</parameter>          
   </proxy>    
</definitions>

fix-synapse-m40.cfg

[default] 
FileStorePath=E:\etc\data\store\synapse
FileLogPath=E:\etc\data\log\synapse 
ConnectionType=acceptor 
StartTime=00:00:00 
EndTime=00:00:00 
HeartBtInt=30 
ValidOrderTypes=1,2,F 
SenderCompID=SYNAPSE 
TargetCompID=BANZAI 
UseDataDictionary=Y 
DefaultMarketPrice=12.30 
SendResetSeqNumFlag=Y

[session] 
BeginString=FIX.4.0 
SocketAcceptPort=9876
DataDictionary=/home/asankaa/etc/spec/FIX40-synapse.xml

 

synapse-sender-m.cfg

[default] 
FileStorePath=E:\etc\data\store\synapse-sender
FileLogPath=E:\etc\data\log\synapse-sender 
StartTime=00:00:00 
EndTime=00:00:00 

HeartBtInt=30 
ReconnectInterval=5
SendResetSeqNumFlag=Y

CBR (Content Based Routing) of FIX Messages 

Business Use Case 

On a trading platform, incoming FIX messages need to route to deferent destinations based on conditions. As an example, consider multiple OMSs running services for a set of symbols and listening to a MDD (Market Data Distribution) Server that publish market data only for defined symbols. In such a situation, FIX messages need to be routed based on symbols (tag 55) and sent to relevant OMS instances. Another example will be route orders based on the side (buy/sell) and all the buy orders will ve accepted by one OMS and sell orders by another.

Users can implement a simple EDA (Event Driven Architecture) that the WSO2 ESB acts on, as the event processing engine. User can send requests such as fill order, partially fill orders, rejected, cancel and new orders to different event queues listed as endpoints.

User can use any available tag and perform CBR by implementing a simple rule.

System Use Case

The WSO2 ESB takes incoming FIX messages through the FIX transport layer and route messages based on user configuration. Based on conditions defined by a switch/case statement and a regex, the value to be compared will be fetched using a simple XPath statement (that navigates through the XML infoset to find the value).

Example

Example describes routing messages by symbol (tag 55), to define endpoints. If 2 switch messages come tagged with 'IBM' and 'MSFT' to two define endpoints, the sample keeps the default switch blank for the system to ignore messages with other symbols. Alternatively, we could define an endpoint in the default block in order to route the rest of messages to another endpoint.

synapse.xml

<definitions xmlns="https://ws.apache.org/ns/synapse">
	<sequence name="proxy_1">
		<in>		
				<switch source="//message/body/field[@id='55']">
					<case regex="IBM">
					<send>
						<endpoint>
							<address
								uri="fix://localhost:19876?BeginString=FIX.4.0&amp;SenderCompID=SYNAPSE&amp;TargetCompID=EXEC" />
						</endpoint>
						</send>
					</case>
					<case regex="MSFT">
					<send>
					<endpoint>
						<address
							uri="fix://localhost:19877?BeginString=FIX.4.1&amp;SenderCompID=SYNAPSE&amp;TargetCompID=EXEC" />
					</endpoint>
					</send>
					</case>
					<default></default>
				</switch>			
		</in>
		<out>
			<send />
		</out>
	</sequence>
	<proxy name="FIXProxy" transports="fix">
		<target inSequence="proxy_1" />
		<parameter name="transport.fix.AcceptorConfigURL">
			file:repository/conf/fix-synapse.cfg
		</parameter>
		<parameter name="transport.fix.AcceptorMessageStore">
			file
		</parameter>
		<parameter name="transport.fix.InitiatorConfigURL">
			file:repository/conf/synapse-sender.cfg
		</parameter>
		<parameter name="transport.fix.InitiatorMessageStore">
			file
		</parameter>
	</proxy>
</definitions>

Bridge Between Data Services and FIX

Business Use Case

Data Services, is a mechanism to expose data stored in persistence storage as Web service(s). In a trading environment, orders/submissions/order instructions may be stored in persistence storage for various reasons and needs conversion to FIX format in order to post them to other system. A typical scenario is where GTC (good till cancel) and GTD (good till date) orders are stored in a persistence storage after the end-of-the-day process, if the orders are still in 'active' state. These stored orders need to be posedt to the market on the following day during the pre-trading session, where stored data needs to be converted to the FIX format before they are sent to their relevant endpoints. Data services will provide order/submission/order instructions information using a get<DS> method and are able to update acknowlegements/executions(fills)/corrections coming from the other end using a set<DS> method.

System Use Case

The WSO2 ESB use a trigger-mechanism that is self initiated to define intervals to call data services hosted externally to a Web application server. Data coming through a data service will be converted to FIX message/s and dispatched to the relevant FIX endpoint. User can split data sets into several 'Order Single' (35=D) messages using the aggregate pattern in the WSO2 ESB, or, alternatively send as a batch order 'Order List' (35=E) to the FIX destination.

Data services can be hosted in any Web application server that supports DS. The WSO2 Web Services Application Server (WSAS) offers full support for data services. Any RDBMS (Relational Database Management System) with JDBC (Java Database Connectivity), CSV (Comma Separated Values) files or Microsoft Excel files can act as persistence storage in such scenarios.

Example

In this example, a DS call, getEquity, is made to WSAS that use an embedded 'Derby' database as persistance storage. Derby database contains an Order table. The WSO2 ESB calls the DS in given time intervals.The result is then handed over to the FIX transport layer. FIX transport layer converts the XML message payload coming from DS to FIX, which then dispatches it to the target FIX endpoint.

synapse.xml

<definitions xmlns="https://ws.apache.org/ns/synapse">
	<!-- XSLT file to transform the message input from the DS -->
	<localEntry key="xslt-fix"
		src="file:repository/conf/sample/resources/transform/fixtransform-ds.xslt" />


	<sequence name="FIXInsequence">
		<log level="full" />
		<xslt key="xslt-fix" />
		<log level="full" />
		<send>
			<endpoint key="FIXTRNS" />
		</send>
	</sequence>


	<sequence name="errorHandler">
		<log level="full" separator="," />
	</sequence>
	<!-- Proxy to call the data service running on external WS -->
	<proxy name="FIXDataServiceProxy" startOnLoad="true">
		<target outSequence="FIXInsequence"
			faultSequence="errorHandler">
			<endpoint>
				<address
					uri="https://localhost:9762/services/DataServiceSample1" />
			</endpoint>
		</target>
	</proxy>

	<task name="fetchDataFromTxnDB"
		class="org.apache.synapse.startup.tasks.MessageInjector">
		<trigger cron="0 0/1 * * * ?" />
		<property name="message">
			<p:getEquities xmlns:p="https://ws.wso2.org/dataservice" />
		</property>
		<property name="soapAction" value="urn:getEquities" />
		<property name="to"
			value="https://localhost:8280/soap/FIXDataServiceProxy" />
	</task>
	<in>
		<send />
	</in>

	<!-- Proxy to Send the FIX message out -->
	<proxy name="FIXTransportProxy">
		<target>
			<endpoint>
				<address
					uri="fix://localhost:19876?BeginString=FIX.4.0&amp;SenderCompID=SYNAPSE&amp;TargetCompID=EXEC" />
			</endpoint>
			<inSequence>
				<property name="transport.fix.ServiceName"
					value="FIXTransportProxy" scope="axis2-client" />			
				<log level="full" />			
			</inSequence>
			<outSequence>
				<log level="full" />
			</outSequence>
		</target>
		<parameter name="transport.fix.InitiatorConfigURL">
			file:repository/conf/synapse-sender.cfg
		</parameter>
		<parameter name="transport.fix.InitiatorMessageStore">
			/home/asankaa/var/data/store
		</parameter>
	</proxy>

	<endpoint name="FIXTRNS">
		<address
			uri="https://localhost:8280/soap/FIXTransportProxy"/>
	</endpoint>
</definitions>

Summary



The WSO2 ESB accepts orders, submissions and order instructions on protocols such as FIX, AMQP, HTTP and  dispatches them to endpoints that accept messages using FIX, AMQP, HTTP protocols. The WSO2 ESB is able to route, smart route, transform and persist incoming messages based on user configurations. Users can use the Web-based GUI to configure scenarios, where the user-friendly graphical interface provides rich functionality to configure, manage and monitor activities. Users can handover message transformation and transport to the WSO2 ESB and concentrate on the business logic of such applications.

The WSO2 ESB 1.7 provides FIX and AMQP transport support - the two widely used protocols in the financial community. Performance is a key element in financial applications. ESB performance results prove that the WSO2 ESB is far ahead of others out there in the market!

References

[1] WSO2 ESB Samples Guide - https://wso2.org/project/esb/java/1.7/docs/ESB_Samples.html

[2] WSO2 ESB Samples Setup Guide - https://wso2.org/project/esb/java/1.7/docs/ESB_Samples_Setup.html

[3] WSO2 ESB Configuration Language Guide - https://wso2.org/project/esb/java/1.7/docs/ESB_Configuration_Language.html

Author

Asanka Abeysinghe is a Software Architect at WSO2. asankaa at wso2 dot com

https://www.asankama.com

About Author

  • Asanka Abeysinghe
  • VP, Solutions Architecture
  • WSO2, Inc