roboquant avatar

History

Why develop a new platform

Before we started to develop roboquant, we looked at existing frameworks and platforms to see if these could fit the bill. What we quickly found out is that many of these frameworks take a very naive approach to algo-trading. For example, hardly any of the sample code available should ever be used in live trading since it doesn’t address many of the edge cases.

For our use-cases, none of them checked all the boxes that we required:

  • Have an engine that can handle large volumes of data and run extensive and realistic back-tests

  • Trade assets in multiple currencies at the same time

  • Support many asset classes including cryptocurrencies

  • Have solid live trading, including support for advanced order types and correct handling of (async) order management

  • Support for trading in multiple markets in different regions at the same time

Some of these use-cases might be unique to our situation. But since we believe that others might also benefit from the platform, we decided to open source it and make it available for free to everyone.

If you want to know why we went with Kotlin as the programming language over some alternatives, read our blog

Interactive Development

From the start, we developed roboquant to be used either as a library included in your standalone application or interactively from a Jupyter Notebook. The various APIs have been designed so that they support both use-cases equally well.

Where some Kotlin/Java based applications require a lot of ceremonies to implement even the simplest piece of functionality, roboquant it designed to remove most of that. Especially in a Jupyter notebook environment, it is very easy to get started. Because of this, the API exposed by roboquant follows certain rules:

  • Minimize the need for imports, for example, don’t expose third party types if it can be avoided

  • Use sensible defaults for method parameters where possible

  • Use informative toString() implementations and explanatory exception messages

  • Provide overloaded convenience methods if it makes life easier for the user of the API

  • Use a flat package structure, so import statements are simple to remember

  • Leverage type inference where possible, so no additional type info needs to be provided

Time-Zone handling

When trading simultaneously in multiple time-zones, like trade stocks both in New York and London, it is key to have proper time management in place. Otherwise, you run the risk that your strategy performs very well but only because it can peep into the future due to faulty handling of time-zones.

Because of that, roboquant internally only uses the Java Instant type to represent a moment in time. This type is independent of any timezone. So all time events can easily be directly compared without having to consider time zones.

When importing data, there is functionality to convert the data from timezone-specific value towards the Instant type. When displaying time related information, it can be converted back the other way around if desired.

But the fact remains that all internal logic relies only on the Instant type in order to prevent timezone mistakes from happening.

Reliability

Even more important than performance, is reliability when it comes to trading software. So roboquant takes several quality assurance measures in order to catch as many bugs as possible before the software is released:

  • Type and null checks where possible to leverage the compiler to identify possible mistakes

  • Good unit test suite with more than 400 unit tests that covers most of the code base (> 90%)

  • Using several code analysis tools: Detekt, Sonarcloud.io and CheckMarx (IntelliJ IDEA builtin).

  • Extensive error logging to alert possible issues, including data quality

  • Immutable data classes (when appropriate)

  • Assert/requires to validate input parameters

  • USe of proven third party libraries

Why an event-driven approach?

Event-driven software is a paradigm in which the flow of the application is determined by events such as user actions, sensor outputs, or message passing from other programs. In the case of algo-trading, these actions are often price actions that happen in the financial markets.

Event-driven algo-trading platforms provide several advantages over a vectorized approach:

  • Reuse - roboquant uses the same event-driven approach for all 4 stages of developing trading strategies, ensuring minimal friction when moving from one stage to the next.

  • Avoid Lookahead bias — with event-driven back-tests; it is unlikely that the strategy will actually peep into the future since at the time of making any decision in the code, the future data is not yet available. In fact, within roboquant, the simulated broker is guaranteed to see pricing information before your strategy does.

  • Robustness — live trading is by definition event-driven. So by using the same approach during back testing, it ensures you got have to address use-cases that otherwise wouldn’t show up until it is too late.

Although event-driven systems come with the above benefits, they traditionally suffer from two disadvantages over simpler vectorized systems:

  1. They are more complex to implement and test. That is why using a platform like roboquant makes a lot of sense, since much of the heavy lifting is done by the platform.

  2. They can be slower to execute compared to a vectorized system. But by using Kotlin and a highly optimized execution engine, roboquant is actually faster than other algo-trading platforms.

To find out more about how Events and Actions are implemented in roboquant, check out the documentation on feeds.