Trading Strategy that Aims to Capture Overnight Moves — Building & Backtesting it in Python
Summary of the Strategy
(This example will use about 150 different $6–$26 priced stocks.)
The basic philosophy behind the example script you’ll be creating is that it aims to hold a lot of different stocks overnight and sell them off in the morning. (A strategy like this aims to capture the big overnight moves that more affordable stocks sometimes experience.)
For this example, favor stocks that recently experienced growth, aka, those that have momentum. Specifically, multiply the stock’s change over the last five days by the number of standard deviations today’s trading volume was above yesterday’s. Python makes this easy to do — just take a look at the code. (“Bars” represents an array of bar objects from the Alpaca API. They show historical pricing information for a stock. Barset logic is below!)
Now into the stock-picking logic — once all the stocks are rated, assign a portion of your sample portfolio to them. Do this by taking a total of the scores and assigning each a proportionate percentage (according to rating) of the test portfolio.
The “portfolio” parameter here is just a float containing the cash balance of your account.
You can’t perform that action at this time. You signed in with another tab or window. You signed out in another tab or…
To run it, you’ll need a free Alpaca paper trading account and the following command to install the API library:
pip install alpaca-trade-api
Performance Testing Matters for Portfolios
One of the hurdles you might face while building a trading algorithm is figuring out how to test its performance. Historical data can be difficult to collect, and integrating it into your code can be confusing. That’s why you should consider creating an algorithm that keeps backtesting in mind.
(Note: past performance is not indicative of future results.)
Designing for Testing
Just like in software development, you should write trading scripts with the mindset of building “testable code”. If you don’t write the original code strategically, the testing can take longer than writing it — the same goes for writing scripts with backtesting in mind.
The key element of writing a script that factors in backtesting is the element of time. Have the time in the trading logic function(s) as an argument so that your testing code can “reset the clock” when it needs to.
Getting the Data
All of the data in this example is provided by the Alpaca API.
Now your script collects the data that gets passed into the rating code and uses that to determine what slice of data to grab. You’ll be able to use this same code for backtesting that is run for paper trading.
When to Test?
Your backtest will need a little bit of specialized code — it needs to iterate over multiple days worth of data, pass it into the trading logic and track the results. It won’t be buying or selling stocks for real while testing, so it just needs to remember each day’s data and then calculate the estimated result for the following day.
Another thing to consider is how to track which days the market is open — it won’t do you any good to test what would have happened on a day the market is closed (like Christmas or a weekend)! To make this easy, use Alpaca’s Calendar API.
Running the Tests
Once you have your Alpaca paper trading account, you’re nearly ready to go. Head over to your paper trading dashboard and look on the right side where it says “Your API Keys.”
As always, keep your API keys safe! If you ever lose them or think they might have been compromised, you can regenerate them on the dashboard at any time.
Once you’ve generated your API keys, you will get a panel that looks like this. Take those keys and set them as environment variables so that your script can automatically connect to the Alpaca API. Set your environment variables as follows:
If you need help setting variables, please go to the “How To” section in the Alpaca Documentation.
Now that your variables are set, you can add in a performance metric — for example, you can compare this algorithm’s performance to the performance of the S&P 500 over the same timespan. (If buying and holding performed better than your strategy, it’s an indicator that you might want to try tweaking some things.)
Print out the view of the S&P 500’s performance when backtesting is done.
*Reminder, this is an example and is for illustrative purposes only.*
Once you have your environment variables set and the script downloaded, you can run the tests like this:
python overnight_hold.py backtest 100000 30
The algorithm will run, starting with a $100,000 sample portfolio, for the last 30 days. Take a look — how did it do?
Upon observation, most of the larger gains are from investing a lot of the portfolio into a single stock that had a very large gain on October 14th. This is a very risky strategy, but in some cases, like this one, it pays off.
*Remember that past performance is not indicative of future results.*
Beating the market during a single month isn’t a strong signal that the algorithm will continue to be performant. Plus, this algorithm took some pretty big risks to make those gains happen. But it’s a start, and gives you at least one number to measure.
Real-Time Paper Trading
Paper trading allows for forward testing of your script. It can be run daily, executing orders in your paper trading account. You can watch your script’s performance on the Alpaca dashboard as it runs. (You can also easily switch to live trading: just set your environment variables to those attached to your real brokerage account. However, consider testing the strategy in paper trading to see if and how it works before trying it in a live brokerage account.)
In this example, things are set up so that the algorithm should only buy and sell things once each day, right before and right after the market closes and opens, respectively. Use the Alpaca Clock API to manage this, as it will handle things like weekends, holidays, and late opens or early closes. Between your algorithm and the APIs specified, you will be able to send buy and sell commands to the Alpaca API. You can use it for paper trading, or if you have a live brokerage account, you can use something similar to live trade.
Once you’ve downloaded the script and are ready to run it, use this command:
python overnight_hold.py run
1. Survivorship Bias
Backtesting in this example is pretty minimal (it is intended as more of an entry point). Using only the currently active list of stocks in your testing (like in this example) can lead to survivorship bias tainting your results. When retrieving a list of stocks from the Alpaca API, you’re only seeing the stock symbols that are listed today. Delisted stocks generally perform poorly before they’re taken off the market (creating that false sense of “beating the market” in backtesting without using them). That’s why, in the example above, the test is only run for 30 days — relatively few companies are likely to have been delisted in that time, so the impact of changes to the stock list should be minimal.
With that in mind, if you’re looking to improve your testing strategy, a good first step would be to acquire a historical view of listed stock tickers. There are a number of sources, including Google, that can show you.
Another concern, which you’ve probably noticed, is that testing is pretty slow. If you want to test tweaks to your strategy and/or fine tune parameters, it can take several minutes to see the results. It would be a lot faster to download the data once per day, save it to a disk, and then reference that file (rather than the API) when running tests.
3. Other Metrics
As of right now, the algorithm’s performance is only being compared to the S&P 500. However, there are many other metrics you might look at when backtesting. For example, you might also want to compare the drawdown to an index of your choice or calculate the Sharpe ratio to achieve more clarity around the risk-to-reward ratio your strategy is showing.
If you have any other ideas about backtesting, recommended tweaks, questions, or requests for follow-up articles, leave a comment!
Follow @AlpacaHQ on twitter.
Technology and services are offered by AlpacaDB, Inc. Brokerage services are provided by Alpaca Securities LLC, member FINRA/SIPC, a wholly-owned subsidiary of AlpacaDB, Inc.
This is not an offer, solicitation of an offer, or advice to buy or sell securities, or open a brokerage account in any jurisdiction where Alpaca is not registered (Alpaca is registered only in the United States).
The Paper Trading API is offered by AlpacaDB, Inc. and does not require real money or permit a user to transact in real securities in the market. Providing use of the Paper Trading API is not an offer or solicitation to buy or sell securities, securities derivative or futures products of any kind, or any type of trading or investment advice, recommendation or strategy, given or in any manner endorsed by AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate and the information made available through the Paper Trading API is not an offer or solicitation of any kind in any jurisdiction where AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate is not authorized to do business.
All investments involve risk and the past performance of a security, or financial product does not guarantee future results or returns. Keep in mind that while diversification may help spread risk it does not assure a profit, or protect against loss, in a down market. There is always the potential of losing money when you invest in securities, or other financial products. Investors should consider their investment objectives and risks carefully before investing.
There are risks unique to automated trading algorithms that you should know about and plan for. You should setup a method or system of continuous monitoring or alerting to let you know if there is a mechanical failure, such as connectivity issues, power loss, a computer crash, or system quirk. You should also monitor for instances where your automated trading system experiences anomalies that could result in errant, missing, or duplicated orders. A more complete description of these and other risks can be found in the Alpaca Securities LLC FAQ section.