The rules
Chan (Algorithmic Trading, Wiley 2013, the buy-on-gap model; blog of April 2012). Near the open, select the S&P 500 stocks whose return from the previous day's low to today's open is below minus one standard deviation (the typical size) of their daily close-to-close returns over the last 90 days. Keep those whose open is above the 20-day moving average of closing prices. Buy the 10 with the lowest such returns, each with a tenth of capital, or all if fewer than 10 qualify, leaving the rest idle, and sell everything at the close. Long only. His blog version buys up to 100 stocks on the gap test alone, without the moving-average filter; in a reply of 21 April 2012 he says its short side does not perform very well, though the book reports the mirror rule, selling short (selling borrowed shares to profit from a fall) stocks that gap up a standard deviation while below their average, at 46% a year over 2006-2012 with a Sharpe ratio (return per unit of risk) of 1.27 and a steeper drawdown (fall from a peak).
- Universe
- Nasdaq-100 stocks (the app's NASDAQ 100 universe preset, 100 tickers)
- Bars
- 1-minute
- Position size
- 10% of equity per stock; a cash account funds about ten at once. Published: a tenth of capital per stock, up to ten stocks, with the rest idle when fewer qualify.
- Rebalance
- Checked at every session's open: stocks that qualify are bought at 09:31 and sold at 15:59, a minute before the close. Published: bought at the open, sold at the close.
What the research found
Chan's book reports 8.7% a year and a Sharpe ratio of 1.5 for the rules over May 2006 to April 2012, before costs, on S&P 500 stocks with survivorship bias (missing stocks that later dropped out); the version he traded lacked the moving-average filter, and its returns diminished from 2009 on. His blog (20 April 2012) puts the 100-stock version at 19% a year without borrowing, a Sharpe ratio of 1.4 and a worst fall of 4% for 3 January 2007 to 29 October 2008, but his chart of them starts in January 2005 and its only 4% fall is in late 2005, so on our reading they include two years of backtest before live trading. It then lost 6% a year to April 2012. He blames the decline on an opening-price inefficiency that faded after the financial crisis. The figures name no cost; he suggests 5 basis points (hundredths of a percent) a side for large stocks. Stubinger and Schneider (Journal of Risk and Financial Management 2019; S&P 500 stocks, 1998-2015) found that trading the ten largest overnight gaps beyond 0.2% against their direction (buying drops, selling rises short) for two hours lost 0.03% a day after their 0.20% round trip (0.17% before costs), while gaps picked by a statistical jump test earned 0.17% a day after costs. Branch and Ma (2018, as summarized by CXO Advisory) found overnight moves no longer reversed during the day in S&P 500 stocks over 2011-2017, only in smaller ones. mikelhsia (QuantConnect, S&P 500 stocks, late 2020 to early 2024) found -21.0% a year without the average filter and +0.26% with it at a tenth of capital a stock, as in the book, and -57.7% and -2.6% with all capital in what qualified, runs whose per-trade expectancy, -0.128 and -0.007, is QuantConnect's ratio to the average loss, not a return. QuantRocket (liquid US stocks bought a minute after the open) found buying such gaps so poor that selling them short made about 10% a year in 2014-2020; with Chan's open-above-average filter added to its prior-close one, the buy side gained in a chart without figures. A reader of Chan's post reported in 2021 live costs of 30-40 basis points to enter and about 10 to exit, which cut his backtest of a variant from 29% a year to 6% or -6%; Chan blamed the shortfall on NYSE stocks not opening at the same moment and said Nasdaq stocks may fare better. No source states a return per trade for Chan's rules to set beside the library's 0.10% round trip.
Results
| Measure | Orbital test | SPY, same days |
|---|---|---|
| Window | Oct 30, 2023 to Oct 30, 2026 | Oct 30, 2023 to Oct 30, 2026 |
| Total return | −0.98% | +88.60% |
| CAGR | −0.33% | +23.54% |
| Sharpe | −1.96 | 1.22 |
| Discounted Sharpe | −5.99 | — |
| Max drawdown | −4.5% | −18.7% |
| Win rate | 50.9% | — |
| Profit factor | 1.00 | — |
| Trades | 110 | — |
Hypothetical: a backtest with modeled costs, not traded with real money.
Hypothetical growth of $10,000
R16 Buy on Gap · −1.0% vs SPY +88.6%
Rebuild it in Orbital
Paste this into Orbital Chat. The Strategy Developer builds the workflow and asks before it runs any backtest.
Use the NASDAQ 100 universe preset and build a program on 1-minute bars, using the session clock. For each stock, keep its daily closes (the open of each session's 16:00 closing-print minute, or on early-close days the close of its 13:00 minute; if that minute has no bar, the session's last close), its last 90 daily close-to-close returns and each session's low over the bars before its closing-print minute, adjusting stored prices for splits. When a stock's first bar of the session closes, if it comes before the 15:58 bar (12:58 on early-close days), compute today's open (that bar's open) divided by the previous session's low, minus 1. If that is below minus the sample standard deviation of the last 90 daily returns, and today's open is above the average of the last 20 daily closes, buy the stock with 10% of equity. Sell every position when the 15:58 bar closes (12:58 on early-close days), so the sale fills at the 15:59 open: a single stock does not print a 16:00 minute on every session. Start once 90 returns are stored. Long only; uninvested capital stays in cash. Backtest the last 3 years with $100,000.
Is it real?
- Strategies tested together
- 10
- Beta to SPY
- 0.00
- Alpha vs SPY
- −4.6% a year
- Costs paid
- $1,038, 1781% of the gain before costs
- Data
- 1m decisions on 1-minute bars, 754 sessions
- Fills
- Next open at market, sized at the fill
Read this before you trust it
The app's NASDAQ 100 preset stands in for the S&P 500, because a three-year run on 1-minute bars can hold about 100 symbols. The preset is a fixed list of 100 large stocks, mostly also in the S&P 500, not the index's membership over time: it holds both Alphabet share classes, GOOGL and GOOG, which tend to qualify together and then take 20% of equity, and names that delisted during the window, such as Ansys and Walgreens, so it carries survivorship and look-ahead bias (it was chosen with hindsight). There is no ranking within the session: each qualifying stock is bought with 10% of equity, the book's tenth, in ticker order until cash runs out, instead of the ten with the lowest gaps. The entry fills at the 09:31 open rather than at the official opening price; for the related reversal of overnight moves in S&P 500 stocks, Della Corte and coauthors find a one-minute delay cuts the profit sharply. Positions are sold at the 15:59 open (12:59 on early-close days), a minute before the close, because a single stock does not print a 16:00 minute on every session, and a sale left for it would fill the next morning. Daily closes and lows come from regular-hours minute bars. The first 91 sessions store 90 days of returns, so the first trade can come on 12 March 2024. Two fills a trade at 0.05% slippage (the assumed trading cost).
Sources