It is frequently reported in the popular press that comparing moving averages gives predictive information about a stock’s momentum. For example, this interview published on Forbes suggests that comparing 15 and 30 day simple moving averages gives an indication of when to buy and sell.

This notebook defines formulas which add moving average columns. Some strategies will use these formulas to define bull and bear signals.

Contents

# Import Packages¶

```
import numpy as np
import pandas as pd
import cPickle as pickle
shortUniverse = True
```

# Load Pickle Data¶

First, we’ll load the pickle we developed in the previous section. The new prices dataframe is given a new name to reflect edits made during this notebook.

```
if shortUniverse:
with open('intermediaries/prices.p', 'rb') as handle:
prices = pickle.load(handle)
else:
with open('intermediaries/prices-full.p', 'rb') as handle:
prices = pickle.load(handle)
```

# Adding Moving Average Columns¶

The following formula defines simple moving averages of closed prices over a given window size. Lagged values are also added as a column in order to allow strategies to easily detect the day a crossover occurred. For a five day window, these columns would have the name “`ma_5`

” and “`ma_5_lag_1`

“, respectively.

For illustrative purposes, the MA5 is added to the prices dataframe. The first ten rows are displayed below.

```
def add_MA(df, lag):
df['ma_'+str(lag)]= df.groupby('symbol')['close'].apply(pd.rolling_mean, lag)
df['ma_'+str(lag)+'_lag_1']= df.groupby('symbol')['ma_'+str(lag)].shift(1)
return df
```

Please note that today’s “moving average” column includes today’s price.

```
prices = add_MA(prices, lag=5)
```

# Adding Moving Average Columns¶

An additional formula was generated for volume-weighted moving averages.

Unlike the simple moving average, which is based on closing prices alone, these moving averages estimate the “typical price” shares traded in a given day (average of high, low, close) and weight the typical prive by volume. For illustrative purposes, `vwma_5`

and `vwma_5_lag_1`

are added below.

```
def add_VWMA(df, lag):
df['typical'] = (df['low'] + df['high'] + df['close']) / 3
df['VP'] = df['volume'] * df['typical']
df['VPLag' + str(lag)]= df.groupby('symbol')['VP'].apply(pd.rolling_mean, lag)
df['VLag' + str(lag)]= df.groupby('symbol')['volume'].apply(pd.rolling_mean, lag)
df['vwma_' + str(lag)] = df['VPLag' + str(lag)] / df['VLag' + str(lag)]
df['vwma_' + str(lag) + '_lag_1'] = df.groupby('symbol')['vwma_' + str(lag)].shift(1)
df = df.drop(['typical', 'VP', 'VPLag' + str(lag), 'VLag' + str(lag)], axis=1)
return df
```

```
prices = add_VWMA(prices, lag=5)
```

# Output Example¶

The first 10 observations are displayed below.

```
prices.head(10)
```

# Save Formulas¶

No new price file is created. However, both formulas have been added to the separate document “`helper_functions.py`

” which can be imported into future tests.

# Potential Extensions¶

Exponentially weighted averages could be added in a future version.