Quant BuffetRelax, Not Over Thinking

Timing the Small Cap Effect ver. 2

Log in to collect

Strategy in a nutshell

This strategy trades the iShares Russell 2000 ETF (IWM) based on the prior month’s performance of large-cap stocks. The investor goes long on IWM following a positive large-cap return and holds cash otherwise, aiming to capture the influence of large-cap trends on small-cap performance.

Economic rationale

Research shows that institutional investors’ trading patterns create predictable return patterns. Large investors rebalance by buying or selling liquid large-cap stocks quickly, while spreading orders for smaller stocks, causing small-cap price movements to reflect prior large-cap performance.

III. SOURCE PAPER

Slow Trading and Stock Return Predictability [Click to Open PDF]

Allaudeen Hameed,Matthijs Lof and Matti Suominen.National University of Singapore.Aalto University School of Business.Aalto University School of Business

The state of market returns positively predicts the size premium (or the difference in the return on small and large firms) as small stocks adjust to market returns with a delay and large firms revert following market returns. This predictability of the size premium is strongest when aggregate asset and funding liquidity is low and is linked to institutional and informational frictions that manifest as slow institutional trading in small stocks but swift trading in large stocks. For example, slow trading by mutual funds leads to predictable small stock returns in the direction of fund flows.

Backtest performance

Annualised return9%
Beta0.438
Sortino ratio0.066
Win rate62%

Full Python code

from AlgorithmImports import *
class TimingtheSmallCap(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2000, 1, 1)
self.SetCash(100000)
self.period:int = 21
self.SetWarmUp(self.period, Resolution.Daily)
self.symbol:Symbol = self.AddEquity("SPY", Resolution.Daily).Symbol
self.data:RollingWindow = RollingWindow[float](self.period)

self.iwm:Symbol = self.AddEquity("IWM", Resolution.Daily).Symbol

self.recent_month:int = -1
self.Settings.MinimumOrderMarginPortfolioPercentage = 0.
def OnData(self, data: Slice) -> None:
if self.symbol in data and data[self.symbol]:
    price:float = data[self.symbol].Value
    self.data.Add(price)

if self.recent_month == self.Time.month:
    return
self.recent_month = self.Time.month
if self.data.IsReady:
    if self.data[0] / self.data[self.period - 1] - 1 > 0:
        self.SetHoldings(self.iwm, 1)
    else:
        self.Liquidate(self.iwm)