My previous post was about my thoughts concerning general architecture of a trading platform. During my way rethinking it from end to end it becomes clear that a “client only” approach would not fit with my needs. So I went back to my list of entities and started the puzzling again. To see all past posts and get a outlook about whats coming up, just have a look here: Content++.
The obvious difference choosing an “server client” approach is having two segregated components. So from the fist impression, the feeling was like: “OK no problem, just fiddle it together by assigning each entity to client or server!” But during doing this, it becomes clear there are some pitfalls. To avoid later reconstructions to move a wrong assigned entity from one side to another, its essentiell to take possible future development stages into account. Now I will discuss this point more detailed cause there is a huge variety of many possibilities.
Ok – we have a server, we have a client
and we have some entities. So let start to assign the obvious to reduce the complexity.
The UI is one entity where its easy to decide that its to be assigned to the client. If we remember about the previous post, its easy to see that chart entity is to be assigned together with UI component. Now we have reduced the complexity by 25% – hurray! But the smart decisions are still in front of us.
I decided to assign the market data adapters and order API’s to server. This allows sending and receiving data and orders when no client is connected. In case the client is connected to server, market data and account states are send further to client from server component. For manual order execution from connected clients, the server receives the order request and routes it through the right API.
If the API and datafeed is on server side, it would makes sense to have the database close to both entities. This reduces latency and the risk to lose data.
Also here, the OMS and risk management engine work side by side and should be on the same component. Due to they interact with datafeed, API and database, they should be near by them. Still the user code engine is to be assigned.
The decision to assign the user code library to server component was more a challenge as it seems. In a work flow I can imagine, I will always develop my indicators and strategies on client side.
So why not put the user code library on client side?
My answer to this question was, the user generated code will be executed on server side. But how the user will develop his indicators and all the other stuff – without maintaining two versions of the user code library? It won’t be a elegant solution to have a version of user code library. One on server side to execute the user generated code and one on client side for developing all the user generated code. Think about a scenario where the user code library needs to be extended. You will need to maintain all changes on client and server side to have same version both. If you break this, you run into a hell were nothing will work any more. In later posts, I will come back to this topic when I post about the user code library design in detail.
Ok, now all entities are placed in one of both components. Lets have a deeper look to the process flow for each component. Lets start with server:
The abstraction of the process
flow show the interaction of each entity with all other server entities. compared to a client only approach, there is one obvious difference.
The local user interface is replaced by some endpoints. Through this endpoints, the communication and data transfer between server and client is established.
The endpoint configuration is to be discussed in later posts more detailed. In the current schema I used 2 end points, just to keep it simple and easy to follow.
For the client we have simple charting and manual order execution features only. This will change later if we talk about how to deal with user generated code. But for now lets keep it simple and focused on the basics.
The received data streams are deserialized on client and processed further and maybe displayed. The user requests, like sending orders or display historical data, are serialized and send to server.
The .Net Framework has some features on board to simplify this and doing the heavy lifting for you. But this will be extensively discussed in my next post later, when I will talk about messaging basics.
During start up, the client establish connections to server via endpoints. This gives us the power to send and receive messages to communicate with server application. Charts can be displayed in time by pushing new quotes to the client and actual account and portfolio states can be displayed. All latency critical and computation intensive parts are on server side. This makes monitoring everything very convenient with a light weight client. Maybe a browser based web client would be sufficient too!
Finally, lets see what we have:
For me it was a long process until I came to this point. But I’m quite happy with that kind of concept and it works well for me. I still learn a lot about service oriented architectures and distributed applications are a universe full of fascinating technologies.
My upcoming posts are all about messaging. Than, maybe I will come back and update the architecture by adding the message glue. If you have some comments don’t hesitate to contact me. Send me a mail or just leave a comment below. To get a preview about upcoming topics, please have look here: Content++.