How to code different types of moving averages in Python. | by Sofien Kaabar, CFA | Towards Data Science

Trading softwares come with different types of moving averages already pre-installed and ready to charted. But it can be interesting to understand how to calculate these moving averages so as to be able to use them when you’re back-testing potential strategies.
I have just published a new book after the success of New Technical Indicators in Python. It features a more complete description and addition of complex trading strategies with a Github page dedicated to the continuously updated code. If you feel that this interests you, feel free to visit the below link, or if you prefer to buy the PDF version, you could contact me on Linkedin.
www.amazon.com
If you want a do-it-yourself method, then the below will surely interest you. All that is needed is a python interpreter such as SPYDER. The different “known” types of moving averages are:
Simple moving average.
Exponential moving average.
Smoothed moving average.
Linear-weighted moving average.
We will go through each one, define it, code it, and chart it.
As the name suggests, this is your plain simple average 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:
In python, we can define a function that calculates moving averages as follows:
def ma(Data, period, onwhat, where):        for i in range(len(Data)):            try:                Data[i, where] = (Data[i - period:i + 1, onwhat].mean())                    except IndexError:                pass    return Data
The function takes your data structure represented by the Data variable, the moving average period (20, 60, 200, etc.) represented by the period variable, what do you want to apply it on (on OHLC data structures, choose 3 for close prices because python indexing starts at zero) represented by the onwhat variable, and the where variable is where do you want the moving average column to appear. Note that you must have an array of more than 4 columns for this to work, because it doesn’t automatically create a new column, but simply populate it.
As opposed to the simple moving average that gives equal weights to all observations, the exponential moving average gives more weight to the more recent observations. It reacts more than the simple moving average with regards to recent movements.
Mathematically speaking, it can be written down as:
The smoothing factor is often 2. Note, that if we increase the smoothing factor (also known as alpha) then, the more recent observations will have more weight.
In python language, we can define a function that calculates the EMA as follows:
def ema(Data, alpha, window, what, whereSMA, whereEMA):        # alpha is the smoothing factor    # window is the lookback period    # what is the column that needs to have its average calculated    # where is where to put the exponential moving average        alpha = alpha / (window + 1.0)    beta  = 1 - alpha        # First value is a simple SMA    Data[window - 1, whereSMA] = np.mean(Data[:window - 1, what])        # Calculating first EMA    Data[window, whereEMA] = (Data[window, what] * alpha) + (Data[window - 1, whereSMA] * beta)# Calculating the rest of EMA    for i in range(window + 1, len(Data)):            try:                Data[i, whereEMA] = (Data[i, what] * alpha) + (Data[i - 1, whereEMA] * beta)                    except IndexError:                pass    return Data
The function is self-explanatory as it merely reproduces the EMA function presented above.
This moving average takes into account the general picture and is less impacted by recent movements. It’s my favourite trend-following indicator. Mathematically speaking, it can be found by simply multiplying the Days variable in the EMA function by 2 and subtract 1. This means that to transform an exponential moving average into a smoothed one, we follow this equation in python language, that transforms the exponential moving average into a smoothed one:
smoothed = (exponential * 2) - 1 # From exponential to smoothed
It is a simple moving average that places more weight on recent data. The most recent observation has the biggest weight and each one prior to it has a progressively decreasing weight. Intuitively, it has less lag than the other moving averages but it’s also the least used, and hence, what it gains in lag reduction, it loses in popularity.
Mathematically speaking, it can be written down as:
In python language, we can define a function that calculates moving averages as follows:
def lwma(Data, period):    weighted = []    for i in range(len(Data)):            try:                total = np.arange(1, period + 1, 1) # weight matrix                                matrix = Data[i - period + 1: i + 1, 3:4]                matrix = np.ndarray.flatten(matrix)                matrix = total * matrix # multiplication                wma = (matrix.sum()) / (total.sum()) # WMA                weighted = np.append(weighted, wma) # add to array            except ValueError:                pass    return weighted
Basically, if we have a dataset composed of two numbers [1, 2] and we want to calculate a linear weighted average, then we will do the following:
(2 x 2) + (1 x 1) = 5
5 / 3 = 1.66
This assumes a time series with the number 2 as being the most recent observation.
If you are also interested by more technical indicators and using Python to create strategies, then my best-selling book on Technical Indicators may interest you:
www.amazon.com
So, which one to choose? That question is left to the risk profile of the trader and her familiarity with the moving average. Some prefer plain simple moving averages while others try to dig deeper by using combinations of exponential and smoothed moving averages. It all depends on you to find your favourite one. My advice? Consider longer-term moving averages.
Note from Towards Data Science’s editors: While we allow independent authors to publish articles in accordance with our rules and guidelines, we do not endorse each author’s contribution. You should not rely on an author’s works without seeking professional advice. See our Reader Terms for details.