calumrussell / rotala Goto Github PK
View Code? Open in Web Editor NEWBacktesting engine written in Rust
License: MIT License
Backtesting engine written in Rust
License: MIT License
Didn't do this because we are going to be making changes to DataSource
but the only method implemented from start was get_quote
.
So depends on completion of - #34
Needs to be fixed after multithreading is complete, balances are going negative and the bookkeeper is trying and failing to liquidate. Happens with binance test.
Exchange module needs another rework:
#31 - started with this but saw that this would likely be more complex requiring Python-specific implementations of additional components.
The goal is to be able to write a trading strategy in Python that can then be passed through to Rust (likely into SimContext) and run. The PR linked above gives an idea of the code that would be required to implement this (i.e. use of Pyo3 types).
#31 - with this PR completed, it should be fairly straightforward to build a WASM implementation of a full backtest. Must be able to pass data between JS and Rust to initialize, must be behind feature, and will most likely need new DataSource
.
There are multiple ways to go so it would make sense to make this easy by keeping with a candle source - so probably still using Diana internally? - but begin implementing API for actual exchange (for example, HyperLiquid).
Mentioned: #27 (comment)
Need to go through usage of &Vec and usage of concrete type as function param but get_quotes
and get_dividends
in the DataSource
trait both return &Vec so should start there.
It should be possible for clients to run multiple tests for multiple strategies simultaneously. When a backtest ends the server stays up and can be used again. This is separate from concurrency, an exchange may or may not support multiple strategies in a single backtest.
This module is a mess. It would make most sense not to bind any of this functionality to underlying structures. So a backtest should own it's own values, but then the user should pass this to another module to calculate performance stats. Right now, the module is closely bound into everything else, which isn't helpful as some of the functionality within this could be used in downstream packages.
This is two parts because if we implement a source with a LOB then Diana isn't going to work. The data source here isn't really the complicated bit either so it would make sense to add the LOB exchange and then add a datasource to run backtests against.
I'm considering using this project in my own projects. Is it possible to add a licence to the project to know if it's viable for me to use it?
This implies that there is going to be something wrong with the exchange impl if we try to implement - #54 - a lot of the types were being passed through in uist but this becomes more tricky with fortuna as the order types are significantly more complex. Any client will bind to those types meaning that they need to be passed explicitly.
Tests also overlap, we can just present single interface to test against
Before cargo publish
can happen, docs need to be reviewed as project structure changed with - 5141cc5
Don't think alator needs to be reviewed as I don't plan to bump version. Will just leave that as an implementation for jurav1.
Original concept was to have a vertically structured backtesting engine due to the potential complexity doing something more horizontal with Rust's borrow checker.
Due to the requirements of the applications downstream, a horizontal structure that provides multi-language support seems to be a better choice.
The existing components will be separated from each other and communicate over rpc with proto messages. This provides horizontal scalability, would make it possible to swap components between languages based on perf requirements, and potentially validate use in production because the components would be actually distinct.
To improve performance further alator should offer the option of multi-threaded components.
This is a complex improvement because of the risk of lookahead bias in backtests. Other similar libraries have multi-threaded components but they achieve this by allowing trading strategies to trade instantaneously at the market price.
This isn't only an issue with high-frequency strategies but end-of-day strategies will overestimate out-of-sample performance if the strategy is allowed to trade instantaneously on close rather than on tomorrow's open, which would be the next possible price to trade at live.
The way to remove lookahead bias in multi-threaded backtesting is to have strategies that can run async but block the trading loop until they are finished creating orders, and then run the rest of the loop synchronously. In this case, I think that the broker and exchange would need new thread-safe structures (Arc<Mutex>).
I believe it would also be possible for the exchange to be multi-threaded too (but haven't tested this fully). In the current implementation, the broker does not wait for trade confirmations anyway because the exchange only executes orders on the next tick (this is why we have the complex Ready/Waiting state controls) so running this async would make sense.
However, this would seem to introduce the possibility of a race condition when an order is passed and executed but the broker state isn't updated, and the strategy keeps issuing orders. If we have a sync::mspc::channel then I am not clear on where in the loop we block to receive messages and update state.
Introduce the ability to hold securities denominated in multiple currencies but broker should still register performance and hold cash in a single currency (so this should primarily impact things like quote and holdings, not cash balances with broker).
Can also introduce the concept of multiple exchanges. This may be required because the above change would require the ability to get a quote across multiple asset types. And differences in currencies would generally imply different exchanges. However, this is really an implementation detail of the data source and the broker so may not be a productive use of time.
I am using this package within a Python app that, at the moment, is getting bound somewhere else into Python. Look at moving some of these bindings into this package so backtests can be run from Python.
Key feature add would be to see whether a strategy could be created in Python and then runs in Rust.
The output is fairly sparse. Could do with adding some more informational statistics (i.e. start and end date), and deeper coverage of performance statistics.
There is currently some duplication downstream so need to look at whether performance reporting in this package can be changed to integrate so I only need one performance-calculating module.
Data sources are currently a bit of a grey area because the HTTP layer isn't particularly well-defined. One path here was to try and go for LOB immediately: this is probably necessary for use cases but is going to mean doing more stuff with exchanges (which is tedious).
I think it would make more sense to define the required functionality of source/inputs so that we have a foundation to come back to LOB later.
Key functions are:
This is less flexible than the current situation but we need a defined way of dealing with data, and this creates limitations to build on later.
Need to fix runtime
Currently prices and corporate events are held within the same data structure which created a dependency between Bookkeeper and Exchange. These should be separate.
Also, the original DataSource
structure was supposed to offer low-cost clones but I seem to have removed it at some point. The default DataSource
implementation should hide all this behaviour too.
DataSource
was a very messy interface that exposed parts of how it worked. This was intentional so that users would know how to create data themselves but the load added has been growing as the internal structures used have become more complex with multithreading.
This issue is also linked to: #38 - which should be completed at the same time.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.