Combining Moving Averages With the Parabolic SAR.
Can Moving Averages and PSAR Provide Good Signals?
Moving averages are great trend-following tools. Similarly, the Parabolic SAR also can hint at the beginning of a new trend. What if we try to combine the two together to give us a timely signal of when a new trend will emerge. This means that we will use the moving averages as dynamic support and resistance levels while confirming the reaction with the Parabolic SAR. The first two parts will introduce the moving averages and the Parabolic SAR and the third part will present the strategy.
The Concept of Moving Averages
Moving averages help us confirm and ride the trend. They are the most known technical indicator and this is because of their simplicity and their proven track record of adding value to the analyses. We can use them to find support and resistance levels, stops and targets, and to understand the underlying trend. This versatility makes them an indispensable tool in our trading arsenal.
As the name suggests, this is your plain simple mean that is used everywhere in statistics and basically any other part in our lives. It is simply the total values of the observations divided by the number of observations. Mathematically speaking, it can be written down as:
# The function to add a number of columns inside an array def adder(Data, times): for i in range(1, times + 1): new_col = np.zeros((len(Data), 1), dtype = float) Data = np.append(Data, new_col, axis = 1) return Data
# The function to delete a number of columns starting from an index def deleter(Data, index, times): for i in range(1, times + 1): Data = np.delete(Data, index, axis = 1) return Data # The function to delete a number of rows from the beginning def jump(Data, jump): Data = Data[jump:, ] return Data
# Example of adding 3 empty columns to an array my_ohlc_array = adder(my_ohlc_array, 3)
# Example of deleting the 2 columns after the column indexed at 3 my_ohlc_array = deleter(my_ohlc_array, 3, 2)
# Example of deleting the first 20 rows my_ohlc_array = jump(my_ohlc_array, 20)
# Remember, OHLC is an abbreviation of Open, High, Low, and Close and it refers to the standard historical data file
def ma(data, lookback, close, where): data = adder(data, 1) for i in range(len(data)): try: data[i, where] = (data[i - lookback + 1:i + 1, close].mean()) except IndexError: pass data = jump(data, lookback) return data
The below states that the moving average function will be called on the array named my_data for a lookback period of 200, on the column indexed at 3 (closing prices in an OHLC array). The moving average values will then be put in the column indexed at 4 which is the one we have added using the adder function.
my_data = ma(my_data, 200, 3, 4)
The Parabolic SAR
The parabolic stop-and-reverse is an interesting indicator created by Welles Wilder Jr. who is also the creator of the famous RSI. This indicator is mostly used as a trailing stop that tracks the trend as it develops but there is no harm in using it as a signal generator.
It is worth noting that it performs relatively well in steady trends but just as any other indicator, it has its weakness, in this case, ranging markets. The below chart shows an example of the EURUSD with the standard parabolic SAR. We will see below how to code it.
I will refer to a python library called talib from where the user could import the sar function that uses a data frame and calculates the values. Having modified that function, you can refer to the one below (I do not take credit for it as I just changed some lines as opposed to the other functions which have been coded by me):
def sar(s, af = 0.02, amax = 0.2): s = pd.DataFrame(s) s.columns = ['open','high','low','close'] high, low = s.high, s.low
# Starting values sig0, xpt0, af0 = True, high, af sar = [low - (high - low).std()] for i in range(1, len(s)):
sig1, xpt1, af1 = sig0, xpt0, af0 lmin = min(low[i - 1], low[i]) lmax = max(high[i - 1], high[i]) if sig1: sig0 = low[i] > sar[-1] xpt0 = max(lmax, xpt1) else: sig0 = high[i] >= sar[-1] xpt0 = min(lmin, xpt1) if sig0 == sig1: sari = sar[-1] + (xpt1 - sar[-1])*af1 af0 = min(amax, af1 + af) if sig0: af0 = af0 if xpt0 > xpt1 else af1 sari = min(sari, lmin) else: af0 = af0 if xpt0 < xpt1 else af1 sari = max(sari, lmax) else: af0 = af sari = xpt0
sar.append(sari) s = np.array(s) s = np.reshape(s, (-1, 1))
The basic understanding is that when the parabolic SAR (the dots around the market price) is under the current price, then the outlook is bullish and when it is above the current price, then the outlook is bearish.
To add the parabolic SAR to your OHLC array, use the following steps:
importing pandas as pd
par = sar(my_data, af = 0.02, amax = 0.2)
par = np.array(par)
par = np.reshape(par, (-1, 1))
my_data = np.concatenate((my_data, par), axis = 1)
Creating the Combined Strategy
Combining indicators and techniques is the first step towards a robust trading system as getting a confluence of signals around a time period reinforces the conviction. There are many ways to create such structured strategies namely, scorecards, indices, and simultaneous conditions. The strategy we will be discussing will revolve around the simultaneous conditions and it is when certain conditions are met at the same time thus giving us a trading trigger.
The conditions we will be using for this strategy are:
Long (Buy) whenever the Parabolic SAR turns below the market price while simultaneously the market price is above and close to the 300-period moving average.
Short (Sell) whenever the Parabolic SAR turns above the market price while simultaneously the market price is below and close to the 300-period moving average.
Let us first be sure that we have the necessary array with the two indicators already calculated before we introduce the signal function that initiates the buy and sell orders based on the above conditions.
# The Parabolic SAR has been calculated in the above part which should give us an array of OHLC data and the indicator
# Adding three columns for the moving average and the buy/sell columns my_data = adder(my_data, 3)
# Calculating the 300-period moving average my_data = ma(my_data, 300, 3, 5)
Now, we are ready to write the signal function as mentioned above:
def signal(Data, close, psar, ma_column, threshold, buy, sell): for i in range(len(Data)): if Data[i, close] > Data[i, psar] and Data[i - 1, close] < Data[i - 1, psar] and Data[i, close] > Data[i, ma_column] and (Data[i, close] - Data[i, ma_column]) < threshold:
Data[i, buy] = 1 if Data[i, close] < Data[i, psar] and Data[i - 1, close] > Data[i - 1, psar] and Data[i, close] < Data[i, ma_column] and (Data[i, ma_column] - Data[i, close]) < threshold:
Data[i, sell] = -1
# Defining the variables threshold = 0.0040
# Using the function to generate the trades signal(my_data, 3, 4, 5, threshold, 6, 7)
The threshold variable is the minimum distance of the market price to its moving average to be able to meet the condition. This means that if we have a bullish flip on the Parabolic SAR with a market price that is close to its moving average and still above it (distance must be less than 40 pips), then the bullish signal is generated.
The above shows the EURGBP chart with the 300-period moving average alongside the Parabolic SAR. Notice that in a downtrend, the market remains below its moving average and while approaching it, we await the signal from the Parabolic SAR to enter into a short trade as shown by the red arrows.
The strategy uses insights from reversal trading to initiate trend-following signals which can provide extended moves. The risk management used should be based on the trader’s choice as it depends on many subjective factors like the risk appetite and tolerance.
Remember to always do your back-tests. You should always believe that other people are wrong. My indicators and style of trading may work for me but maybe not for you.
I am a firm believer of not spoon-feeding. I have learnt by doing and not by copying. You should get the idea, the function, the intuition, the conditions of the strategy, and then elaborate (an even better) one yourself so that you back-test and improve it before deciding to take it live or to eliminate it. My choice of not providing specific Back-testing results should lead the reader to explore more herself the strategy and work on it more.
To sum up, are the strategies I provide realistic? Yes, but only by optimizing the environment (robust algorithm, low costs, honest broker, proper risk management, and order management). Are the strategies provided only for the sole use of trading? No, it is to stimulate brainstorming and getting more trading ideas as we are all sick of hearing about an oversold RSI as a reason to go short or a resistance being surpassed as a reason to go long. I am trying to introduce a new field called Objective Technical Analysis where we use hard data to judge our techniques rather than rely on outdated classical methods.
One Last Word
I have recently started an NFT collection that aims to support different humanitarian and medical causes. The Society of Light is a set of limited collectibles which will help make the world slightly better as each sale will see a percentage of it sent directly to the charity attributed to the avatar. As I always say, nothing better than a bullet list to outline the benefits of buying these NFT’s:
High-potential gain: By concentrating the remaining sales proceedings on marketing and promoting The Society of Light, I am aiming to maximize their value as much as possible in the secondary market. Remember that trading in the secondary market also means that a portion of royalties will be donated to the same charity.
Art collection and portfolio diversification: Having a collection of avatars that symbolize good deeds is truly satisfying. Investing does not need to only have selfish needs even though there is nothing wrong with investing to make money. But what about investing to make money, help others, and collect art?
Donating to your preferred cause(s): This is a flexible way of allocating different funds to your charities.
A free copy of my book in PDF: Any buyer of any NFT will receive a free copy of my latest book shown in the link of the article.