Algorithmic Trading with Python and TD Ameritrade

Ryan Kemmer

--

Image by the author

We are currently in the midst of a technological revolution in finance. With new advances in computing and artificial intelligence, there is a lot that can and will be automated. In recent years algorithmic trading has become much more advanced, and is continuously becoming more common practice. Someday in the near future, we all might just rely on their our own “robo-advisors” to handle our investments, and never worry about markets again.

In this post I am going to show you how to make your own bot that can trade a simple mean reversion strategy using Python and TD Ameritrade. While I am no expert in quantitative finance, I hope this can help make getting started with algo-trading easy and accessible.

What you will need:

  • Python
  • A TD Ameritrade Developer Account
  • Patience
  • EXTREME Caution

DISCLAIMER: The material in this post is intended for educational purposes only and is NOT financial advice. Please be very careful if working with real money. Use at your own risk.

Getting Started

The first step in getting started with our strategy is creating a TD Ameritrade Developer account, and getting all necessary API keys. The reason we are using TD Ameritrade as a brokerage is because they have access to developer tools and an extensive API that we can use to buy and sell securities.

Step 1: Create a TD Ameritrade Account

If you don’t already have one, go to the TD Ameritrade website and create an account. If you already have an account with TD Ameritrade, feel free to skip this step.

Step 2: Sign up for a TD Ameritrade Developer Account

Once your brokerage account is set up, head over to the TD Ameritrade developer site and sign up for a developer account. The process should be fairly straightforward. If you need more info, here is their getting started page.

Step 3: Create a New TDA App

After your account is approved, head over to the “My Apps” tab on the developer site and create a new application. You will need to specify an App Name, Callback URL, and App Description. If you are not sure what to use for the callback URL, try using http://localhost.

Step 4: Get the Consumer Key and Callback URL

Once your app is created, all you will need to start coding with the API is the Consumer key, which you will find under the “Keys” tab, and the Callback URL which you specified upon app creation.

Creating a Strategy

Probably the most important part of algo-trading is having a throughout, algorithmic strategy that has low risk and has high returns. Unfortunately, this is easier said than done. A lot of people try to come up with strategies that beat the market, and a lot of them fail. Even banks and hedge funds with tons of money and resources can’t manage to beat the market in the long term. But, it’s fun to try, right? After all, it helps us learn and become better programmers.

The strategy we will be using in this post is not likely to beat the market, or even get close (sorry to disappoint). BUT, if you know what you are doing, feel free to use this work as a starting point to implement your own trading logic into code.

The Mean Reversion Strategy

The algorithmic strategy we will implement in this post is a variant of Mean Reversion. Mean Reversion is a popular mathematical methodology that is commonly applied to stock trading. The basic idea behind mean reversion is simple: stock prices commonly move back to an average price. Therefore, when a stock is far below its average price, this indicates a good time to buy. When it is far above its average price, this indicates a good time to sell.

Mean Reversion Strategy with Vanguard 500 Fund ETF — 1 day interval

To decide whether or not a stock is worth buying or selling at a given point in time, we need first need to calculate the stocks Bollinger Bands. Bollinger Bands are trend lines plotted two standard deviations away from a stocks simple moving average (SMA). When a stocks price is below the lower Bollinger Band, our bot will buy a stock. When a stocks price is above the upper Bollinger Band, our bot will sell a stock (if it owns it). The chart above shows an example of Mean Reversion with VOO calculated on a 1 day time interval. The green and red lines indicate upper and lower Bollinger Bands.

The time interval at which we calculate Bollinger Bands can change our strategy drastically. Changing this interval will influence how often our bot will be subjected to making a trade. If we are calculating bands every second, our bot will be trading a lot. Meanwhile, if we calculate bands based on daily closing prices, our bot might take days or weeks before it detects a price worth trading.

It’s always necessary to backtest a strategy before you implement it in real time. Backtesting will give us an idea of how well a strategy might perform, and what risks are associated with it. I backtested this strategy with VOO over the last 60 days using a 30 minute interval yielded average returns of .78%. Not great at all! But hey, at least we tried. Looking at the chart below, it seemed like it was at least attempting to make informed trades.

Mean Reversion Strategy with Vanguard 500 Fund ETF — 30 minute interval

Python Implementation

Now that we have a strategy and API to trade with, we can start the fun stuff. To begin implementation, we will need to first install a couple of important Python Packages.

These include:

  • tda-api — An open source Python wrapper for the TD Ameritrade API. This wrapper will make the API much easier and straightforward to use.
  • schedule — A library we will use to schedule our bot to make trades at certain times.
  • selenium — A browser automation tool (used for account verification)
  • webdriver-manager — A package to handle webdrivers (used for account verification)

TDA-API is the library that is most crucial to our implementation. A lot of the functionality of this code, including fetching prices and making trades are built around this library. I highly suggest taking a brief overview of their documentation, and my code will make a lot more sense. https://github.com/alexgolec/tda-api.

Before we begin, we will also need our basic data science libraries, such as pandas and numpy to work with stock data.

Now, I will dive into the individual components of our bot. Our bot will be designed to do Mean Reversion with VOO (Vanguard 500 Fund ETF) based on 30 minute price intervals.

User Authentication

Whenever our bot makes a trade, TDA will need to verify our account information. To do this, we will programmatically create an API access token (valid for 90 days). Whenever the 90 period runs out, we will use selenium and webdriver-manager to open up a chrome window where we can re-enter our account details, and create a new token.

Real Time Bollinger Bands Calculation

Once we are authenticated with the API, we need to define some functions that can pull historical prices and calculate Bollinger Bands in real time. This is a core component in influencing what our bot will do next.

Based on our strategy, our Bollinger Bands will be calculated every 30 minute price intervals. I have hardcoded this into the “get_prices” function when we fetch data using tda-api.

Fetching Current Price

We also need a function to get a current market quote of whatever stock we are trading. Luckily, the tda-api makes this simple enough! We just need to use their “get_quote” function, and parse out the JSON response.

Fetching Account Info

To make a successful bot with TDA, we need a way to get our current account balance, and also see how many “roundtrips” we have made within a day.

“Roundtrips” refers to the number of times we have bought and sold a position on the same day. When our bot is trading, we need to make sure that it does not make more than 4 roundtrips in a day, or else our account will get flagged for day trading. With our current strategy based on 30 minute intervals, it is unlikely this will ever happen. However, if we were trading on the 1m or 2m interval, this could easily happen. More info on TD Ameritrade’s day trading policies here.

We also will include another function, “get_position” that will check whether or not we are currently holding a position in VOO. Right now, the function assumes that VOO is the only stock we are trading, and only looks for if we have any position or not. If you are doing other trades within your account, you will need to update this function accordingly.

Executing Trades

We need code that can actually place orders for us. We will write a function called “place_order” that takes in an order type (buy or sell), as well as the number of shares to trade. We will then use the tda-api to construct an order spec, and place the order in our account. If the idea of using an “order spec”, is confusing for you, I once again highly recommend reading the tda-api docs https://github.com/alexgolec/tda-api.

Piecing the Bot Together

Now that we have all of our components, we can write a function, “get_action” that can be run multiple times during market hours to decide whether to buy, sell, or hold our current position.

The function will first calculate Bollinger Bands, get the current price, and fetch account information. Then, it will decide to make a trade based on our Mean Reversion criteria. Because this is a simple strategy, it will only buy/sell 1 share at a time.

Scheduling the Bot to Run at Certain Times

Finally, let’s use the Python schedule library to make our bot to run every 30 minutes during market hours. I am located in Arizona (MST), which means that currently, markets open at 6:30 am and close at 1:00pm. I’ll schedule the bot to check for opportunities every 30 minutes within that time frame.

This will be the driver function for our code.

Conclusion

This concludes how to create a trading bot using Python and the TD Ameritrade API. Although this bot hasn’t been extremely profitable, it is fun to know that it is trading when you are still asleep.

For a repository of the full code, find it on my Github. Let me know if you have any questions. https://github.com/ryankemmer/MeanReversionTradingBot

Enjoy!

--

--

Responses (3)

Write a response