State of the Nation

Posted by Russ Williams on Sunday, 8th February 2009 at 21:49 GMT
Comments (2) | Reply
Well, that's about it for the weekend...

The FIX part seems reasonably robust, but still isn't doing much validation. The network part is fairly basic, but works. The exchange... well... it's OK for a single client, but seems to have some issues with concurrency and can occasionally deadlock.

I've had two clients trading with each other, and I've learned a lot about the protocol - and been surprised by how little documentation is available for some of this. Which is as much as I could have hoped for in a weekend, really.

The biggest tasks still to handle are:

  • * Validation of the FIX messages

  • * The remainder of the FIX4.0 standard

  • * A proper multithreaded exchange

  • * Rearranging the code into subpackages

  • * Implementing the FIX4.1 and 4.2 protocols



As promised, the code - such as it is - is available here. I've decided to call it FIXME as a pun on the protocol and the state of the code. I'm releasing it as public domain, so if - God forbid - anyone wants the code, they can have it without attribution.

Order entry

Posted by Russ Williams on Sunday, 8th February 2009 at 18:53 GMT
No comments yet | Reply
Well, the client can now put orders (New Order - Single, message type "D") into the exchange... sadly this is a bit useless as it's only able to trade against itself at the moment.

Next step is to put in execution reports (type "8", spammed to all clients) and we should be getting somewhere.

... as the client said to the server!

Posted by Russ Williams on Sunday, 8th February 2009 at 17:14 GMT
No comments yet | Reply
Today I've spent quite a lot of time trying to make the repeated groups work neatly, and it's just about there now.

Far more importantly, I've integrated the FIX stuff with the network stuff and have a working logon sequence:

Constructing FIX engine: CLIENT
About to send: 8=FIX.4.0|9=42|35=A|49=CLIENT|56=SERVER|34=1|98=0|108=30|10=186|
Got a message of type A
Handling logon message
BeatingHeart constructor(delay = 4 seconds)
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=2|10=142|
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=3|10=143|
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=4|10=144|
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=5|10=145|
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=6|10=146|
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=7|10=147|
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=8|10=148|
Got a message of type 0
About to send: 8=FIX.4.0|9=30|35=0|49=CLIENT|56=SERVER|34=9|10=149|
About to send: 8=FIX.4.0|9=31|35=0|49=CLIENT|56=SERVER|34=10|10=190|


That output is currently missing 52 (SendingTime) tags, but that's easy enough to put in. There are two heartbeat threads running - one giving the server a kick (message type "0") every 4 seconds, and one doing the same to the client every 30, as specified by the logon ("A") messages.

So, now to connect this to my order book...

Exchanging Places

Posted by Russ Williams on Saturday, 7th February 2009 at 22:10 GMT
No comments yet | Reply
Woo! After some rather fiddly code, I now have an order book working.

Most of the problems seemed to come about from having to handle (near-)empty bid/offer lists at the start of the day's trading - if your first orders are a market-buy and a market-sell, at what price do you match them?

So, anyway, I've got an order book class for a single stock, which supports market/limit/stop/stop-limit order types and (I hope) correctly handles priority with unblocking stop orders.

For time, I've decided to use a (lock-protected) serial number: every order that comes in locks/increments/unlocks the timer, forcing serialisation of requests. None of this two-orders-the-same-age business!

Obviously generalising this to a full exchange is as simple as creating a collection of order books - load balancing isn't an issue when cheating at toy problems ;-)

So, about the biggest thing I'm missing now is the session - the network layer is there, as is the FIX engine, and now the server-side (and even some basic client-side) of the trades. Time to glue it all together!


I figure there's now about a month's work on my "TO DO" list just to get this stuff up to a decent standard, but my goal for the weekend was to have a couple of clients making random trades on a toy exchange, which is certainly looking plausible.

Round trip!

Posted by Russ Williams on Saturday, 7th February 2009 at 14:30 GMT
No comments yet | Reply
OK, so now I've got messages doing round trips between strings and my internal data model (in fact, string -> data -> string -> data -> string for verification). Yay!

The string in question is:
"8=FIX.4.0|9=65|35=A|49=SERVER|56=CLIENT|34=177|52=20090107-18:15:16|98=0|108=30|10=060|"
with the |s replaced by SOH (\u0001) characters.

I've implemented all 139 field types (1~140, with 101 undefined) in the FIX4.0 specification, using a type hierarchy derived from the 5.0SP1 spec, though only for basic static checking - almost no validation yet. Dynamic checking (e.g. "tag 64 required when tag 63=6 or 63=8, but optional otherwise") will add a fair chunk of work, so I'm leaving that for now. Repeated groups are supported but need a little tidying up in the parser.

Next big tasks on the horizon are the session model (logon, heartbeats, responding to requests, termination) and implementing an order book for the exchange.

But, for now, I'm having a beer. Black Sheep - Riggwelter (5.7% abv), in fact.

FIX woes

Posted by Russ Williams on Friday, 6th February 2009 at 20:55 GMT
No comments yet | Reply
Well, I've got a very basic parser running. A "Doctrine" module that sets up the field types and relations, a generic tag parser, a top-level message-to-string/string-to-message interface... and a lot of duct tape.

I shall probably be changing to the 4.2/later basic field types, they appear to be more specific than the 4.0 types (e.g. Qty can be an integer or a float, rather than just a float which should be an integer if referring to countable items; String and Char as separate types), assuming this won't break compatibility.

Repeating groups will cause some slight difficulty, but I think I've got a solution that handles them well... even for the arbitrarily-repeated 46 (related symbol) and repeated-group-within-a-repeated-group 92 (broker of credit) tags.

The most irritating thing, however, is the complete lack of a simple verification test for the checksum. The 4.1 examples on the site acknowledge this, the 4.2 examples on the Wikipedia page and in the 5.0SP1 spec do not. One even claims a body length (tag 9) of 67 when it's closer to 220!

So, yes, clearly some basic test data would be a Good Thing. I shall provide some.

And the code? Java (J2SE) 1.5, and it'll be available here for free next week. Still a lot more to write!

Network!

Posted by Russ Williams on Thursday, 5th February 2009 at 19:10 GMT
No comments yet | Reply
Well, that's the easy-but-annoying part done for now: a client that opens a TCP socket and starts sending text, and a multithread server listening on a port spawning worker threads for each client connection to echo the messages back.

Slight issue in that an abnormal termination of any client causes the server to abort and then kill the other clients, but then it's only sending "The rain in Spain falls mainly on the plain" so it's not exactly mission-critical at this point. Will need to fix it later, but then I'll also need to implement the session layer to comply with the specs.

Anyway, now I can get on with encoding/decoding messages... and pizza and wine.

The Plan

Posted by Russ Williams on Thursday, 5th February 2009 at 17:40 GMT
No comments yet | Reply
OK, slightly insane idea, but it could be fun: build a toy stock exchange.

This mostly came about from reading about the FIX (Financial Information eXchange) protocol, thinking "Ooh, that looks quite interesting to parse", downloading the 4.0 specs - a mere 60 pages and 27 message types - and thinking "why not". Then I realised implementing a FIX engine on its own would be about as much use as owning the world's only fax machine and, since I'm not going to have a real exchange to connect to any time soon, I'd have to write one myself...

So... why not? I've seen order books of various stripes and they're simple enough - a list of buy orders, a list of sell orders and, if the best buy/sell orders happen to cross over, some code to execute the trades.

I figure I'm going to do this in five parts:

  • * Network Server - the network/session parts of the server

  • * Network Client - the network/session parts of the client

  • * FIX Engine - encoding/decoding messages and validation as the presentation layer

  • * Exchange - application running the order book(s), executing trades and issuing ticks

  • * Trader - application to actually issue orders, probably randomly as it'll rapidly become AI Complete if I start building in trading strategies



Maybe also a sixth part to monitor the exchange and produce pretty graphs of the virtual stock prices.

So, yeah, I've managed to waste a day's holiday doing... nothing other than writing this blog post. Time to get my code on!

---
Russ

New Blog

Posted by Russ Williams on Thursday, 5th February 2009 at 15:00 GMT
No comments yet | Reply
Using the old code from the RPRF web site as I'm too lazy to write another (for now!). Expect a re-skin in the near future...

It's aliiiiiiiive!

Posted by The Administrator on Thursday, 5th February 2009 at 00:00 GMT
No comments yet | Reply
The database has now been reset and the site is now officially live and ready for use.

Also: First Post!