Académique Documents
Professionnel Documents
Culture Documents
GENEVA TRADING
980 N Michigan Avenue
Chicago, IL 60616
1
Index
1. Introduction
Purpose of SpreadTrader and its functionality
2. Background
Describes previous attempts
3. SpreadTrader 3.0
Architecture diagram and description of various components of the SpreadTrader
4. Spread
Architecture diagram and description of various components of a Spread
5. External I/O
6. Screen shots
Screen shots of various windows in SpreadTrader 2
A comparison
8. Basics of FIX
FIX Architecture
9. Sample Code
11. Conclusion
2
Introduction
The purpose of developing the SpreadTrader is to trade multi-instrument equity spreads at rapid speeds. It
is designed to provide higher quality execution while minimizing the execution risk. My intent is to
enable the trader to trade multiple spreads simultaneously and to be able to execute spreads at right prices.
I believe that this project will greatly reduce the execution risk resulting in increased profit and free the
user to explore a lot many opportunities in today’s markets. It will directly affect the way trading is
conducted in Maggiore Fund and the use of high end technology would give it an edge.
SpreadTrader essentially is an electronic eye which continuously monitors the equity markets and
computes the pre-defined spread prices. The execution algorithm is activated once certain conditions are
met. Execution of initiating leg is started. The balancing legs are closely monitored for any adverse
change in prices. Further execution depends on whether the right price can be achieved based on the price
of balancing leg and the size available. If initiating leg is filled, balancing leg is activated. The whole
process not only gets the correct price for the spread but also provides tremendous speed of execution.
Please note that execution algorithms can be customized as per the user requirements.
3
Background
Previous attempts of developing a similar system using other platforms are described below:
Although, scripting in VBA easier from a programming point of view, the speed of execution was
limited. Also, lack of multi-threading capabilities hampered the systems ability to trade multiple
spreads. Having said that, a basic SpreadTrader was built which could handle a 2-3 spreads with a
total of 15-20 stocks.
.NET offered both speed of execution and multi-threading capabilities which lacked in the previous
version. However, a new requirement of using Level 2 quotes was added to this SpreadTrader.
Surprisingly, Redi provides L2 data through DDE links which are not supported in .NET.
Additionally, speed with which SpreadTrader could send orders in .NET was restricted by Redi to 3-4
orders per second.
4
Spread Trader
SPREAD
FORM 1
CITRIUS® DYNAMIC
DATA
STORAGE
SEND
ORDERS ORDER
(SYNC) OUT
ORDER
EXECUTION
DATA
SPREAD
FORM n
FIX ENGINE
LIME SERVER
5
This is essentially a data source which is rapidly updated by Citrius®. A sort algorithm is used to
store the data in ascending (ask prices) and descending (bid prices) order. Stocks contained in this
data are added and removed after a spread is added or removed by the user. Technically, this is a
listener to the data providing API which is updated using RMI (remote method invocation). All the
technicalities are take care of by their class libraries. SpreadTrader simply adds a listener method.
(More on RMI: http://java.sun.com/javase/technologies/core/basic/rmi/whitepaper/index.jsp)
For basic information on Financial Information eXchange (FIX), please refer this.
FIX communication is essential for rapid execution. Orders are sent over the FIX server and status
messages are received at great speeds. SpreadTrader uses FIX for these basic operations. A FIX
engine is used to communicate with the LIME’s FIX server (Note: This is server is different from the
Citrius® server which only provides data). Technically FIX engine provides the required support on
session layer of the OSI model and it provides us with an interface at the Application layer. Later in
this document I explore this interface in detail. Please note that although FIX protocol is standardized,
the FIX API is not. Thus, although the functionality remains the same, syntax for different engines is
different. We may use following free, open source FIX engine but there are other available engines
which come at a cost.
6
QuickFIX/J:
QuickFIX/J is a full featured messaging engine for the FIX protocol. It is a 100% Java open source
implementation of the popular C++ QuickFIX engine. Essential features of this engine can be found
here: http://www.quickfixj.org/.
This stores the status messages of the orders sent in the market. This is a static data storage which is
updated at real time speed by the FIX server.
This is read by the spreads running at regular intervals for updates on the orders sent by the spreads.
Each order has a unique id called “SecurityIDSource” which is an encoded string used to identify the
spread that sent the order, long or short leg and the stock number. This greatly reduces the
computational efforts to sort out these messages. SecurityIDSource is attached to the order when it is
sent and it is basically “echoed” back through FIX.
This messenger is used to construct the FIX messages. Please refer sample codes in appendix to know
more about how a FIX message is constructed.
Synchronization of order-sending is achieved using this block of code. It would serialize the orders
when multiple spreads are active and send orders at the same time. It is only a precaution against any
thread-safety issues which “may” arise.
7
Blocks using
User settings
DYNAMIC
DDS of SPREADTRADER
DATA
STORAGE
BID / ASK
PRICES, SIZES
CALCULATOR
SPREAD
PRICES
MONITOR
BALANCING PRICE of
BALANCING LEG
LEG INITIATOR
ORDER EXECUTION
START
MONITORING
BALANCING LEG
EXECUTE
INITIATING
LEG
BALANCE To SEND ORDER
(SYNC)
FIX MESSANGER
CANCEL
UPDATE
INVENTORY
DATA UPDATE
SPREAD
DATA
8
Similar to the DDS of the SpreadTrader as a whole, every Spread has its own data storage which is
synchronously updated. It is a subset of the SpreadTrader’s DDS and it contains only those stocks
which are part of the concerned spread. Every spread runs a separate thread to delegate the task of
updating the data. This activity continues as long as the spread is open.
2. Calculator:
A calculator, as the name suggests, calculates the spread price using four combinations of bid and ask
prices of long and short legs of the spread. These combinations are Bid / Bid, Bid / Ask, Ask / Bid
and Ask / Ask. Intermediate steps involve calculating long leg on Bid and Ask and short leg on Bid
and Ask. Calculations are done for the sizes executable for each of these four combinations.
Following is the list of variables calculated synchronously by the calculator:
a. Bid a. Bid
b. Ask b. Ask
a. Bid a. Bid
b. Ask b. Ask
* (Except for sizes of long and short legs sizes every other variable is displayed in GUI)
3. Initiator:
A set of conditions are created based on the user settings (slops, quantity desired, algo trading etc).
These conditions are tested continually by the Initiator. When all the conditions are favorable,
Initiator creates two signals: -
A. Send initiating orders: Details of the initiating orders are sent to the FIX messenger.
9
This thread is started once the initiating orders are sent. The main purpose of MBL is to monitor the
price of the balancing leg. If the price of the spread (with fixed price of initiating leg and floating
price of balancing leg) falls out of the required range, MBL generates a signal to cancel the spread
and balances the spreads if the initiating leg is partially filled.
It also monitors the incoming messages from FIX server. After a certain percentage of the initiating
leg is filled, balancing leg orders are sent to hedge our market exposure.
MBL directly communicates with the FIX messenger to cancel orders or send new orders on the
balancing side.
Mandatory user settings with their default values are listed below:
ii. Order Settings: Order types for initiating and balancing leg for long and short side
iv. Inside and Outside slops (Default: ±3% of spreadPrice ± 10 cents for inside and
outside respectively)
10
External I/O
User Inputs:
Single Trade: A single buy or sell trade would require the user to enter the following data:
Stocks traded on any of the available exchanges can be traded using SpreadTrader.
Validation of availability can be done.
2. Corresponding ratios
An inside slop is used an upper limit on the spread price when one is buying the spread.
Similarly, outside slop is a lower limit on the spread price when the spread is being sold.
While buying the spread, outside slop is not required and while selling the spread inside
slop is not required.
4. Liquidity constraint
It is a proper fraction which is used to determine whether the quantity available on the
balancing side of the spread trader is sufficient to continue the trade. The quantity on the
balancing leg is actually divided by the liquidity constraint to obtain a much higher
quantity which is then compared with the required quantity on the balancing leg.
Maximum Inventory:
This input is used only when the algo trading options is selected. Algo trading is a
continuing process of buys and sells at the prices defined by the inside and outside slops.
Note that once the algo trading option is selected, both the inside and outside slops are
required. Once the price is right SpreadTrader would start executing spread until the
maximum inventory level is reached.
11
System Outputs:
1. When the spread is getting executed the user is notified of the execution progress through a
status bar.
2. Buying price and quantity, selling price and quantity along with the total inventory price and
quantity are displayed.
3. Also, a detailed report of the orders executed is also recorded in a data grid.
Screen Shots
1. Log in
12
2. New Spread:
3. Spread:
13
4. Execution:
5. Settings:
14
6. Order grid:
15
Previously we used REDI Plus for L1 data reception. There were two issues which have been solved
in this system.
a. L2 data was available with DDE links which are quite slow. This is not the case with
Citrius. It provides Level 2 data with tremendous speed in Java.
b. ActiveX controls used in REDI give data updates whenever anything associated with the
symbol changes. This results in unnecessary updates and waste of computational time. In
Citrius, I can subscribe to the fields I want updates on and thus this problem is avoided.
2. Interfaces used:
In REDI Plus, a single interface is used to receive data and to send orders. I believe they use a market
/order router which results in asynchronous time-multiplexing on a single thread. Thus, it reduces
speed. With Lime, I receive the data using Citrius API and sending orders and getting confirmations
is done through the FIX interface. Thus, multiprocessing can be achieved; not to mention it’s much
faster.
3. Order sending:
Speed with which orders can be sent on REDI is restricted to 3-4 orders/ second. On the other hand,
the FIX protocol can handle thousands of messages every second and supports basket orders which
enables us to buy or sell an entire leg (with multiple stocks) with a single message.
4. Simulation environment:
REDI Plus provides two exchange-traded dummy stocks which can be used for testing a program. But
since these two stocks are quite illiquid they are useless to test the speed of execution.
Lime provides a simulation environment wherein I can trade using fake money at real time speeds.
16
Basics of FIX
(Source: www.onixs.biz)
validates messages
17
FIX message:
Every FIX message consists of three parts. Headers and trailers are explained in the Basic information of
FIX. Following is an example of a FIX message:
8=FIX.4.0\u00019=86\u000135=D\u000149=0\u000156=0\u000134=1\u000152=999909
09-
17:17:17\u000111=90001008\u000121=1\u000155=IBM\u000154=1\u000138=100\u000
140=1\u000159=0\u000110=191\u0001";
Basic building block of the message is a “tag = value” pair. Following table shows some of the tags
usually used in an order message and their values:
Tag Value
ClOrdID 90001008 Unique identifier
Side 1 Buy
TimeInForce 0 Day
OrderType 1 Market
OrderQty 100 Quantity
Symbol IBM Ticker Symbol
In the message u0001 represents a Unicode character which serves as a separator in the tag=value format
of FIX.
e.g.
8 = FIX4.0
Tag 8 marks the beginning of every FIX message. Its value is the version of FIX being used.
9 = 86
Tag 9 follows tag 8. This contains the length of the FIX message; generated by the FIX engine.
38 = 100
18
Sample Code
Following code demonstrates the use of FIX engine. (I hope this helps to allay qualms about using FIX.)
Note that following code is written with QuickFix/ J in mind. Different FIX engines have different
syntaxes but same functionality.
Every FIX message has a header which identifies the FIX message and a trailer which is used for error
detection and possibly error correction.
1. Log in:
FIX protocol is used to communicate with Lime’s server. First step in client –server communication
is the Log in.
Header:
Body of Message:
Trailer:
2. Log out:
Header:
Body of Message:
Empty
Trailer:
19
3. Send Order:
Header:
Body of Message:
Trailer:
4. Cancel Order:
Header:
Body of Message:
Trailer:
20
Code that creates these messages by employing the API of the FIX engine:
Import QuickFix.*;
1. Log in
Header:
Trailer:
2. Log out:
Only thing different in the log out message is the type of Message field (i.e. tag 35) which is set
to “5” indicating that it’s a log out message.
Header:
21
3. Send order:
Header:
Body:
Trailer:
4. Cancel Order:
Header:
Body:
Trailer:
After the message is constructed, it is sent through the FIX engine using the active “Session”
Session.sendToTarget(message);
Here the target is the Lime Server: IP: 12.189.151.195 Port: 7000
22
Session.sendToTarget(message); b = hOrder.Submit(myerr)
As you can see, the only difference between using FIX and using REDI is the use of a FIX engine object
“Message” and use of a CacheControl object in REDI for the order construction. Technically, the client
side of LIME consists of the FIX engine and the client side of REDI is defined by its Interop.REDI
library. The application has to make use of the API of these “stubs” and “skeletons”.
23
In order to understand the difference between the two, let’s first look at the basic structure of a
Distributed Object Communication.
REDI:
Both the stubs and skeleton are implemented by GS and the CacheControl object class can invoke
methods on their server and similarly their server can invoke methods on the CacheControl object. Since
they only provide the limited API of this model (Class library: Interop.Redi), we do not know how the
communication takes place. Usually the data associated with “caller” is serialized into byte-streams and
then sent over the network.(TCP/IP) But the protocol used to define the streaming data, sent over the
network, is unknown to us and will remain so.
LIME:
We know that FIX protocol is used to communicate with the Lime server which then relays the order to
the desired exchange. The stub and skeleton shown in the diagram are implemented in the FIX engine.
(Stub in our engine and skeleton in their).We can select the network but I think TCP / IP would suffice
given that we do not generate enough volume. Also, note that Citrius® is more like REDI (although it
provides L2 data) but the Citrius API and FIX API are different. Thus, FIX is used only for order
execution and management and not for market quotes.
24
Conclusion
Addition of FIX technology to the SpreadTrader not only improves the speed of execution but also
separates out the “GetData” and “SendOrder” functions which are at the heart of this system. This
improves the overall stability of the application. Although, a large amount of Level 2 data is to be handled
in this system, efficient use of multiple threads enables us to compute number of spread prices at any
given time (on different threads, of course.)
The application can be loosely separated into three parts:
The first part is implemented solely in Java and is not much different than any other third party API.
However, this API (called Citrius®) has many more functions compared to REDI (Refer the Comparison
of SpreadTrader 3.0 vs. SpreadTrader 2.)
Second part reads the live data from Dynamic data storage of the main program, to compute spread prices
and spread sizes. Note that every spread runs on a different thread, thus computations are carried out
independent of each other. All the basic data types in Java are thread-safe for “reading” and “writing” is
done by a single thread (which deals with Citrius®)
The FIX engine works on a lower level (sessions level) and performs the functions necessary to make the
FIX protocol compatible with Java program ( Refer the Functions of FIX engine.) Please note that FIX
communication takes place in “text format” but our program is concerned with only the application level
interface of the FIX engine. We don’t engage in using FIX protocol ourselves; another program (i.e. FIX
engine) does it for us.
25