diff --git a/.claude/commands/research-strategy.md b/.claude/commands/research-strategy.md index 189c3b98..691f2e6e 100644 --- a/.claude/commands/research-strategy.md +++ b/.claude/commands/research-strategy.md @@ -154,12 +154,26 @@ If the finding meets the auto-implement threshold from Step 4: 3. Create `tradingagents/dataflows/discovery/scanners/.py` following the same structure: - Class decorated with `@SCANNER_REGISTRY.register()` - - `name` and `pipeline` class attributes + - `name`, `pipeline`, and `strategy` class attributes - `scan(self, state)` method returning `List[Dict]` - Each dict must have keys: `ticker`, `source`, `context`, `priority` - Priority values: `"CRITICAL"`, `"HIGH"`, `"MEDIUM"`, `"LOW"` -4. Check `tradingagents/dataflows/discovery/scanners/__init__.py` — if it - imports scanners explicitly, add an import for the new one. + - All tunable parameters must use `self.scanner_config.get("param", default)` + so they can be overridden from config without touching scanner code +4. Add an import in `tradingagents/dataflows/discovery/scanners/__init__.py`: + `from . import # noqa: F401` +5. **Add a config entry to `tradingagents/default_config.py`** under + `discovery.scanners.`. This is mandatory — without it the scanner + cannot be enabled/disabled or tuned from config, and is invisible to the + settings UI. Include every parameter that `self.scanner_config.get()` reads: + ```python + "": { + "enabled": True, + "pipeline": "", + "limit": 10, + "": , # one entry per scanner_config.get() call + }, + ``` If threshold is NOT met: write the research file only. Add this note at the top of the research file: diff --git a/tradingagents/default_config.py b/tradingagents/default_config.py index 4500aa44..3d2db515 100644 --- a/tradingagents/default_config.py +++ b/tradingagents/default_config.py @@ -209,6 +209,13 @@ DEFAULT_CONFIG = { "min_short_interest_pct": 15.0, # Minimum short interest % "min_days_to_cover": 5.0, # Minimum days to cover ratio }, + "earnings_beat": { + "enabled": True, + "pipeline": "events", + "limit": 10, + "lookback_days": 14, # Days to look back for recent EPS beats + "min_surprise_pct": 5.0, # Minimum EPS surprise % to surface + }, "ml_signal": { "enabled": True, "pipeline": "momentum", @@ -231,6 +238,18 @@ DEFAULT_CONFIG = { "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) }, + "high_52w_breakout": { + "enabled": True, + "pipeline": "momentum", + "limit": 10, + "max_tickers": 150, # Cap universe for scan speed + "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 + "freshness_threshold": 0.97, # Price must be within X% of 52w high + "min_price": 5.0, # Filter penny stocks + "min_avg_volume": 100_000, # Min avg daily volume for liquidity + }, }, }, # Memory settings