Friday, June 08, 2007

QuickFIX

In Saxo Bank we have developed our own FIX library, instead of using the commercial offerings or the open source libraries available. From a historical perspective it was mainly due to two separate reasons: the commercial products very vastly expensive and there really was no open source libraries at the time we entered the FIX world 6 or 7 years ago, at least not of a production quality.

There are many advantages to having build your own FIX library to handle the message parsing and the session layer, the main one being flexibility. Apart from our B2B server, which is – needless to say – using the FIX protocol, we are most often the client side in the client-server relation ship and must as much adhere to whatever “interpretation” of the protocol the server side has seemed fit to implement. In a separate post I will try to elaborate on some of the more horrifying examples of protocol violations, but we have pretty much seen it all: custom tags, extra tags, added repeated sections and stuff best clarified as message re-interpretation or re-definition. We have been able to handle it all and more importantly from a business perspective in a swift and efficient manner.

With the release of FAST, FIX version 5.0 and the fact that we internally in the bank are moving away from C++ towards C#, we have considered using QuickFIX instead. Not so much because we are tired of our own library, but resources are scares, and we would rather spend our time on areas where we can really add value to the business and not just fool around with the protocol (however satisfying that may be). By moving to QuickFIX we may get some “for free” – I know, I know, there is no such thing as a free lunch. If some other party extended the QuickFIX library to support FIX.5.0 we would not have to do it. It is as simple as that.

The switch is, for obvious reasons, not going to happen just like that and not without an extensive test period to ensure that the flexibility and scalability is in order. We have just added support for CFDs to our B2B server. Several of our clients are using QuickFIX, so to get some experience with it we have developed a new test framework using QuickFIX and not our own FIX library. The test framework is build in such a way that we can unit and regression test the B2B Server, ensuring all is working as expected when new features are added (again a separate post on this).

Our initial findings suggest that it is a major step in the right direction, compared to inventing the wheel (again) yourself. Nothing is perfect, and some unfortunate design decisions have made stuff more cumbersome, and require you to code around. My good colleague Sebastian Bargmann, who is our QuickFIX ninja has found the following:

On the positive side:
· A complete framework of all FIX versions from 4.0 to 4.4.
· Full source available in portable C++ (as portable as C++ can be that is)
· .NET and java wrappers.
· Most of the administrative messages are handled by QuickFIX (e.g. logon, logoff, heartbeat and so on).
· Automatic logging to file and database which is easily extendable to support any custom logging requirements.
· Automatic message storage (in QuickFIX’s own proprietary format).

On the negative side:
· It is a framework in the original meaning of the word. A very thin OO encapsulation of the protocol, but the abstraction is not “big” enough.
· The .NET code is an ultra thin wrapper around the framework. No delegates on top of the callback-events created by the C++ code.
· Everything is created as classes. There is really nothing wrong with this, but the simple types are still chars, int’s and so on. QuickFIX claims to be strongly types, but this claim is not really valid.
· The documentation is non-existing. You really need to read the C++ code (and show quite a lot of passion) to understand what is going on and how everything is connected.
· The configuration is done by an ini-file, which is difficult to use. Some of the stuff is even full of errors.
· The use of multiple sessions for e.g. FX trading – where you should have a trade session and a quote session – looks initially simple. It turns out, however, to be somewhat difficult because all messages have to pass through the same singleton instance of the connection handler. What this means is, that for each message coming in, you have to check what session is supposed to receive it.
· Special tags needs to be hard coded. If you for instance have a requirement that tag 50 is mandatory in the header, you need to add this to each and every message that is being send. This should really have been configutable.
· The supplied sample code is way to simple.

Conclusion:
A nice framework that needs some tweaking, but once this is done, you will end up with something usable.

No comments: