Skip to content
tpierrain edited this page Oct 23, 2014 · 26 revisions

Day 13 (October 20th 2014)

A Logbook entry written by @tpierrain

Like the previous time, we started to discuss with Cyrille, and code after with Mendel.

Topic of the day was:

Let's hexagonal our SOR!

Hexadecimal?!? No. Hexagonal? for sure! For those that needed a recap on what the Hexagonal -or port and adapters- architecture is => click HERE(beware: shameless bragging!!!)

Ok then: let's get back to our mob thing:

After having whiteboard-ed our hexagon, we identified its 3 ports and adapters:

  1. SmartOrderRouting API (investor-side)

  2. MarketDataFeed API (markets-side)

  3. OrderRouting API (markets-side)

We were trying then to figure out the form of the third one: the OrderRouting port/adapter. Should it be a protocol or an OO API as we started to implement since the beginning? Should we introduce a kind of common layer upon all the various kind of markets to handle and protect from race conditions in the way we received the notifications/information? ... Wait a minute! Did you just said "race condition"?!? (you may ask "why" here).

Yes, you should... (in fact it will help me if you do it right now...)

- "Why?!?"

Because Markets are functional race conditions kingdoms!

What does it mean? Cyrille illustrated that to us through the whiteboard:

MarketsRaceConditions

Every time a client (like our SOR) is sending an Order to a Market, there are many steps involved on the Market side:

  • The Order book of the Market is updated, and that triggers a potential Execution via the Market's Matching Engine

  • This Order(s) matching will then send an Order(s)Updated message (Message 1 on the diagram) to the OrderRouting Market API used by our SOR.

  • Depending on the Market, an optional Execution notification message (Message 1bis) may also be sent to the OrderRouting Market API used by our SOR.

  • In every case, this Order matching will also lead to a Trade generation on the market side (next step after the Execution). To do so, the Market have to collect some needed extra data to be sent as part of the TradeInfo message (Message 2). This TradeInfo message is sent to the connected OrderRouting Market API of the involved Market client (i.e. our SOR).

  • On the Market (data) Feed side of the considered Market, this new execution may lead to a LastExecutedPrice update notification (Message 3) forwarded to every MarketFeed API connected to this Market (i.e. not via the OrderRouting API this time).

  • But this new trade will impact more deeply the FeedEngine of the Market, that will also send a FeedUpdated notification (Message 4) to every connected APIs (once this new execution will have impacted all related prices, available quantities/depths for this Instrument, etc).

Sounds logical right? But in reality

There is no guarantee regarding the reception order of these 4 various kind of messages.

For a given Market you may receive messages 1, 2, 3, 4, with another Market you will receive 1, 1bis, 3, 4, 2 ... etc. It is also worth-noting that our SOR solver is mainly interested by 3 and 4.

Anyway. Our SOR must somehow be able to cope with those Market discrepancies. The question Cyrille, Mendel and I have been asking was:

  • WHERE to handle those functional race conditions?

And our answer so far:

  • Somewhere part of our business logic, and not embedded in a kind of Market APIs wrapper.

'Cause we don't want a leaky abstraction layer hiding from us some of the good Markets information and capabilities...

Ok. Cyrille left us, and Mendel and I started to code.

Building our first port and adapter (on the investor-side)

We started to build a C# raw (i.e. without any middleware nor HTTP involved) port, and an adapter to translate from a flat DTO world ... to our internal business logic (OO world).

We continued to build it in TDD mode, but we've been asking tons of questions during the elaboration of this new public API for the SOR: how to expose our events in a non-OO world? How to do it without creating functional race conditions (where you post an investor instruction, and the corresponding answers/events are raised before you had the opportunity to subscribe to them, etc.).

As of today, you can have a look at:

but also to

Note: We didn't have much time to work on it (lot's of talking before, even if it was necessary). So don't be cruel with us ;-)

Well guys... I think this is enough for today's Logbook entry. Next session, with (almost) the entire crew will be much more interesting regarding this SOR hexagonalization topic.

To be continued thus...

Clone this wiki locally