Buy when everything is oversold? Half true

Mean reversion · 3 min

Trying to improve a mean-reversion strategy by filtering for "market capitulation" actually kills the system's performance, even though the…

Mean-reversion (RSI) signal example (EURUSD daily, real data): look for a bounce when RSI is oversold.

Mean-reversion (RSI) signal example (EURUSD daily, real data): look for a bounce when RSI is oversold.

Trying to improve a mean-reversion strategy by filtering for “market capitulation” actually kills the system’s performance, even though the underlying observation about market behavior is correct. I started with a simple hypothesis based on the work of Larry Connors. Connors suggests buying individual assets that are oversold. I wondered if buying when a large number of assets are oversold simultaneously, also known as a “breadth” event, would lead to a sharper rebound. It turns out I was wrong.

The performance gap

I categorized trades by how many assets were oversold at the time of entry (the breadth). The results were the opposite of what I expected:

Breadth LevelWin RateProfit Factor (PF)
Q1 (Low breadth)79.9%2.25
Q5 (High breadth)59.7%0.97
In other words, when the breadth was high (0.18 or more), the Profit Factor dropped to 0.97, meaning the strategy was losing money. When the breadth reached 0.3 or higher, the PF fell further to 0.78.
The takeaway here is that when the entire market is selling off, it is usually a genuine “risk-off” event where prices keep falling, making mean reversion a dangerous “catching a falling knife” scenario. Conversely, when only a few assets are oversold, it represents a healthy, isolated correction that is much more likely to bounce back.

Why filtering failed

Even though I identified that high-breadth trades are lower quality, adding a filter to exclude them actually made the overall system worse.

  • Plain setup (no filters): PF 1.49, Sharpe 1.11, Relative Drawdown 0.54
  • Filtered setup (breadth < 0.18): PF 1.12, Sharpe 0.28 When I tested this on out-of-sample (OOS) data, which is data the system hasn’t seen during development, the plain version maintained a solid PF of 1.38, while the filtered version collapsed to a PF of 0.86. This is the third time I have seen this pattern in my research: finding a feature that identifies “low-quality” trades does not mean that turning it into a filter will improve your system. By excluding those trades, you lose the winning trades that happen to occur during those periods, and you lose the diversification benefits of taking a higher volume of setups. Connors’ original approach, which takes all setups, remains the most robust because it relies on the law of large numbers. The insight regarding market behavior is valid, and it provides a strong foundation for the logic behind my existing equity risk-off filter (v1.4.0). However, it cannot be used as an explicit filter for the Connors strategy itself. I will keep the system as is for v1.5.0.

How this connects

This verification builds on earlier ones (what failed before and what I tried this time, comparisons between approaches).