A Long-Short in JavaScript (Node.js) Using Stock API
In this post, I will be sharing how I created a simple Long-Short Equity trading script in JavaScript (a Node.js app) using Alpaca’s free paper trading API.
Alpaca’s paper trading API simulates the live trading API in a paper environment so we don’t have to worry about trading with real money when testing a strategy.
To get access to the paper trading API, sign up here. Once you’ve signed up, you should now have access to the Alpaca paper trading dashboard, which allows you to monitor your paper trading and gives you the access keys to link your script to your account.
The Strategy
The example strategy I will be implementing in this script is the Long-Short equity strategy. The idea behind this strategy is to rank a group of stocks from better performing to worse performing stocks, then to long the top stocks in the list and short the bottom ones. By doing this, the algorithm takes maximizes potential gains by longing what it predicts are going to be the better performing stocks, and shorting the predicted worse performing stocks.
The driving force behind success, though, is how the stocks are ranked. The ranking can make or break your algorithm. If your ranking system is good, ideally you’ll be longing stocks that are green the following days and shorting ones that aren’t doing so well. However, a bad ranking system could see your algorithm longing poorly performing stocks and, perhaps more dangerously, shorting high performing stocks, which could cause your algorithm to quickly lose you money.
Getting Started
If you already know how to set up a Node.js environment and run Node.js apps, you can skip this section. If not, this section will detail how to set up a Node.js environment for running the Long-Short script.
First, you need to download Node.js from the internet and run the installer. You can download it here. Once Node.js is finished downloading, create a new folder and run following command while in the folder:
npm init && npm install
Once you run this command, you’ll be presented with options while in the terminal. You can just hit enter through all the options. After completing all of the options, your Node.js application will be initialized.
To run this particular script, you will also need to install the Alpaca node module, which can be found in the Alpaca JavaScript SDK. To install, you just run the command:
npm install --save @alpacahq/alpaca-trade-api
while in your Node.js directory, and the Alpaca node module should install.
Once you’ve completed all these steps, all you need to do is download the long-short.js file (found in the Alpaca JavaScript SDK, under the “examples” folder) and place it in the folder (making sure to input your API keys into the script). Now you just run the command node long-short while in the folder, and the script should start running. You can stop the script anytime using the command Ctrl+C in the command line.
Overview
Before we dive into the code, I’ll give a high-level overview of this script. Here’s an outline:
- The script checks if the market is open. If not, the script spins for a minute and does nothing. If open, the script begins to run.
- Rebalance the portfolio every minute by getting a list of stocks to long and short, and then executing those orders based on amount of equity allocated to each bucket.
- When the time is within 15 minutes of market close, the script clears all positions and sleeps until the market is closed.
- After the market is closed, the script awakes and begins checking if the market is open, effectively looping back to step 1.
And that’s it! Now that we have a decent, high-level understanding, we can dive into the code so that you can fully understand what’s going on. This way, you will be able to make changes along the way so that you can customize the script to fit your needs.
PS: If you find yourself not understanding the code well enough to make changes after the walk-through, don’t worry. The last section of this article will explicitly show you some simple customizations you can make without needing to understand the code.
The Code
I’ll walk you through each major component of the script. First, I have input constants so that I can link my account to the script. To get your keys, hit the “Generate Keys” on your Alpaca paper trading dashboard and copy and paste them here:
Next, I initialized a class which will contain all methods that the script will use. In the class initializer, the script initially establishes a connection to the Alpaca API, and initializes a bunch of class variables that will be used throughout the script. You can customize the stocks that you want to rank in the this.allStocks array, making sure to keep the formatting as a string array of stock symbols. The list of stocks below is an example and is for illustrative purposes only.
The function run() will be the main method of this algorithm. First, it clears all incomplete orders so that none of them fill while rebalancing the portfolio, which would interfere with the rebalancing. Next, it waits until the market opens by awaiting a promise from awaitMarketOpen(), which will only resolve when the market is open. Finally, there’s the trading portion of the script (handled mainly by the function rebalance()), which executes after every minute until 15 minutes before market close, where it then closes all positions and sleeps until the market is closed, where it then calls run() again and starts the cycle all over again.
The function rebalance() is where all the trading happens. It first calls the function rerank(), which ranks the stocks from last to first, and then assigns them to either the long or short (or nothing) bucket, and determines the quantity that should be shorted for each bucket. The ranking mechanism itself is handled by rank(). After calling rerank(), rebalance() will adjust any positions that I have with the new quantities (either ordering a corrective amount or clearing the position if the stock is no longer in either list). After clearing positions, the script then market orders all the new stocks with the respective quantities using sendBatchOrder(). sendBatchOrder() is special because it’ll return the stocks that succeeded to order, and stocks that failed to order. After receiving which stocks orders failed, rebalance() reorders more of the stocks that executed successfully using the leftover equity that would’ve been used for stock orders that failed. Once the stocks are reordered, the trading will end, and the script will wait a minute to trade again.
Here’s a link to the entire script on the GitHub.
What You Can Do
Within the classification of a Long-Short equity strategy, there are many variables that you can control to fine-tune your ranking system. I mentioned earlier that you can change the universe of stocks by altering the this.allStocks array at the top of the script. The amount of stocks you will long and short is another customization you can make. The script takes the top and bottom 25% to long and short, but you can change this to whatever you prefer. Just edit the “4” in the snippet below (4 representing ¼) and you can change the script to select a larger or smaller amount of stocks for each bucket.
Another variable you can control is the percentage of equity to use for longing and shorting. This algorithm uses a 130/30 split which is popular amongst hedge funds. What this means is 130% of equity is used for taking long positions, and 30% of equity is used for short positions. You can edit that in the snippet below, choosing either percentage of equity or hard-coding amounts for your strategy.
You can also change the frequency of portfolio rebalancing. At the moment, the script rebalances after every 1 minute. This is represented by the “60000” in the code below, representing 60000 milliseconds. You can change this to be more or less frequent (for example, if you only wanted rebalancing every 5 minutes, you would change 60000 to 5 * 60000 = 300000). However, be sure that you are not making your frequency too high or low. If you set it to be too frequent, you might reach the 200 requests per minute quota and the script would start throwing errors. If you set it to be too infrequent, the script may not be able to clear all positions in time for market close (you can adjust for this by increasing the 15 minute tolerance to market close, located in the run() function).
The final variable that you can easily manipulate is the ranking system. In this script, the stocks are ranked in terms of percent change in stock price over the past 10 minutes. This means that the algorithm is betting stocks that are doing well will continue to do well, and vice versa. You can change the ranking system by changing the function rank(). In this function, you can rank the stocks in whatever manner you please, just make sure you input the rank in the field “pc” for each stock in the allStocks array, where higher numbers is better (0 is the worst stock, 5 is a better stock). This way, the function rerank() will order the allStocks array least to greatest by the “pc” field, which then allows the script to split up the stocks into buckets.
There are other customizations you can make to this script (for example, buying more shares of the highest ranked stock in the long bucket and buying less shares of the lowest ranked stock in the long bucket, and then doing the same for the short bucket), but those changes require more intricate code changes than simply changing one number/area of code.
Technology and services are offered by AlpacaDB, Inc. Brokerage services are provided by Alpaca Securities LLC, member FINRA/SIPC. Alpaca Securities LLC is a wholly-owned subsidiary of AlpacaDB, Inc.
Originally posted on forum.alpaca.markets.