The Acceptor and Initiator
They share a common session layer implementation and state machine with the following features:
- Full implementation of the session level protocol
- Generated strongly typed immutable field and business messages for all versions of fix
- A code generator which sources the XML from the Quickfix4j dictionaries - you can edit the XML and add your own fields if you have to extend the spec.
- Unknown fields are preserved within the message as untyped pairs.
- Injectable message store - you could replace with your own
- Default message store is file based, supporting replay of business messages
- Injectable business class which can forward messages to your own actor
- Notification of business class that the session is open, closed (the business class is a class which you write)
- Notification of business class that messages are rejected
- Automatic reset of sequence numbers at the start of each day
- Ability to reset sequence numbers in application.conf to resynch after issues
- Multiple configures sessions, running in parallel
- Actor for IO, decoding, session maintenance, latency recording (optional)
- Logging of state change (using logback)
- Optional logging of every raw fix message to its own file (via logback)
- Optional logging of human readable fix message to it own file (via logback)
- With less logging average times to process a business message once the session is established is 300 to 500 microseconds, or 3 ms with full logging (on a small i5 laptop)
- There is a normal level of GC and this is obviously not low latency
- Automatic wake and sleep by config in application.conf
Part of writing a fix engine is finding out how exactly fix should work. The best spec I found was the test spec, and from this an entirely seperate project was created containing all the session level tests - check out the sackfixtests project.
So, what is missing? The following have not been implemented, and I am not going to, as this is not a commercial project, this is a learning project. You could add these features if you need them - don’t be scared to open the code and change it.
- Login by username and password in a session
- Multiple fix versions (jars) in a single JVM - you would need a classloader per session/group of sessions
- On receipt it does not enforce strict ordering of fields in groups which is what the spec says. On sending the order is correct.
Sackfix was written to learn Scala and Akka with a real world problem.