Simulation

One or more event-logs can be replayed to simulate how a client strategy would behave.

Event Flow

The simulator allows for user-specified latency expectations, possibly different expectations for market data and order management.

../../../_images/simulator_timeline.svg

In the above chart, left-to-right, we have a typical flow of events

  • Market data (from exchange)

  • Order action (from strategy)

  • Order ack (from exchange)

  • Market data (from exchange)

  • Order update (from exchange)

However, there is actually no reason to simulate using an artificial “exchange time”. It is trivial to shift the exchange time line to match our receive time. Like this

../../../_images/simulator_adjusted_timeline.svg

With the notation

  • L1 = Order Management Latency + Market Data Latency

  • L2 = Order Management Latency - Market Data latency

Working in the space of receive time allows for certain optimizations.

Buffering

In order to guarantee corret time-ordering, buffers must be used:

../../../_images/simulator_flowchart.svg

The matching engine will multiplex both inbound and outbound queues to guarantee correct time-ordering.

Time

Event-logs are captured by receive time (system clock, monotonic) allowing for an almost identical replay as would have been seen during live trading.

Note

Correct time-ordering is guaranteed when using a single event-log!

However, when multiplexing several event-logs, there is a small possibility for re-ordering (as compared to live trading) due to strategies listening to multiple inbound streams during live trading. Client processing of these streams could happen in a different order than the receive times captured by the gateways.

Note

So why not use a realtime clock?

The reason is that the system clock is monotonic, consistent across CPU cores, and provides a high degree of accuracy. Two features that are very useful when we later want to multiplex several event-logs.

The realtime clock is not very accurate and, worse, is not guaranteed to be monotonic. We may very well observe the realtime clock stalling or even reversing time. In other words, when the realtime clock is being adjusted, it is no longer possible to accurately multiplex several event-logs.

Order Matching

The default implementation of roq::Matcher supports conservative order matching.

  • Order is filled when the limit price cross the opposite side of the order book. For example, a buy order with a limit price of 10 will be filled if (1) the market best ask is 10, or less, when the order is placed or (2) the market best ask becomes 10, or less, at a later time.

Assumptions

  • roq::GatewaySettings must be the first message from an event-log. This update contains information about what is supported, in particular if roq::ModifyOrder is supported.

  • The instance of roq::Matcher should use the roq::GatewayStatus (with non-empty account) to discover available accounts. The implementation of roq::Matcher should reject all order actions for unknown accounts.

    This also means that the event-log should contain all account-relevant event, e.g. roq::GatewayStatus and roq::StreamStatus. Currently there’s no option to override this.

  • There roq::DownloadBegin / roq::DownloadEnd sequence will be automatically generated for the first occurence of a roq::GatewayStatus event (for each combination of source and account).