# How to Implement the Short-Term Reversal Effect in Stocks with Weekly Rebalancing

> Implement the short-term reversal effect in stocks with weekly rebalancing. Buy worst weekly performers and short best monthly performers using a QuantConnect algorithm. Learn more now.

- Repository: [Papers With Backtest/awesome-systematic-trading](https://github.com/paperswithbacktest/awesome-systematic-trading)
- Tags: how-to-guide
- Published: 2026-08-02

---

**You can implement the short-term reversal effect by creating a QuantConnect algorithm that buys the worst weekly performers and shorts the best monthly performers, rebalancing every 5th trading day using the `ShortTermReversalEffectinStocks` class from the awesome-systematic-trading repository.**

The short-term reversal effect is a well-documented market anomaly where stocks that underperformed over the past week tend to outperform in the subsequent period, while recent winners often mean-revert. In the **awesome-systematic-trading** repository, this quantitative strategy is fully implemented in Python using the QuantConnect Lean engine. This guide explains how to implement the short-term reversal effect in stocks with weekly rebalancing by examining the actual source code architecture and providing runnable examples.

## Strategy Architecture and Components

The implementation follows a modular design with distinct components handling universe selection, data storage, signal generation, and execution. Understanding these building blocks is essential for customizing or extending the strategy.

### Algorithm Setup and Scheduling

The strategy inherits from `QCAlgorithm` and initializes the backtest environment in the `Initialize` method. According to the source code in [`static/strategies/short-term-reversal-in-stocks.py`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/static/strategies/short-term-reversal-in-stocks.py) (lines 18-22), the algorithm sets the start date, cash allocation, and adds a proxy equity (`SPY`) to ensure the scheduler functions correctly even when the primary universe is empty.

The weekly rebalancing mechanism relies on a simple counter that triggers selection logic every 5th trading day. The `Selection` method (lines 54-59) toggles a boolean flag (`self.selection_flag`) to indicate when the portfolio should be rebalanced, creating a consistent weekly cadence without requiring calendar-based scheduling.

### Universe Selection Logic

The strategy employs a two-stage filtering process to identify suitable candidates for the reversal effect. First, the coarse universe filter selects the 500 most liquid U.S. stocks with prices greater than $1 (lines 50-70). This initial screen ensures sufficient liquidity for short positions and removes penny stocks that might distort return calculations.

Next, the fine filter narrows this universe to the 100 largest stocks by market capitalization (lines 90-95). This additional constraint focuses the strategy on large-cap equities where the reversal effect is statistically robust and transaction costs are manageable. The filtered symbols are then passed to the selection logic for performance ranking.

### Rolling Window Calculations

Each symbol in the universe maintains a `SymbolData` object that stores historical prices in a `RollingWindow[float]`. The default window size is 21 days (lines 62-66), providing approximately one month of daily close prices for return calculations.

The class provides helper methods `weekly_return()` and `monthly_return()` (lines 73-77) that compute performance over the past 5 and 21 trading days, respectively. These methods calculate simple percentage returns using the oldest and newest prices in the rolling window, enabling efficient signal generation without redundant historical data calls.

### Selection and Rebalancing Logic

The `FineSelectionFunction` implements the core reversal logic by ranking stocks based on their recent performance. For the long portfolio, the algorithm calculates weekly returns for all symbols in the fine universe and selects the 10 lowest performers (lines 98-104). These recent losers are expected to experience short-term mean reversion.

For the short portfolio, the algorithm identifies the 10 highest monthly performers (lines 106-122), excluding any symbols already selected for the long basket. This dual approach captures both legs of the reversal effect—buying past losers while shorting past winners—creating a market-neutral posture.

The `OnData` method (lines 25-49) executes trades when `self.selection_flag` is active. It first liquidates positions not present in the new long or short sets, then allocates equal capital weights to each selected stock. The strategy applies a custom fee model charging 0.5 basis points per share (`price * quantity * 0.00005`) to simulate realistic transaction costs (lines 81-85).

## Practical Implementation Guide

To run the strategy on QuantConnect, instantiate the `ShortTermReversalEffectinStocks` class within your algorithm framework. The implementation is self-contained and ready for backtesting:

```python
from AlgorithmImports import *

class MyReversal(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2015, 1, 1)
        self.SetCash(100000)
        # Re-use the existing implementation

        self.AddAlpha(ShortTermReversalEffectinStocks())

```

This approach leverages the existing implementation while allowing you to combine the reversal signal with other alphas or risk management overlays.

## Customizing the Strategy Parameters

The base class exposes several configurable parameters that you can override to test different hypotheses or adapt to market regimes. Here are practical modifications:

**Adjusting Universe Size and Lookback:**

```python
class CustomReversal(ShortTermReversalEffectinStocks):
    def Initialize(self):
        super().Initialize()
        self.coarse_count = 300          # fewer liquid stocks

        self.top_by_market_cap_count = 50
        self.period = 14                 # two-week rolling window

```

**Modifying Rebalancing Frequency:**

```python
class BiWeeklyReversal(ShortTermReversalEffectinStocks):
    def Selection(self):
        # Rebalance every 10th trading day (≈ bi-weekly)

        if self.day == 10:
            self.selection_flag = True
        self.day += 1
        if self.day > 10:
            self.day = 1

```

These modifications demonstrate how the architecture supports experimentation while maintaining the core reversal logic implemented in [`static/strategies/short-term-reversal-in-stocks.py`](https://github.com/paperswithbacktest/awesome-systematic-trading/blob/main/static/strategies/short-term-reversal-in-stocks.py).

## Summary

- The **awesome-systematic-trading** repository provides a complete implementation of the short-term reversal effect in the `ShortTermReversalEffectinStocks` class.
- The strategy uses a two-stage universe filter (500 liquid stocks → 100 large-cap stocks) to ensure tradeability.
- **Weekly returns** determine long positions (10 worst performers), while **monthly returns** determine short positions (10 best performers).
- Rebalancing occurs every 5th trading day via a simple counter mechanism in the `Selection` method.
- Rolling windows store 21 days of price history per symbol, enabling efficient calculation of weekly and monthly performance metrics.
- A custom fee model applies 0.5 bps per share to simulate transaction costs.

## Frequently Asked Questions

### What is the minimum capital required to implement this strategy?

The strategy trades 20 stocks simultaneously (10 long, 10 short) with equal weighting. Given the custom fee model of 0.5 basis points per share and the need to maintain short positions, a minimum capital of $100,000 is recommended to ensure transaction costs do not erode the statistical edge. The source code sets this as the default cash allocation in the `Initialize` method.

### How does the rolling window handle stale or missing data?

The `SymbolData` class maintains a `RollingWindow[float]` with a configurable period (default 21 days). If data is missing for a symbol, the window simply won't have enough entries to calculate returns, and that symbol is excluded from selection. The implementation requires at least 5 days of data for weekly returns and 21 days for monthly returns before including a stock in the ranking process.

### Can I change the number of stocks in the long and short portfolios?

Yes, you can modify the selection counts by overriding the `FineSelectionFunction` in a subclass. The original implementation selects 10 stocks for each leg (lines 98-122), but you can adjust these values to create more concentrated or diversified portfolios. Ensure you update the position sizing logic in `OnData` to maintain equal weighting if you change the basket sizes.

### Why does the strategy use weekly rebalancing instead of daily?

Weekly rebalancing captures the short-term reversal effect while minimizing transaction costs and market microstructure noise. Daily rebalancing would incur excessive fees that likely outweigh the small-capacity alpha from overnight reversals. The 5-day counter in the `Selection` method (lines 54-59) specifically targets weekly frequency to balance signal strength against implementation costs.