← All ideas
#051NewMomentumPosition

Weekly momentum rotation with an absolute floor

Once a week we hold the 10 strongest index stocks by ROC, but only among those that gained more than 20% over 18 months. No stops, exits via rotation. Nick Radge's variant: market trend first, then the strongest stocks over 12 months.

The Algorithmic Advantage · Alan Clement · Watch video

Markets

Stocks

Timeframe

D1, W1

Data

OHLC, Instrument universe

Rules

Partly formalised

Difficulty

Medium

Status

Untested

Some rules were added by us and are marked in the text.

TradingView needs data or workarounds
EasyLanguage has pitfalls
MetaTrader 5 needs data or workarounds

Idea in brief

Alan Clement tried various trend entries on stocks: breakouts, Darvas boxes. Clement's observation: any such entry works better if it lets through only stocks with strong momentum, and the higher the threshold, the better. Taken to its logical end, the idea needs no entry signal at all. It is enough to rank the index stocks once a week, hold the top ones and replace those that drop out.

The rules use two kinds of momentum. Absolute momentum is a floor: we hold only stocks that gained more than a set percentage. The author's example: more than 20% over 18 months. Relative momentum is a place in the ranking: among the stocks that pass the floor, we take the 10 strongest. There are no stops. A stock leaves the portfolio when it drops out of the top or falls below the floor.

The floor also works as a regime filter. In a bear market, stocks fall below it one by one, the portfolio shrinks and moves into cash in stages. When the market rises, the list fills up again.

Variant B from Nick Radge checks the trend of the whole market first. If it points down, the entire portfolio is in cash. If it points up, the strongest Russell 1000 stocks over 12 months are bought.

The idea differs from the "Dual momentum" card in scale. There, it is three or four index ETFs, one position for all capital and T-bills as the benchmark. Here, it is hundreds of stocks, 10-16 positions, and the floor is set by the stock's own gain. The exit from the market happens not all at once but one stock at a time.

Why it might work

Clement gives three reasons. The portfolio always holds the strongest stocks in the index, so it captures the market's rise. Selling and buying happen at the same time: one stock replaces another, and portfolio risk changes smoothly. In a system with separate setups, capital can go into trades on a single day and just as uniformly get caught in a pullback the following week.

The third reason concerns the exit. Tops are rarely sharp: a stock first moves in a sideways range, and momentum tends toward zero during that time. Rotation takes the position out in the middle of that range, without waiting for a collapse and without a stop-loss.

Radge looks at the same mechanics through the right tail. Strong trends do not happen all the time, but often enough, and a single stock like Tesla in 2020 makes the year. Momentum as a factor, according to Radge, has long been described in academic research. Both authors know the weak spot: a sideways market where leaders change often.

All of this is the authors' explanation. The interviews contain no figures on the results of the rotation itself.

Rules

Main version (Clement)

// universe: stocks of one index with historical constituents
// author: an index or a sector; Finetiq: S&P 500 as the starting universe
// decision once a week at the close of the last trading day of the week,
// execution at the open of the next bar
// author: weekly rotation; Finetiq: day of the week

ROC(x) = Close(x) / Close(x, 378 bars ago) - 1      // author: gain over 18 months; Finetiq: 18 × 21 trading days
Floor  = 20%                                         // author: example floor
N      = 10                                          // author: example; optimum in the author's experience 14-16

Eligible = [x in Universe : ROC(x) > Floor]          // absolute momentum (author)
Top      = N stocks from Eligible with the highest ROC   // relative momentum (author)
// Finetiq: ranking by the same ROC, the author did not name a separate measure

FOR each x in Portfolio
    IF x NOT in Top                                  // dropped out of the top or fell below the floor (author)
        SELL x AT NEXT BAR OPEN
FOR each x in Top NOT in Portfolio
    BUY x AT NEXT BAR OPEN

// if Eligible has fewer than N stocks, the free slots stay in cash (author)
PositionSize = Equity / N      // Finetiq: equal weights; the author talks about many small positions
// no stops, positions are not touched within the week (author)

Regime filter (author: any of the three)

// 1. momentum of the index itself (author)
IF Close(Index) / Close(Index, 126 bars ago) - 1 < 0   // Finetiq: 6-month window and a threshold of 0
    SELL all positions AT NEXT BAR OPEN, no new buys

// 2. only the floor on stocks (author): no separate filter, the portfolio shrinks on its own

// 3. an external indicator (author): a VIX spike or the shape of the VIX futures curve
//    Finetiq: see the vix-term-structure-regime card

Variant B. Radge: market first, then stocks

// universe: Russell 1000 with historical constituents (author)
// rotation once a month (author; in the general description "once a month or once a week")
// Finetiq: last trading day of the month, execution at the open of the next one

Regime = Close(SPX) > SMA(Close(SPX), 200)       // author: one of two filter examples
// the author's second example: NYSE new highs minus new lows, threshold not named

Mom(x) = Close(x) / Close(x, 252 bars ago) - 1    // author: 12-month window "as an example"
N      = 20                                        // Finetiq: the author did not name the number of positions

IF NOT Regime
    SELL all positions AT NEXT BAR OPEN           // author: market down, portfolio in cash
ELSE
    Top = N stocks with the highest Mom
    SELL held stocks that are not in Top          // author: sell the ones that weakened
    BUY stocks from Top that are not in the portfolio
// Finetiq: the regime is checked only on rotation day

Version for one or two symbols (Finetiq)

Ranking cannot be tested on a single symbol. What can be tested is the floor: how much of the time it keeps you in the market and what it does during declines.

// index ETF or futures, decision once a week
IF ROC(Close, 378) > Floor AND no position
    BUY AT NEXT BAR OPEN
IF ROC(Close, 378) <= Floor AND position open
    SELL AT NEXT BAR OPEN
// Floor: 0%, 10%, 20%. A floor meant for stocks may keep an index out of the market
// most of the time: count the share of weeks above the floor before testing

// two symbols: hold the one with the higher ROC if it is above the floor, otherwise cash

Parameters

Parameter Value Source
Universe stocks of an index or a sector author
Starting universe S&P 500 with historical constituents Finetiq
Momentum measure rate of change author
Absolute floor gain of more than 20% over 18 months author (example)
Window in bars 378 trading days Finetiq
Ranking measure the same ROC Finetiq
Number of positions 10 in the example, optimum 14-16 author
Rotation frequency once a week author
Rotation day last trading day of the week Finetiq
Position size equal weights Finetiq
Stop none author
Direction long only author
Index filter index ROC over 6 months below 0 Finetiq (author: index momentum)
Variant B: market filter S&P 500 above SMA 200 or NYSE new highs-new lows author (examples)
Variant B: window 12 months, 252 bars author (example), bars Finetiq
Variant B: frequency once a month author
Variant B: number of positions 20 Finetiq

What to test

  1. Floor and window neighborhood. A floor of 0, 10, 20 and 30%, a window of 6, 12, 18 and 24 months. The author named 20% and 18 months as an example. If the result holds only near that pair, the pair was fitted.
  2. Number of positions. 10 versus 15 versus 25. Look at return, drawdown and the share of weeks when fewer stocks pass the floor than there are slots.
  3. Floor versus index filter. Three runs: only the floor on stocks, only the index filter, both together. Look separately at 2008, 2020 and 2022: how quickly the portfolio moved to cash and how quickly it came back.
  4. Frequency and buffer. Weekly versus monthly rotation. Then a buffer: with a top 10, sell a stock only when it falls below 15th place. Count trades per year and the result after commissions and spread.
  5. Historical versus current constituents. Clement warns directly that trend approaches look better on the current index members than they actually were. The difference between the two runs shows the size of the survivorship bias.
  6. Sideways years. 2011, 2015-2016 and 2022 separately: turnover, the number of re-entries into a just-sold stock within two weeks, the result. This is the weak spot Radge names.
  7. Main version versus variant B on the same universe and period: a floor for each stock versus a common market filter.

Platform notes

TradingView (Pine Script)

  • A strategy trades only the chart symbol. Rotation across hundreds of stocks cannot be tested as a strategy, and the number of request.security calls is limited and not enough to rank an index.
  • The single-symbol version can be tested. ROC over 18 months on daily bars: close / close[378] - 1, with no signal for the first 378 bars. On a weekly chart the same window is about 76 bars (378 / 5).
  • A weekly decision on a daily chart has to be caught on the change of week and executed at the open of the next bar. If the week ended on a holiday, check that the rotation was not skipped.
  • Dividends change the ROC of stocks. Check whether chart adjustment is enabled (adjustment.dividends in ticker.modify).

MultiCharts and TradeStation (EasyLanguage)

  • Orders are sent only for Data1. Rotation is done in a portfolio module: TradeStation Portfolio Maestro or MultiCharts Portfolio Trader. A copy of the strategy runs on each symbol, and the top-N selection happens at the portfolio level.
  • The list of portfolio symbols is set in advance. If you take the current S&P 500 members, the test buys winners that are already known. You need data with historical index constituents and stocks that were removed from the index.
  • Calculate position size from the capital of the whole portfolio. If each copy of the strategy works from its own starting capital, you get a set of independent systems, not a rotation.
  • Change of week on daily bars: DayOfWeek(Date) < DayOfWeek(Date[1]) fires on the first bar of the new week. A decision based on the previous week's close is then executed one day later than in the rules.
  • For 5-10 ETFs a simplified path without the module works: a strategy on Data1 reads the other symbols as Data2 and beyond and holds Data1 only when it is in the top. This does not work for hundreds of stocks.

MetaTrader 5 (MQL5)

  • An EA can trade any symbol from Market Watch, and the multi-symbol tester supports this. The problem is data: the broker must carry the whole index. Usually CFDs on several hundred US stocks are available, with short history and without stocks removed from the index. A test on such a list is a test on survivors.
  • Each symbol has to be added to Market Watch and its history downloaded. A test across hundreds of symbols gets heavy.
  • Dividends on stock CFDs arrive as a balance adjustment, while the price on the chart drops on the ex-dividend date. ROC on such a series is understated for dividend stocks. A swap is charged for holding a long position, and with a holding period of three to four months it becomes a noticeable cost.
  • Calculate the week boundary in server time, and take data from the closed daily bar (index 1).

Where the idea can break

  • Clement gave the floor of 20% over 18 months and the top 10 as an example. The parameters and results of Clement's own system were not disclosed.
  • Without a stop, a stock's loss within the week is limited only by its weight in the portfolio. The author accepts this risk deliberately and protects against it with the number of positions. In a bear market, by the author's own account, stock correlations tend toward one, and ten positions fall together until the floor or the filter moves the portfolio to cash.
  • Survivorship bias. Both authors test on historical index constituents. Retail traders often lack such data, and on current constituents rotation looks better than it was.
  • A floor in percent gain depends on the era. In calm years few stocks gain 20% over a year and a half and the portfolio is underfilled. In a bubble almost all stocks pass, and the floor stops filtering.
  • A sideways market brings frequent replacements and whipsaws. Radge calls 2022 a hard year precisely for this reason.
  • Weekly rotation across hundreds of stocks produces noticeable turnover. Spread, commissions and tax on short-term gains can eat part of the result.
  • Radge's figures on the probability of profit and on 2022 refer to Radge's accounts as a whole, not to the configuration described here.

Sources

Author's claims

These figures and statements are the author's. We have not verified them.

  • Alan Clement: rotation once a week, with an average holding period of about three to four months per trade.
  • Clement: from experience, the optimal number of positions is 14-16. The floor of 20% over 18 months and the top 10 are given as an example, not as the parameters of Clement's own system.
  • Clement: in Clement's tests, 52-week breakouts and other absolute trend entries on stocks delivered less than rotation. No figures are given.
  • Nick Radge: 2020 was a record year for Radge, mostly because of Tesla, bought at around $30-40 (peak around $340). According to Radge, a stock like that comes along almost every year: Moderna in 2021, AppLovin in 2024. In 2022 there was none.
  • Radge: in 2022 the drawdown across Radge's accounts was about 30%. Radge calls a sideways market the weak spot of the approach.
  • Radge: the probability of profit in any 12-month window is 86% or 91% for Radge's strategies, depending on the strategy. Which one is which is not specified.

Related ideas

Updated: 2026-09-11