Simple Moving Average Strategy Using Python
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
from datetime import date
Step 2: Writing Function
# Getting today's date
today = date.today() # Splitting today's date into day, month, year
end_day = today.day
end_month = today.month
end_year = today.year # Getting the date 365 days before today
year_ago = date.today() - datetime.timedelta(days=365) # Splitting year_ago date into day, month, year
start_day = year_ago.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:
A couple things to point out about the above function:
- The try and except statement was used after the function kept running into errors for simplicity’s sake. I did not investigate those errors.
- 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.
- 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.