Algorithmic Trading Models - Cyclical Methods
In the fourth article of this series, we will continue to summarise a collection of commonly used technical analysis trading models that will steadily increase in mathematical and computational complexity. Typically, these models are likely to be most effective around fluctuating or periodic instruments, such as forex pairs or commodities, which is what I have backtested them on. The aim behind each of these models is that they should be objective and systematic i.e. we should be able to translate them into a trading bot that will check some conditions at the start of each time period and make a decision if a buy or sell order should be posted or whether an already open trade should be closed.
Please note that not all of these trading models are successful. In fact, a large number of them were unsuccessful. This summaries series has the sole objective of describing the theory behind different types of trading models and is not financial advice as to how you should trade. If you do take some inspiration from these articles, however, and do decide to build a trading bot of your own, make sure that you properly backtest your strategies, on both in and out of sample data and also in dummy accounts with live data. I will cover these definitions and my testing strategies in a later article.
In signal processing, a filter is a device that removes “unwanted” components from a signal. It removes certain frequencies from the signal that are considered background noise in order to paint a clearer picture of the true underlying signal.
The are four broad types of filters and they are defined by the types of frequencies they allow to pass through and those that they therefore exclude.
A low pass filter will, as the name suggests, allow low frequencies to pass through and reduce the significance of the higher frequencies
A high pass filter will do the opposite, allowing high frequencies to pass through and reducing low-frequency impact
A bandpass filter will allow frequencies to pass through that are within a pre-defined band. We supply a minimum and maximum frequency value to our filter and it will only keep those values that fall within
A band stop filter also requires a minimum and maximum value, but will pass all frequencies that are either greater than the maximum or lower than the minimum, essentially all the frequencies a bandpass filter would not allow
There are, of course, more sophisticated types such as notch filters (filters than reject a specific frequency) or comb filters (a series of regularly spaced band filters), but for the purpose of introducing this topic, we will stick to the fundamental concepts.
The Butterworth filter was first introduced by the physicist Stephen Butterworth in 1930. I won’t go into all the technicals of how this filter works, but the most important feature about it is that it is a low pass filter. The Butterworth filter aims to produce an output that is as flat as possible, ignoring the high frequencies and returning the lower ones. It has been found that this filter is an ideal one for use in the world of forex trading because we want to see the general underlying “low frequency” cycles. We want to remove the high-frequency movements, as this is what we might consider as just noise.
When we look at a chart, we start to see the scope for where this might have an application. As you can see, in the GBP/USD closing prices for the last 18 years, we see a lot of minor fluctuations around general price trends. If we were long or medium-term traders, we wouldn’t be interested in these fluctuations occurring around the trend, but we want the trend itself. One method to see the underlying trend is to use a moving average, which is useful, but is also a lagging indicator. The benefit of a filter is that it removes frequencies in real-time. We can see trend continuations and reversals immediately, making it easier for us to make trading decisions as close to these changes as possible.
Python’s SciPy package has an option for us to easily run a Butterworth filter. You can find the documentation here, but if you don’t come from a Physics background, you can look at the unknown values as parameters that we have the option to tune.
from scipy import signal frequency = 1000 cutoff = 100 # Cut-off frequency of the filter freq_normal = frequency / (cutoff) # Normalize the frequency b, a = signal.butter(3, freq_normal, ‘low’) output = signal.filtfilt(b, a, data[‘Close’])
Naturally, our frequency cutoff must be less than our frequency value, but it is these two values and the order of the filter (the first argument to the signal.butter() method) that we have the opportunity to tweak. To find the best set of frequencies, cutoffs and order is simply a case of testing different values and finding the one that best follows our data. Plotting the output against the closing price will our visual measurement for how well our model performs. If we wanted a more mathematical evaluation, we could look at the correlation or R² value between our two variables.
The graph above shows a subsection of our closing prices in blue and the Butterworth filter outputs in orange. As you can see, the filter follows the prices quite closely. This is not, by any means, a perfect fit and with more fine-tuning you could probably find a filter that is a better representation of the more general trends. As you can see, from October 2020 onwards, GBP/USD continually rises in value, but the filter is still affected by small price movements to the downside. If I was to tweak this, I would experiment with increasing the cutoff frequency and see if this creates a line that follows that price straight up.
Turning Analysis into a Trading Strategy
I wanted to take this analysis a step further and see if this could be turned into an actual trading strategy. The goal in the graph below was to identify the turning points of the Butterworth filter and see how close this was to an actual turning point in the chart.
I ran a loop through the closing data to check where the filter returned minimum and maximum points. These points are compared to the previous two days and next two days, so it’s worth remembering that if we were to place orders based on these signals, we would inly be able to do so two days after the mark we have made on the graph.
Whilst this isn’t a mathematical measure of accuracy, the filter returns some positive results. It doesn’t capture every turning point, but of the ones it does, it captures them with reasonable accuracy. We never expect 100% of our trades to be successful, but if we were trading from minimum to maximum point on the filter, it looks like we could make a profit.
I have taken a further subsection of the above charts for clarity, as I have now introduced two new identifiers. As mentioned before, we have a two day lag between identifying the minimum or maximum point and actually placing a trade, because we require that time to establish a turning point. I have included points for where these trades would therefore be possible. We can see on the above graph where, after identifying a minimum point, we would be able to place a buy on GBP/USD and after identifying a maximum point, we would be able to sell.
This delay ultimately doesn’t seem to affect us too much. We can still place buy trades as prices are rising and sell as prices continue to fall. If you were to play all of these trades, this strategy might turn you into more of a short term trader, as I count 17 trades being made on just 1 currency in the space of 8 months. But there is clearly scope. The next steps in finishing our analysis would be to run accurate backtests to check the validity of the model and set up an automated system that would either return a signal for when to buy or sell or automatically place trades itself.