Even if you’ve never stepped a foot into one of its stores to buy the newest version of Call of Duty, you’ve probably been hearing the name Gamestop a lot lately. That company’s stock is included in a group of stocks called ‘meme stocks’. Basically, these are (or were) dead-man walking stocks that are being heavily shorted by the big guys in the market (hedge funds, mainly).
Online communities, like Reddit, took notice of these stocks and decided that everyone and their dog should start buying them. Why? The short answer is, of course, to make money. Some of those investors, however, might tell you they are just doing their righteous duty to stick it to the hedge funds, who they think have been taking advantage of the market for years.
Regardless of the reasoning, it can’t be denied that a big driving force behind the meme stock movement is Emotion – especially FOMO (fear of missing out). That’s not good. As any course teaching the basics will tell you, emotion is your enemy when it comes to trading stocks.
In this post, we’ll aim to take the emotional angle out of the stock market by creating a trading indicator/bot that will analyze certain stocks and even execute trades. We will create this simulated stock trading bot using thinkScript and the ThinkOrSwim platform.
Ways To Create A Trading Bot
If you want to create a trading bot, there are actually many ways you can do so.
I like the idea of creating an extendable, home-spun bot using Python. While there are some cool things you can do, I haven’t seen a good (or cheap) way to interact with a broker to get live trade data or execute trades, so going in a different direction for now.
NinjaScript is a C#-based language that allows unlimited extensibility to NinjaTrader. The fact that it’s C# makes it an attractive option. I may write another blog post using NinjaScript in the future.
thinkScript® is a built-in programming language that gives you the capability of creating your own analysis tools such as studies, strategies, watchlist columns, etc. In thinkScript, you decide which kind of data to analyze with which methods. Functions present in this programming language are capable of retrieving both market and fiscal data and provide you with numerous techniques to process it. – ThinkOrSwim
Apparently, thinkScript’s base language is Java. Because of the maturity and tools offered by ThinkOrSwim and the ease of entry to this platform, this is the one I chose for this blog post.
Getting Started With ThinkOrSwim’s Stock Platform
If you want to follow along with this post, you will need a TD Ameritrade account. You can open a TD Ameritrade account with zero dollars (I promise I don’t work for them). After creating an account, you’ll need to download the powerful ThinkOrSwim platform.
One of the many great things about ThinkOrSwim is its “Paper Money” option. This is a side account that starts you off with $200,000 of FAKE money (sorry) and offers simulated trading.
Everything works the exact same way in the Paper Money account as it does in the Live Trading account (the real account), except for one important detail… when you lose all the money in the Paper Money account, nobody will come to your front door asking for the keys to your house…
So be sure to choose that option when logging in.
Now go to the “Charts” tab and in the dropdown at the top left, enter the symbol SPY. We will use SPY as our ‘instrument’ upon which to build our trading strategy. This is the symbol for the SPDR S&P 500 ETF, an exchange-traded fund consisting of the 500 stocks listed on the S&P 500 Index.
Your settings for the fund chart may be different than mine so while it may look somewhat different, it should look similar to the image below.
To zoom in on any section of the graph, you can highlight it, or you can use the magnifying glass at the bottom right of the chart.
For example, zooming in on the last month and a half or so on my chart looks like this:
By default, each bar (aka, candlestick) on the chart is one day. You can change this to whatever you want. For example, day traders need to watch the trades at a much more detailed level, so they’ll set their charts up so that each bar represents just one minute.
This is important to remember **because the script we write will be in the context of one bar on your chart. **
Let’s start building a strategy that will plot some helpful lines on our chart and by the end, set us up to have this strategy make trades for us. At the top right of the chart, you’ll see a beaker icon.
Clicking that icon will open a window that looks like this by default:
On the bottom, left side, click the ‘Create…’ button, which will open a window that looks like this one.
Name the script something like ‘SimpleMovingAverage’.
Let’s start by just seeing what the default line of code does for us.
plot Data = close;
Click ‘Ok’ (and then ‘OK’ on the next window, too). Zoom in on your chart to see what we just did.
As you can see, we just plotted a line connecting the closing price for every bar (every day, in this case).
From a trading standpoint, this line is not very helpful. So let’s plot a line that may actually be helpful in helping us determine when our next stock trade should happen.
Stock Analysis Over Time
Again, it’s pretty simple. Replace the current line with the one below:
plot simpleMovingAvg = average(close, 21);
Zoom back out on your chart, and you should see something like this:
As its name implies, the Simple Moving Average provides the average stock closing price over a given period of time. Generally speaking, a rising SMA indicates strength; a declining one, weakness.
As each bar on our chart is one day, we just plotted a 21-day Simple Moving Average (SMA) of the SPY stock market fund.
Why is this helpful? A simple rule for a trading strategy might be: When trades break above the SMA, buy. When they break below it, sell. In fact, there are plenty of traders that pay attention to only that rule.
Before we move on, one important point. Instead of hardcoding the values for the SMA, we can provide them as configurable inputs. Update your code to the below.
input price = close; input length = 21; plot simpleMovingAvg = average(price, length);
This will not change the way your chart looks. To see what changed, click on the Beaker icon again and then click on the cog on the far right.
As you can see, we just provided any future user of this Strategy the ability to input whatever data points they want to use for their chart.
It’s important to provide these configurations to users if you ever wanted to sell/give these scripts to others.
We can make this chart even more useful by adding another Simple Moving Average line to our chart, but this one will be over a shorter period of time.
# Plot our fast SMA input fastPrice = close; input fastLength = 9; plot fastSimpleMovingAvg = average(fastPrice, fastLength); # Plot our slow SMA input slowPrice = close; input slowLength = 21; plot slowSimpleMovingAvg = average(slowPrice, slowLength); # Draw an up arrow where buy orders are placed plot signal = Crosses(fastSimpleMovingAvg, slowSimpleMovingAvg, CrossingDirection.ABOVE); signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
So now we have code for a fast SMA and a slow SMA, with configurable inputs for both. Here is what that chart looks like:
What we’ve built is called a ‘Simple Moving Average Cross’.
When the fast-moving average (the blue line) crosses the slow-moving average (the pink-ish line) in a bullish (upward) direction, a purchase order should be placed. Likewise, when it crosses it in a bearish (downward) direction, it may be time to place a sell order.
You can see that if you had used this strategy to buy some long positions over the last year or so, you would have done pretty well.
We also added a bit of code to plot an up arrow at each point on the chart where our strategy will place a buy order.
Real-Time Stock Buying Strategy
So this is coming together pretty nicely but we’re missing the most important part. We need this Strategy to analyze the chart in real-time (as new bars populate our chart) and place trades.
To do this, we’ll need to add another Strategy to our chart. So let’s click the Beaker icon one last time and, once again, click the ‘Create…’ button. You may name this Strategy whatever you like, but something like ‘SMA_Buy’ might make sense.
The code to do this is going to look very similar to our code in our other Strategy. We should be able to combine these code blocks. However, when I have done this, things don’t work. I’m not sure why at the moment. Regardless, if you build them as separate studies as we are here, things work fine.
For now, we’ll just focus on the buy-side of the equation. So, as mentioned above, when the fast SMA crosses the slow SMA in a bullish direction, we need to add code that will place the buy order for us.
input fastPrice = close; input fastLength = 9; def fastSimpleMovingAvg = average(fastPrice, fastLength); input slowPrice = close; input slowLength = 21; def slowSimpleMovingAvg = average(slowPrice, slowLength); # Evaluate for a bullish cross... def buy = fastSimpleMovingAvg < slowSimpleMovingAvg and fastSimpleMovingAvg > slowSimpleMovingAvg; # If the lines crossed in a bullish direction, place a buy order addOrder(OrderType.BUY_TO_OPEN, buy);
Wrapping Up Our ThinkOrSwim Stock Trading Bot
In this post, we learned how to use thinkScript on the ThinkOrSwim platform to build a Simple Moving Average Cross strategy that will execute stock market trades.
There are of course many different patterns that you can implement with thinkScript. It comes down to experimentation and trial and error to find the patterns you are most comfortable with. Luckily, ThinkOrSwim provides the perfect learning environment with its Paper Money option. There is a set of tutorials that you can find here. Give it a try!
Or check out this post about creating your own web bots in .NET with CEFSharp!