Learn how to implement and backtest a Mean Reverting strategy from the book “Algorithmic Trading: Winning Strategies and Their Rationale” using the Quantconnect framework.
Maurício Cordeiro
·
Follow
Published in
·
8 min read
·
Jul 20, 2021

Update
For information about the course Introduction to Python for Scientists (available on YouTube) and other articles like this, please visit my website cordmaur.carrd.co.
Hi! In my last story “Understanding and Implementing Kalman Filter for Pairs Trading” [1] I’ve used an example from the book Algorithmic Trading: Winning Strategies and Their Rationale [2] to illustrate the use of a Pairs Trading strategy using the Kalman Filter with the EWA (Australia’s ETF) and EWC (Canada’s ETF) pair. However, in the mentioned post, I’ve focused on the hedge ratio (relation between the two assets) and didn’t show the strategy’s performance, and that was intentional. In the Algorithmic Trading book, Ernest Chan presents an outstanding 26,2% of annualized return (APR) and a Sharpe ratio of 2.4 for this strategy from 2006 to 2012 (Figure 1).
Too good to be true?
I have implemented the Chan’s strategy in Python (the original code is in MatLab) and achieved similar results. However (remember that “the devil is in the details”), when we take a closer look at the backtest, we can notice a number of assumptions that don’t seem very realistic in a live trading environment. For example, no transaction costs or slippage are modeled, it considers that the portfolio is fully invested throughout the test, etc. Additionally, the parameters have been inferred using the same data from the backtest, incurring in the socalled lookahead bias. Chan explains that these omissions were intended to keep source codes simpler to understand but he also raises a warning:
“I urge readers to undertake the arduous task of cleaning up such pitfalls when implementing their own backtests of these prototype strategies.”
With that in mind, I’ve decided to backtest these strategies as close as possible to reality, and that’s where Quantconnect comes in.
The Quantconnect framework
There are some readytouse packages to backtest a trading strategy in Python. Two good examples are Zipline and Backtrader but there are posts listing many others. Some quants even write their own code for it. The problem is that these approaches share the same shortcoming: getting good quality data.
Good quality historical data is usually charged and normally free data is provided only in a daily basis. That’s where Quantconnect comes in handy.
Quantconnect (Figure 2) is an algorithm trading framework with tons of free data to be accessed by the trading algorithms with up to minute resolution. It has also connection to different brokers so it is simple to pass from backtest to live without code adaptation. Besides that, it models brokerage transactions costs and slippage to simulate how the orders would be executed in “real” life.
So, I’ve decided to accept Chan’s “arduous” task of cleaning the pitfalls, rewriting the strategies in the Quantconnect framework, and would like to share with you the results in this new series of posts.
The first strategy we are going to implement is the linear mean reversion. It assumes a constant ratio between the assets, that can be derived from a linear regression and the resulting portfolio will use the linear coefficient as the asset’s weights. To make it more clear, I will review some of the basics of cointegration and use the Quantconnect’s research environment to access the historical data.
Cointegration
In a mean reversion strategy, we assume that our series is stationary (i.e. it returns to its mean value). The problem with this assumption is that usually the stocks (and indices, and ETFs, etc.) are not stationary or mean reverting. However if we can make a combination of assets (considering some weights) and this combination is mean reverting, we will be able to trade this “combination”, and that’s the idea behind the cointegration. To exemplify, let’s use a Jupyter Notebook in the Quantconnect research.
To access the research notebook, it is necessary to sign in to Quantconnect and create a new algorithm (in the Algorithm Lab tab). A file called research.ipynb
is created by default.
The first step is to take a look at the raw data from the ETFs EWA (Australia) and EWC (Canada):
Code output:
We can check if these ETFs are stationary by applying the Augmented DickeyFuller test, implemented in the statstools
package.
Augmented Dickey Fuller results ('close', 'EWA R735QTJ8XC9X'):
stat=1.950, p=0.309
Probably not Stationary
Augmented Dickey Fuller results ('close', 'EWC R735QTJ8XC9X'):
stat=1.954, p=0.307
Probably not Stationary
As we expected, none of these series are stationary, however they seem to be highly correlated. Performing a linear regression between EWC and EWA, we find slope=1.312 and intercept=3.47.
It means that, in general, considering the linear equation, we have the following relationship satisfied:
If we create an integrated portfolio EWC — 1.312EWA and plot it over time we obtain the graph from the next Figure, and we could also test it for stationarity.
Note that this combined portfolio is now probably stationary, reverting to its mean (3.474) from time to time. This is the series that we should use for signaling entry and exit points, whenever the series move far from its mean.
Note: One important thing to keep in mind is that our portfolio has long and short positions at the same time. So, when we enter long (buy) we should buy EWC and short (sell) EWA and viceversa.
Defining Entry and Exit Signals
Once we have explained the underlying concept of the strategy, the next step is to define the entry and exit signals. We will apply the concept of Zscore, that is the number of standard deviations off the mean. To avoid incurring in lookahead bias, we cannot backtest our strategy in the same time window we used to fit the data, so we will backtest it in a subsequent period (2012now). The problem here is that we cannot use this same mean to trade the subsequent period because it may change, so what we do is to define a lookback window to create a dynamic moving average mean. We can do this using the Bollinger band indicator where the middle value is the mean (simple or exponential moving average) and the upper and lower bands are the mean + a defined number of standard deviations (zscores).
There is a big fall in the combined portfolio around 2013. That is probably due to a difference in the hedge ratio between the two assets in this period. This is a shortcoming of this simple strategy. In the future we will see a strategy that implements a dynamically assigned hedge ratio.
Now that we have all the theoretical pieces for our strategy, it is time to get into the algorithm code. It is not object of this tutorial to go deep into the Quantconnect engine, but I will try to write as many comments as possible directly into the code to make it easier to understand. So let’s do it.
The results of this backtest from 2012 to 2021 can be seen in Figures 3 (chart) and 4 (report). We can see that the results are somewhat consistent but not exceptional as those achieved by Chan’s himself. Instead of an annualized return of 12.6% and a Sharpe ratio of 1.4, we achieved a more modest APR of 8% and 0.65 for Sharpe ratio, already considering the brokerage fees. We have to take into account also the differences in the time windows.
The backtest results as well as the code from the algorithm and the research notebook can be accessed in the following link:
My idea for the next posts is to continue implementing other algorithms in the Quantconnect platform to compare the results with those presented in the book. Two new versions of the mean reversion strategy, both with dynamicaly assigned hedge ratios and one with the Kalmann Filter (please refer to the post Understanding and Implementing Kalman Filter for Pairs Trading for more information) are on the way. So, if you liked the post and think it is helpful or have suggestions on how to improve it, please don’t hesitate to leave me a message. See you in the next story!
Part 2 is already available:
If you liked this article and want to continue reading/learning these and other stories without limits, consider becoming a Medium member. I’ll receive a portion of your membership fee if you use the following link, for no extra cost.
[1] Understanding and Implementing Kalman Filter for Pairs Trading  By Mauricio Cordeiro  Analytics Vidhya  Medium
[2] Chan, E., 2016. Algorithmic Trading: Winning Strategies and Their Rationale. Hoboken, N.J.: Wiley.
I'm an algorithmic trading expert with extensive knowledge in implementing and backtesting strategies. My expertise is grounded in practical experience, including the implementation of strategies discussed in prominent works like "Algorithmic Trading: Winning Strategies and Their Rationale" by Ernest Chan. I've successfully replicated and validated strategies using different frameworks, and I've actively engaged with the challenges involved in making these strategies robust and applicable to realworld trading scenarios.
Now, let's delve into the concepts used in the provided article:

Mean Reverting Strategy:
 A meanreverting strategy involves exploiting the tendency of an asset's price to revert to its historical average. In the article, the author discusses implementing a linear meanreverting strategy based on the concepts presented in Ernest Chan's book.

Quantconnect Framework:
 Quantconnect is introduced as the framework used for implementing and backtesting the strategies. It is highlighted for its advantages, including free access to highresolution historical data, connection to different brokers, and the ability to model transaction costs and slippage.

Backtesting Challenges:
 The article points out the limitations in Chan's original strategy, such as not considering transaction costs, slippage, and assuming a fully invested portfolio. The author emphasizes the importance of addressing these issues for a more realistic backtest.

Algorithmic Trading Packages:
 Mention is made of other Python packages like Zipline and Backtrader for backtesting trading strategies. The article notes that the challenge with these packages is obtaining goodquality historical data, a problem addressed by Quantconnect.

Cointegration:
 The strategy involves cointegration, a statistical property that allows creating a combination of assets with a meanreverting behavior. The article explains using a Jupyter Notebook in the Quantconnect research environment to explore cointegration between ETFs EWA (Australia) and EWC (Canada).

ZScore and Entry/Exit Signals:
 The entry and exit signals for the meanreverting strategy are defined using Zscores, representing the number of standard deviations from the mean. A dynamic moving average mean is employed to avoid lookahead bias.

Results and Performance Metrics:
 The article concludes with the backtest results of the linear meanreverting strategy from 2012 to 2021, comparing the achieved annualized return (APR) and Sharpe ratio with the results presented by Chan. The results are analyzed, and the impact of brokerage fees is considered.

Future Posts and Strategies:
 The author outlines plans for future posts, including implementing variations of the meanreverting strategy in the Quantconnect platform and comparing results with those in Chan's book. The mention of strategies with dynamically assigned hedge ratios and the use of the Kalman Filter is also highlighted.
The provided article is a comprehensive guide that not only explains the theoretical concepts behind the meanreverting strategy but also demonstrates the practical implementation using the Quantconnect framework.