Printing Money With TD Ameritrade's API

We’ve all heard about algorithmic trading in the news. It sounds great! You think of a program making money for you while you sip Mai Tais and smoke the finest ganja on the beach in Jamaica. I’m going to show you how you can do it yourself with TD Ameritrade and a laptop.

Before we start, you need to know that great reward comes with great risk. Don’t do this with money you’re not willing to lose.

Image for post

Sunrise in St. Elizabeth, Jamaica. One of the best places in the world to spend your trading profits.

Getting API Keys

The first thing you’ll need is a TD Ameritrade account. You don’t need to be a US citizen to get an account, and the process is pretty easy. If you’re in Jamaica, you’ll have to send TD Ameritrade signed copies of the documents they give you via Fedex or DHL. After you’ve signed up for TD Ameritrade, head over to their developer website and sign up for a developer account. Create an app and specify it. TD’s developer website will not accept a Callback URL that doesn’t begin with https, even if it’s localhost. You can test applications locally by removing the “https” with “http” in the URL bar after the redirect, or serving localhost over TLS.

Image for post

The app Callback URL must begin with https://

Once you’ve created your app, its client ID will be available to you in the dashboard. It seems you can only create one app per developer account.

Image for post

The OAuth2 Client ID is available as the Consumer Key in the dashboard.

You can use this client ID in any OAuth2 client library to interact with TD Ameritrade’s API. If you use Go, I’ve written a TD Ameritrade client library that handles authentication and interaction with the TD Ameritrade REST API, and if you use Python, Alex Golec wrote a python wrapper.

API Documentation

TD Ameritrade’s documentation is available on its developer website, but it is not as comprehensive as you may be used to from companies like Apple and Google. There are several surprises in their API that I’m going to tell you about to make your life easier.

Client ID Surprise

You have to append @AMER.OAUTHAP to your OAuth2 client ID, or it will return an error. This is only documented on their Authentication FAQ and Getting Started Guide in the example URLs.

Image for post

The dreaded “This may be due to a technical error, or the client application may be an attempt to fraudulently access your account.” error

PaperMoney Doesn’t Work

TD Ameritrade has a world class demo trading platform, PaperMoney. It has real time data when you have a funded account with TD Ameritrade. It’s the best demo trading platform I’ve ever used. It’s also not available via the API. It’s not clear when, if ever, TD Ameritrade will make demo accounts available via the API. It’s best to test your strategy with the data using a backtesting library, but make sure that your orders would actually fill given the state of the liquidity in the order book at the time before going live.

Real Time Updates

TD Ameritrade provides free real time market data over a websockets API. Alex Golec’s python wrapper allows you to process the market data in real time using Python’s async feature.

Risk Management

The most important skill when trading is risk management. This is even more vital when running an automated trading bot, since computers can lose lots of money very quickly. You’ll need to defend against hackers and trading losses.

Image for post

The bigger a loss, the harder it is to recover. Image from

Avoiding Margin Calls

  • Don’t run your trading bot on your main investment TD account. Create a new account and fund that with a smaller amount of money to trade on.
  • Ensure your bot has trade size and daily loss limits specified in dollars (not percentages) to prevent bugs from causing you to blow up your account. You can make these configurable so they can grow with your account.
  • If you’re trading options, futures or other leveraged securities, be sure to take the total risk into account when designing your limits. A leveraged position can be very volatile.
  • Monitor your account balance using TD Ameritrade’s apps. This will protect you from bugs in your code telling you you’re making millions when you’re really on your way to a margin call.
  • Run the bot in demo mode by default and create a switch to place live trades to stop yourself from accidentally running with real money when you think it’s paper money. For maximum assurance, have the bot require an explicit command to begin placing trades.
  • Ensure there is an easy external killswitch that will stop all trades immediately in case of runaway losses. My bot runs on an Azure VPS, and can be killed quickly by simply shutting the VPS off from the Azure Portal. This lets me kill the bot even if my VPN is down, or the program isn’t responding to kill signals from the OS.

Hosting and Security

Your trading bot will have access to your money. Although you cannot withdraw money via the API, hackers can steal from you in other ways, like having you sell all your holdings and purchase some low liquidity, worthless securities that they hold at a higher price, like the VIAcoin pump on Binance.

  • Do not give your bot server a public IP address. Use a VPN or a gateway like Cloudflare Access to access your server. If you’re self-hosting a VPN, ensure the VPN and VPN server OS are always updated to the latest versions.
  • Use firewall rules to limit access to only the ports used by your bot, and only allow it to send traffic to TD Ameritrade and your OS’s update servers. If possible, limit traffic at the network level, like Azure’s Network Security Groups or AWS’s Security Groups instead of relying on a host-based firewall. Do not use unencrypted network protocols to control the bot. I’d recommend using HTTPS with TLSv1.2 or TLSv1.3.
  • Only install the bot and software necessary for it to run. I like Go because it can produce a single static binary that runs on a minimal Linux distro or Windows Server install.
  • Keep the OWASP Top 10 in mind when building the bot. Use modern software development frameworks that help mitigate against bugs like XSS and CSRF. Be sure to write automated tests for your code, especially your trading strategies and limits and ensure code can only be merged into your master branch after all its tests pass. Be sure to leverage static analysis to catch bugs where possible, and I’d recommend using a statically typed programming language so the compiler and type system can help you write accurate code.
  • Ensure you update your library dependencies regularly. Vulnerabilities in dependencies can compromise your bot and cost you money.
  • Ensure your bot server is monitored. Track your logs and system performance using an external log monitoring system, and set alarms for strange events, like new processes, or attempts to send network traffic to non-approved sources.
  • Use a cloud provider like Microsoft Azure or Amazon AWS. They can likely provide better uptime and security than you can on hardware you operate. Your mileage may vary. Start with the smallest VPS and scale up as needed.
  • Use a dedicated device to access your trading bot. Install as little third party software as possible. Ideally, you’d only install a browser and the VPN client. Use TD Ameritrade’s website to monitor your performance.

My Setup

I run my bot on an Ubuntu 20.04 VPS on Microsoft Azure in a private subnet only accessible on port 443 via VPN using Azure Network Security Groups. The bot web UI is only available via HTTPS, and the server is only able to send traffic to TD Ameritrade’s API server and the OS update servers.

The server has a managed identity that it uses to access other services within the Azure account. Secrets like TLS certificates are stored in Azure Key Vault. I monitor my server logs and performance with Azure Application Insights, and I monitor traffic to and from the server’s subnet with Azure Traffic Analytics.

The bot is a single binary built in Go. It exposes a web UI on port 443 over HTTPS only (I don’t need automatic HTTP -> HTTPS redirects) and does not use many non-stdlib libraries to reduce attack surface and dependencies to keep current. It is the only non-default program running on the VPS.

Trading Strategy

This is the hard part. Your bot is useless unless it’s executing trades based on a profitable strategy. I’m not going to tell you how to come up with this part. Read about technical analysis and fundamental analysis. You can use external data, like news feeds and social media to influence your trading strategy. It’s best to automate a profitable trading strategy that already works for you manually. Read posts on /r/algotrading for inspiration.

Trade on TD Ameritrade with Go

If you made it this far, you’re probably really interested in algorithmic trading. I created go-tdameritrade, a fork of Zachary Rice’s go-tdameritrade to make it easier to write trading bots. It’s free and open source. Use this library at your own risk. Automated trading can cause you to lose money very quickly.