Welcome

Reading Guide

Welcome to the roboquant tutorial. Just like the roboquant software, the documentation is also open source. So if you find mistakes or want to contribute, head over to the GitHub documentation repository where you can find the source. The documentation is in AsciiDoc format, so easy to modify with any editor.

  • You can select a topic from the menu to get more information about that item.

  • Content that is formatted like SomeName, represents a real Kotlin class, interface, method or attribute.

  • The package names are typically omitted to make it easier to read.

  • All the used code snippets are compilable and runnable code. However, the required import statements are not shown to improve readability.

Main components

Perhaps the most important part of using roboquant is to understand the sequence of steps and the responsibility each component has in this flow. The following diagram provides a logical overview of the main components and the type of data they consume and produce.

main flow simplified

The role and responsibilities of each of the components are as follows:

  • Roboquant

    The engine of the platform that performs the actual run and orchestrate the interaction between the components. The engine supports all 4 stages of developing a trading strategy with minimal changes to your code. This is also the only component that is a concrete class and not an interface and not designed to be swapped out for a custom implementation.

  • Feed

    Provides the data needed for testing and trading in the form of events. A feed can represent both historic and live data and is not restricted to pricing information only. A feed delivers its data in the form of events on a channel.

  • Strategy

    Receives the event and generates zero or more signals. A Signal is a Rating for a certain asset, like a BUY rating for stock XYZ. So the strategy doesn’t create orders, that is the responsibility of the next component, the policy.

  • Policy

    Receives the generated signals and creates the actual orders. If you need to create orders that are not based on signals, this is also the place to do so, for example re-balance your positions at regular intervals. Check the features why it is smart to separate this from your strategy logic.

  • Broker

    Receives the newly created orders by the policy and process them. Any open orders received in previous steps will also be processed until they are closed. After the processing of hte orders, it will return an updated account that reflects the latest state.

  • Metric

    Receives the latest state of the account and calculates various metrics that are of interest to determine the progress and results of the run so far. These results are then handed over to the MetricsLogger that will store and/or log the metric values, so you can inspect them at a later time.

Implementation details

The actual implementation is a bit more elaborate. Especially the order of the components in the actual implementation might not be what you expected.

But there it a good reason it is done this way, it is now almost impossible to "look into the future" with your strategy since the broker will always first observe a new event. So the signals and orders you create based on event at timet, will only be processed by the broker based on an event at timet+1.

The following diagram shows the actual interactions with their real method names and parameters between the components.

main flow

Developing your own strategy

Developing a new strategy and validate it during a back-test is a straight forward process. The code snippet below shows the different steps that you have to take to develop and run your strategy.

class MyStrategy : Strategy { (1)
    override fun generate(event: Event): List<Signal> {
        TODO() // Your code goes here
    }
}

val strategy = MyStrategy() (2)
val metric = AccountMetric() (3)
val roboquant = Roboquant(strategy, metric) (4)

val feed = CSVFeed("./data/stocks") (5)
roboquant.run(feed) (6)
1 Develop a new strategy based on some idea you have. This can be done either from scratch or by assembling existing building blocks. In many cases, this is the only real software development required. See also Strategy for more details.
2 Create an instance of your strategy.
3 Instantiate the metrics you want to use to evaluate the performance of your strategy.
4 Create an instance of Roboquant (the engine) with the strategy and metric(s) as parameters to the constructor.
5 Pick the data feed you want to use to test your strategy.
6 Run the back test using the data feed you just created.

The roboquant platform is very flexible and provides many more options than the above example shows. You can easily change almost any aspect of the platform if the default behavior doesn’t suit your needs.