Capitalise.ai’s Beta version, of the anticipated backtest feature, has been released!
Now you can create strategies, analyze, and research them before you apply them to your portfolio.
Backtesting is a methodology in which an algorithm is fed with historical data, calculates it according to its predefined rules, and eventually prints the results.
In this article, I would like to dive into how our backtest engine works and what assumptions are taken when a backtest is performed.
But before we get started with backtesting, I would like to mention the different limitations backtest presents:
- Detailed historical data: With real-time market activity, there are millions of messages flowing in, from real-time prices, book depth, orders, cancellations, and more.
When performing a backtest, one needs to decide on the granularity of the data set. The more details it is, the higher the processing times and costs, whereas fewer data presents the risk of failing to realistically represent the results.
- When running a backtesting simulation, none of our simulated actions have an effect on the markets. Thus, a backtest result cannot represent use cases in which our actions would affect market behavior.
- We run the potential of overfitting: When we decide on our trading scenario and adjust its parameters, what we might inadvertently do is overfit our criteria to the historical data set at hand. A possible solution for such a scenario is to test the strategy on multiple instruments/data sets.
So why should we backtest?
Understanding its limitations, I wouldn’t use a backtest results as a prediction tool for any future performance.
When would I use it?
When I have a strategy I wish to apply to my trading account, I want to first see how it would have played out historically. Even though it doesn’t reflect past performance 100%, I would still want to get the results because they present some measurement of success or failure.
I would prefer not to start trading with a strategy that historically would have lost me 20% of my equity.
To run a backtest analysis, follow these 3 simple steps:
At this point, the platform will perform a backtest analysis based on historical market data.
You can also look at this short video demonstrating the process.
I would like to address four elements regarding the analysis: Market data, Fees, Timeframe, and Order types.
To better understand this element, let me first introduce continuous vs. granular data sets. Let’s look at the following scenario:
This means that if Apple’s stock price crosses the 20 1-hour bars moving average, we will send a market order to buy 100 Apple shares. When running this scenario on our live account, AAPL price is considered continuous data because it is derived from real-time market data and the crossing event can happen at any time (14:36:27 e.g.). The moving average, however, is considered a granular data point, meaning it updates only once an hour.
When performing backtesting, all of our data sets are granular data sets. Our lowest time frame will be considered the “continuous” data set and will be used for any condition that requires continuous data.
In the Beta version, the lowest time frame used is 1-minute bars, which means that the smallest time increment is one minute. With each minute we have the Open price, Close, High, and Low, and we make decisions accordingly.
Trading fees are not taken into account during backtesting. If you want to know what the results on your personal account would be, you would need to add the fees applied to your account. For example, if the backtest results show gains of $100 after 15 trades and you pay $1.2 per transaction, your overall performance would be $100-(15*$1.2) = $82.
In future versions, we will add a mechanism that takes trading fees into account.
We currently provide 3 months of historical data analysis; this will increase in upcoming versions.
The backtesting engine supports all order types, but in order to better understand how those are calculated, we’ll review the Limit and Market orders.
- Limit order – consider the following scenario:
- A backtest started and a trigger was simulated with a limit order to buy at $100.
- The last registered price on the market was $105, and so the order was not triggered.
- Since the increment in time is 1-minute, the backtesting engine will move 1 minute in time and will look to see if the Low price of that 1-minute bar is <= $100.
- If the 1-minute bar low price is less than $100 – the buy limit will be filled.
- If the 1-minute bar low price is greater than $100 – the engine will move 1 minute forward in time and continue with the same logic.
- Market order – Once a trigger was simulated, the backtesting engine will look for the first-rate that was registered in the system after the trigger event and will consider this rate as the execution rate. This rate would be the next 1-minute bar Open price.
A backtesting analysis is a great tool for trying out multiple ideas. You can run a scenario, change it, and run it again and again until you find the best scenario for you.
As always, if you have any questions, we are here for you.