Idea in brief
Andreas Clenow was looking for a momentum measure for stock selection that captures both the strength of a move and an estimate of its reliability. Clenow considers a simple price change over a period, even divided by ATR, a legacy of the era of calculating on paper.
The indicator is built in two steps. First, an exponential regression is fitted through prices over a window, that is, a straight line through the logarithm of price. Its slope shows the gain in percent per day, not in dollars, and reads the same on a cheap stock and an expensive one. Then the slope is multiplied by R², the coefficient of determination. R² lies between 0 and 1 and shows how evenly prices line up along the line. A stock that stood still for a month and then doubled gets a steep slope and a low R², and its score drops. In the interview the slope is given in percent per day. In the author's book "Stocks on the Move" the slope is converted to an annual percentage, and that annual figure is what gets multiplied by R².
The indicator and the ranking are worth keeping apart. The indicator is one formula on one series, and it ports to any platform. The ranking is a portfolio system: hundreds of stocks, a top 25 or more, periodic replacement and risk-based position sizing. Its parameters were not named in the interview, so here they are ours.
The difference from the "Dual momentum" card: there, the returns of several indices over a period are compared, while here the trend quality of an individual stock within a large universe is assessed.
Why it might work
Clenow distinguishes trend following from momentum. A futures trend model relies on markets that move independently (commodities, currencies, bonds) and on cheap leverage. Stocks have neither: in a bull market almost all stocks rise, in a bear market almost all fall, and leverage is expensive and dangerous. According to Clenow, a standard futures trend model fails on stocks. Stocks need selection: out of many similar stocks, pick those where the move is stronger and steadier.
Multiplying by R² favors smooth growth over a jump. We interpret it this way: a jump is often caused by a single event (an earnings report, a takeover rumor) and will not necessarily continue, while smooth growth is closer to what Clenow calls trend quality. This is our interpretation, it is not in the interview.
The author says that long-term momentum has long been confirmed both in practice and in academic research, but there is no magic in it. In Clenow's own service it is used only for a small weight adjustment.
Rules
Indicator (author)
// regression of the logarithm of price on the bar number over the last L bars
y[i] = ln(Close[i]), x[i] = 0, 1, ..., L-1 // x grows from the oldest bar to the current one
b = slope of the least squares line y = a + b * x
R2 = (correlation of x and y)^2 // from 0 to 1 (author)
SlopePct = exp(b) - 1 // gain in percent per bar (author: slope in percent)
Score = SlopePct * R2 // author: slope multiplied by R²
L = 90 // Finetiq: the author did not name the window length in the interview
Annual scale (author's book)
// author's book "Stocks on the Move": annualized slope multiplied by R².
// The annual scale was not mentioned in the interview
AnnualSlope = exp(b * 252) - 1 // Finetiq: 252 trading days per year
ScoreAnn = AnnualSlope * R2 // author's book
// the order of stocks by Score and by ScoreAnn can differ: for a steep slope
// the annual scale grows faster, and R² holds it back less
Stock ranking (author's logic, Finetiq parameters)
// universe: index stocks with historical constituents
// author: large or small companies is a question of goals, there is no best universe
// decision once a week at the close, execution at the open of the next bar // Finetiq
Candidates = [x in Universe : Score(x) > 0] // Finetiq: rising stocks only; author: long only
N = 25 // author: 25-30 for ordinary use
Top = N stocks with the highest Score
SELL held stocks that fell below place 2 * N // Finetiq: buffer against unnecessary trades
BUY stocks from Top into the free slots
// risk-based size (author), risk measure Finetiq
ATRpct(x) = ATR(x, 20) / Close(x)
Weight(x) = (1 / ATRpct(x)) / Σ(1 / ATRpct across portfolio stocks)
// rebalance a weight only when it has moved beyond ±20% of the target
// author: no-trade zone; Finetiq: zone width
// market filter (author: the model from the book gradually exits the market)
IF Close(Index) < SMA(Close(Index), 200) // Finetiq: form of the filter
no new buys, freed slots stay in cash
Indicator on one or two symbols (Finetiq)
// trend quality filter on a single market, decision at the daily close
IF Score > 0 AND R2 >= 0.5 AND no position // Finetiq: starting R² threshold
BUY AT NEXT BAR OPEN
IF Score <= 0 AND position open
SELL AT NEXT BAR OPEN
// two symbols: hold the one with the higher Score if its Score > 0, otherwise cash
Parameters
| Parameter | Value | Source |
|---|---|---|
| Regression | exponential (on the logarithm of price) | author |
| Slope | in percent per day | author |
| Quality adjustment | multiplication by R² | author |
| Regression window | 90 bars | Finetiq |
| Annual scale | exp(b × 252) − 1 | author (book Stocks on the Move), 252 days Finetiq |
| Direction | long only | author |
| Number of positions | 25 | author (25-30) |
| Ranking frequency | once a week | Finetiq |
| Exit buffer | below place 2 × N | Finetiq |
| Position size | by risk | author |
| Risk measure | ATR(20) as a percentage of price | Finetiq |
| No-trade zone | ±20% of the target weight | Finetiq (author: the zone exists) |
| Market filter | index above SMA 200 | Finetiq (author: trend filter in the book) |
| R² threshold for a single symbol | 0.5 | Finetiq |
What to test
- Does R² add anything. Three rankings on the same universe: 90-day ROC, ROC divided by ATR (the simple variant the author mentions), and Score. If Score is not better than the second one, the elegance of the formula does not translate into results.
- Window. 60, 90, 125 and 250 bars. Look at the whole curve of results, not at the best point.
- Score versus ScoreAnn. Compare the top 25 lineup each week and the final result. The author's book uses the annual variant. If the difference is large, fix in your system which variant is used.
- Is a jump filter needed. Exclude stocks with a daily move of more than 15% within the window. If the result does not change, R² already handles jumps on its own.
- Number of positions. 10, 25 and 50 stocks: return, volatility, drawdown. This is a direct test of the author's words about diversification.
- Market filter versus always invested. Clenow built both types of models. Compare them on 2008, 2020 and 2022.
- Frequency and costs. Weekly versus monthly, a no-trade zone of 10%, 20% and 40%. Count turnover and the result after commissions.
Platform notes
TradingView (Pine Script)
- The indicator takes a few lines. Slope:
ta.linreg(math.log(close), 90, 0) - ta.linreg(math.log(close), 90, 1), the difference between two adjacent points of the same line. R²:math.pow(ta.correlation(math.log(close), bar_index, 90), 2). - Ranking hundreds of stocks cannot be tested as a strategy: a strategy trades only the chart symbol, and the number of
request.securitycalls is limited. The single-symbol version can be tested. - There is no value for the first 90 bars, and the SMA 200 filter needs an even longer history.
- The price of dividend stocks drops on the ex-dividend date. Without adjustment (
adjustment.dividendsinticker.modify), the logarithmic regression sees this as a decline, and R² falls.
MultiCharts and TradeStation (EasyLanguage)
- Slope on the logarithm:
LinearRegSlope(Log(Close), 90). R² is more reliable to calculate yourself in a loop over the sums of x, y, xy, x² and y², so as not to depend on built-in functions that differ between versions. - Ranking is done in a portfolio module: TradeStation Portfolio Maestro or MultiCharts Portfolio Trader. The list of symbols is set in advance, and the current index composition creates survivorship bias.
- Risk-based sizing and weight rebalancing require the capital of the whole portfolio. A copy of the strategy on a single symbol does not know it on its own.
- For two symbols an ordinary chart is enough: the strategy on Data1 also calculates Score on the second series (Data2).
MetaTrader 5 (MQL5)
- There is no built-in regression. Calculate slope and R² from an array filled by
CopyCloseon closed bars, starting from index 1. - A typical broker has no stock universe for ranking: CFDs on a few hundred stocks, short history, no companies removed from the index.
- On stock CFDs, dividends arrive as a balance adjustment, while the price on the chart drops on the ex-dividend date. A regression on such a series understates the Score of dividend stocks.
- The version on one or two symbols (index CFDs, futures) ports without problems.
Where the idea can break
- The interview describes only the principle. The regression window, filters, frequency and number of stocks of the book's model were not mentioned, and our values are starting values. If you want to test the author's own version, check them against the book.
- Clenow calls the models in the books educational: their purpose is to explain the mechanism, not to provide a ready-made trading system.
- The author warns about two data errors that inflate results: the current index composition instead of the historical one, and prices not adjusted for dividends.
- R² rewards smooth growth. The portfolio tilts toward calm stocks, and risk-based sizing gives such stocks even more weight. Check whether the outcome simply repeats an ordinary low-volatility bet.
- After a bear market the reversal is often sharp. At that moment the leaders over the last 90 days are the stocks that fell less, and the rebound stocks enter the ranking late.
- 25-30 positions with risk-based sizing require capital or fractional shares. On a small account, rounding position sizes distorts the weights.