From 7567a17c828ec7e4da12ccd160c4c16ecfe495ff Mon Sep 17 00:00:00 2001 From: Youssef Aitousarrah Date: Tue, 14 Apr 2026 17:12:05 -0700 Subject: [PATCH] feat(scanners): remove max_tickers caps and raise timeout now that cache is in place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - timeout_seconds: 30 → 120 (cache load alone takes ~28s for 1003 tickers) - minervini max_tickers: 50 → 0 (no cap) - high_52w_breakout max_tickers: 150 → 0 (no cap) - Fix high_52w_breakout to treat max_tickers=0 as no cap (was slicing unconditionally) Co-Authored-By: Claude Sonnet 4.6 --- .../discovery/scanners/high_52w_breakout.py | 5 +++-- tradingagents/default_config.py | 14 +++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tradingagents/dataflows/discovery/scanners/high_52w_breakout.py b/tradingagents/dataflows/discovery/scanners/high_52w_breakout.py index f15520ff..550408bb 100644 --- a/tradingagents/dataflows/discovery/scanners/high_52w_breakout.py +++ b/tradingagents/dataflows/discovery/scanners/high_52w_breakout.py @@ -40,7 +40,7 @@ class High52wBreakoutScanner(BaseScanner): def __init__(self, config: Dict[str, Any]): super().__init__(config) - self.max_tickers = self.scanner_config.get("max_tickers", 150) + self.max_tickers = self.scanner_config.get("max_tickers", 0) # 0 = no cap # Academic threshold: 1.5x eliminates 63% of false signals self.min_volume_multiple = self.scanner_config.get("min_volume_multiple", 1.5) self.vol_avg_days = self.scanner_config.get("vol_avg_days", 20) @@ -62,7 +62,8 @@ class High52wBreakoutScanner(BaseScanner): logger.warning("No tickers loaded for 52w-high breakout scan") return [] - tickers = tickers[: self.max_tickers] + if self.max_tickers: + tickers = tickers[: self.max_tickers] cache_dir = self.config.get("discovery", {}).get("ohlcv_cache_dir", "data/ohlcv_cache") logger.info(f"Loading OHLCV for {len(tickers)} tickers from cache...") diff --git a/tradingagents/default_config.py b/tradingagents/default_config.py index dfb30464..aca33a82 100644 --- a/tradingagents/default_config.py +++ b/tradingagents/default_config.py @@ -121,7 +121,7 @@ DEFAULT_CONFIG = { "scanner_execution": { "concurrent": True, # Run scanners in parallel "max_workers": 8, # Max concurrent scanner threads - "timeout_seconds": 30, # Timeout per scanner + "timeout_seconds": 120, # Timeout per scanner (raised — cache load alone ~28s for 1003 tickers) }, # ======================================== # SCANNERS (each with scanner-specific settings) @@ -167,11 +167,11 @@ DEFAULT_CONFIG = { "enabled": True, "pipeline": "momentum", "limit": 10, - "lookback_days": 20, # Days to measure price/OBV change over - "min_obv_pct_gain": 8.0, # Min OBV gain as % of avg_vol × lookback_days + "lookback_days": 20, # Days to measure price/OBV change over + "min_obv_pct_gain": 8.0, # Min OBV gain as % of avg_vol × lookback_days "max_price_change_pct": 2.0, # Max price change % over lookback (divergence window) - "volume_cache_key": "default", # Shares cache with volume_accumulation scanner - "max_tickers": 2000, # Universe size cap + "volume_cache_key": "default", # Shares cache with volume_accumulation scanner + "max_tickers": 2000, # Universe size cap }, "market_movers": { "enabled": False, @@ -249,13 +249,13 @@ DEFAULT_CONFIG = { "sma_200_slope_days": 20, # Days back to check SMA200 slope "min_pct_off_low": 30, # Must be 30%+ above 52w low "max_pct_from_high": 25, # Must be within 25% of 52w high - "max_tickers": 50, # Cap universe to keep download under scanner timeout (~75s for 50 tickers x 1y) + "max_tickers": 0, # 0 = no cap (nightly cache makes full universe fast) }, "high_52w_breakout": { "enabled": True, "pipeline": "momentum", "limit": 10, - "max_tickers": 150, # Cap universe for scan speed + "max_tickers": 0, # 0 = no cap (nightly cache makes full universe fast) "min_volume_multiple": 1.5, # Min volume vs 20d avg to confirm breakout "vol_avg_days": 20, # Days for volume average baseline "freshness_days": 5, # Max days since 52w high was set