Simple Moving Average Strategy Using Python

Michael Wirtz
4 min readNov 23, 2020



Since I began coding, writing my own trading algorithm has been a top priority on my to-do list. I know that it is incredibly hard to make them profitable, as it takes a team of individuals working on and updating the algorithm on a daily basis. As a first-attempt personal project, I do not expect this algorithm to start making me any money. A simple working algorithm is the goal for now.

I initially began with a YouTube video series, hoping that a guided tour of the space would grant me immediate understanding. Unfortunately, there are many added complexities when you want to automate the interaction between code and your online broker, and I was quickly lost. While the video series is something that I will go back to in the future, I will start with a simple time-series analysis and work my way forward.

Simple MA Strategy


  • Input: list of stock tickers
  • Output: subset list made from input list made up of stock tickers in which the 30-day moving average has crossed the 200-day moving average in the last 10 days

Visualize Moving Average Strategy

I first downloaded TSLA price data from Yahoo Finance ranging from 2010 to 2020. I wanted to visualize the 30–200 moving average strategy. I first plotted the price:

Next, I plotted the 200 and 30-day moving averages against this price plot:

And, finally, I placed markers on the plot to indicate buy and sell signals:

Now that I had an idea of the strategy implementation, it was time to put it into action.

Returning Subset List of Tickers

As you may have noticed, I am using a 30-day moving average instead of the classical 50-day moving average. This was simply done to ensure that I was not left empty handed with my output. Furthermore, no real-world implementation will be made with the code in this blog. Everything done here was more for curiosity’s sake than anything else.

Anyway, here are the steps I took:

Step 1: Necessary Imports

import pandas_datareader as pdr
import datetime
from datetime import date

Step 2: Writing Function

def ticker_satisfy(list_of_tickers):

# Getting today's date
today =
# Splitting today's date into day, month, year
end_day =
end_month = today.month
end_year = today.year
# Getting the date 365 days before today
year_ago = - datetime.timedelta(days=365)
# Splitting year_ago date into day, month, year
start_day =
start_month = year_ago.month
start_year = year_ago.year

buy_list = []

# iterating over list to return satisfying tickers
for ticker in list_of_tickers:

# Grabs daily price data of specified ticker with specified start and end dates
data = pdr.get_data_yahoo(ticker,
start=datetime.datetime(start_year, start_month, start_day),
end=datetime.datetime(end_year, end_month, end_day))
# Creating columns to assess crossover
data['SMA30'] = data['Adj Close'].rolling(window=30).mean()
data['SMA200'] = data['Adj Close'].rolling(window=200).mean()
data['above'] = np.where(data['SMA30'] > data['SMA200'], True, False)

# Dropping null values from dataframe
data = data.dropna()

# Resetting index for simplified slicing

# Creating variables for comparison
last_10 = data.iloc[len(data)-10:, :].above.any()
eleventh = data.iloc[len(data)-11].above

# Assessing crossover in last 10 days
if eleventh == False and last_10 == True:

return buy_list

A couple things to point out about the above function:

  1. The try and except statement was used after the function kept running into errors for simplicity’s sake. I did not investigate those errors.
  2. The dates are set up where you can run the function on any given day, and it will return you a list of stocks that satisfy the strategy criteria relative to the current day.
  3. No effort was yet made as to the optimization of the function. With a list of about 3,500 ticker symbols, I killed the kernel after the function was going on an hour of run time. Therefore, as you will see below, I limited the function to an input of only 100 ticker symbols.

Step 3: Getting the output

I downloaded the NYSE ticker symbols as a CSV. I then set variable “tickers” to the first 100 ticker symbols in the CSV. Here are the symbols below:


After running this list of tickers through the function, the output was as follows:


And, just to make sure the function was properly returning ticker symbols, I plotted the first ticker in the list ‘AIR’:

As you can see from the graph above, the 30-day moving average just passed the 200-day moving average in the last couple days.


Given that the function returned a suitable list, I think we can chalk this exercise up to a success. As we continue to explore python within the field of finance, the goals will get more complex, and the outcomes, hopefully, will incrementally be more useful in real-world applications.