Skip to content

My Custom-Built Trading Platform

How I built my custom-built trading platform

Context

I recently began intraday trading, also known as Day Trading. There are various strategies for day trading, but Gap trading resonates most with me.

Gap trading focuses on stocks that have gapped, i.e., stocks that have opened higher or lower than the previous close.

I follow a few traders who primarily focus on this strategy. The one I resonate with the most is Meir Barak, whose style closely aligns with my preference. Meir’s trading strategy is simple and consistent, following a few straightforward rules. If a stock gaps up, then he waits for confirmation before going long (buying the stock). The opposite applies if the stock gapped down. Meir spends time identifying interesting stocks during the pre-market trading session (stocks traded before the regular 9.30am ET start time). He looks for gappers and selects a few that show promising setup. Once the market opens, he monitors these stocks, waiting for confirmation.

Realizing that most of these tasks could be automated, I set out to do just that.

Trading tool

For this reason, I built a personal trading platform.

First attempt

I use TDAmeritrade for day trading. TDAmeritrade offers ThinkOrSwim, an application where users can create watchlists, scan to find stocks, chart, and, of course, enter trades.

ThinkOrSwim also offers a programming language called ThinkScript. You can use it to enhance charts by adding new functionalities or to create custom criteria to run your scan and find stocks that meet certain requirements.

Initially, I attempted to use ThinkScript to emulate most of what Meir does each day. The results weren’t great. Instead of spending more time optimizing and learning more about ThinkScript, I decided to write my own program using primarily web technologies.

Second attempt

TDAmeritrade also offers several APIs, such as historical price of a stock, market status, and real-time stock price.

By combining historical and real-time stock prices, I was able to create a series of scripts that met my needs.

First, I downloaded the majority of stocks listed on the NYSE and NASDAQ. I had about 1000 stocks, which I filtered based on price and volume.

With these stocks, I aimed to recreate the gap strategy that Meir uses.

As previously mentioned, there are two critical elements for selecting stocks and entering a trade. To select a stock, I initially filtered only the stocks that traded more (or less) than 2% of the open price compared to the previous closing price. During trading hours, I defined rules to alert me when a stock showed a confirmation pattern.

Let’s start with the shortlist of gappers.

I am leveraging the TDAmeritrade API to download each stock’s historical data. I download two versions. One is the open/close/high/low values of the previous 30 days. The other is the open/close/high/low values of the previous day, grouped in 1-minute intervals. There is a cron job that each morning at 6am downloads this data and stores it in a folder. One JSON file for each stock, one with daily data, one with minute data. I use the daily file to get the previous closing price.

At 7am ET, another cron job starts pulling real-time price data. TDAmeritrade has a websocket API where you can subscribe to price changes for a specific set of stocks. Each time there is a transaction, the TDAmeritrade API pushes you the value. When I receive a new price notification, the data is stored in a PostgreSQL database. At 9.30AM, when the market opens, I grab the previous close and the price at 9.30am to calculate which stocks are opening above or below 2%.

The list of stocks that match more than 2% or less than 2% are stored in a watchlist JSON file. This file is used by a web server. This web server serves a dashboard which lists the stocks that gap up and down and their charts. I use Lightweight Charts™ for the charts.

Each chart consists of three series of data. The first one is the previous day price candles (candles are a way to represent the stock price changes in a timeframe). The second one is the price of the SPY (the main index of the market). The last series represents the values of today’s price action, always represented in candles.

For the first and second series, I use the minute data collected by the script that ran at 6am and stored in the JSON. For the third, I query PostgreSQL and get the data populated by the real-time websockets.

The subsequent steps involve defining a set of rules that will trigger an alert when a certain condition is met or a confirmation signal is recognized.

Let’s focus on the case of a stock gapping up. The same principles will apply inversely when a stock gaps down.

When a stock gaps up, I check each new candle and ensure that certain conditions are met. I need to see:

When these conditions occur, I add a marker on the chart and a sound is played. This signals that something interesting is happening with that stock. I don’t need to mentally analyze each chart but only focus on those that have some confirmation.

When I find a trade interesting, I perform further checks. I analyze factors such as: is this the high of the day, is it hitting resistance, is the market trend supporting this, is it too early in the morning, is it too late, is the spread of the stock reasonable, is there enough volume.

Based on that, if I decide to enter a trade, I simply click on the chart. This action will draw a line on the chart, and then I click again to set up a stop loss. I added a utility that, once an entry price and stop loss price are set, automatically draws a new line for the take-profit point on the chart. I set a 1.2:1 risk/reward. This means that for each trade, say I risk $1, I expect to gain $1.2. This ratio has worked well for me, but it can vary for each person. By clicking and setting the entry, stop loss, and exit directly on the chart, I can quickly understand if the trade can be successful. On top of that, the chart automatically fills an order box with the prices and quantity based on my risk. I usually risk $500 a trade. That means if I trade a stock priced at $100 and the stop is at $99, I can buy up to 500 stocks. So, if the price goes from 100 to 99, I know my loss will be capped at 500. Previously, I had to do the math on my own, but now it’s automated, which saves me precious time, especially when stocks are moving rapidly.

Other Considerations

If I draw an entry price and I do not like it, I can simply hover over the line and remove it. When I submit an order, I send an OCO order, which means I send a buy order and a stop and target order all at the same time. When the first order is executed, then the stop and target orders are also placed. This has helped me in case the internet goes down as I know my orders are set to auto-execute when reaching my levels. The charts also receive the latest price marked by a purple line. The TDAmeritrade real-time streaming API is plugged into a Redis instance that has a Pub/Sub interface, and the dashboard hooks to it to update the chart prices. I started by following 1000 stocks, but over time I added some further filtering: price and volume. For price, I only trade stocks above $10, which is what Meir does as well. For volume, I need stocks that can provide me with a certain size. So, if a stock traded less than a certain overall volume the previous day, and if more than 5 candles had less of a certain volume, I discard the stock. I use a 3-minute interval candle. This means I have some fancy math to combine single 1-minute candles into a single 3-minute candle. I tried with 1-minute or 2-minute candles and it felt too fast for my style. While 5-minute is too broad of a timeframe for me to enter for my style.

Training

Since I have the data for all these stocks, I cloned the dashboard and created a training tool. Usually, at the end of the day, I use a separate URL that opens a training dashboard. This training dashboard is pretty similar to the regular one. The main difference is that it uses the previous data, and each candle is drawn every few seconds. When I see a pattern I like, I can press the space bar and the charts stop, allowing me to take some time to analyze if entering or not the trade. It allows me to enter a trade and quickly understand if the trade would have been positive or not. This has helped me refine my strategy and improve my success rate.

Other Small Details