diff --git a/tradingagents/dataflows/discovery/filter.py b/tradingagents/dataflows/discovery/filter.py index d189b60d..46c2030f 100644 --- a/tradingagents/dataflows/discovery/filter.py +++ b/tradingagents/dataflows/discovery/filter.py @@ -109,17 +109,25 @@ class CandidateFilter: # Discovery Settings discovery_config = config.get("discovery", {}) + + # Filter settings (nested under "filters" section, with backward compatibility) + filter_config = discovery_config.get("filters", discovery_config) # Fallback to root for old configs + self.filter_same_day_movers = filter_config.get("filter_same_day_movers", True) + self.intraday_movement_threshold = filter_config.get("intraday_movement_threshold", 10.0) + self.filter_recent_movers = filter_config.get("filter_recent_movers", True) + self.recent_movement_lookback_days = filter_config.get("recent_movement_lookback_days", 7) + self.recent_movement_threshold = filter_config.get("recent_movement_threshold", 10.0) + self.recent_mover_action = filter_config.get("recent_mover_action", "filter") + self.min_average_volume = filter_config.get("min_average_volume", 500_000) + self.volume_lookback_days = filter_config.get("volume_lookback_days", 10) + + # Enrichment settings (nested under "enrichment" section, with backward compatibility) + enrichment_config = discovery_config.get("enrichment", discovery_config) # Fallback to root + self.batch_news_vendor = enrichment_config.get("batch_news_vendor", "openai") + self.batch_news_batch_size = enrichment_config.get("batch_news_batch_size", 50) + + # Other settings (remain at discovery level) self.news_lookback_days = discovery_config.get("news_lookback_days", 3) - self.filter_same_day_movers = discovery_config.get("filter_same_day_movers", True) - self.intraday_movement_threshold = discovery_config.get("intraday_movement_threshold", 6.0) - self.filter_recent_movers = discovery_config.get("filter_recent_movers", True) - self.recent_movement_lookback_days = discovery_config.get( - "recent_movement_lookback_days", 7 - ) - self.recent_movement_threshold = discovery_config.get("recent_movement_threshold", 10.0) - self.recent_mover_action = discovery_config.get("recent_mover_action", "filter") - self.min_average_volume = discovery_config.get("min_average_volume", 500_000) - self.volume_lookback_days = discovery_config.get("volume_lookback_days", 10) self.volume_cache_key = discovery_config.get("volume_cache_key", "avg_volume_cache") self.min_market_cap = discovery_config.get("min_market_cap", 0) self.compression_atr_pct_max = discovery_config.get("compression_atr_pct_max", 2.0) @@ -128,9 +136,6 @@ class CandidateFilter: self.context_max_snippets = discovery_config.get("context_max_snippets", 2) self.context_snippet_max_chars = discovery_config.get("context_snippet_max_chars", 140) - self.batch_news_vendor = discovery_config.get("batch_news_vendor", "openai") - self.batch_news_batch_size = discovery_config.get("batch_news_batch_size", 50) - def filter(self, state: Dict[str, Any]) -> Dict[str, Any]: """Filter candidates based on strategy and enrich with additional data.""" candidates = state.get("candidate_metadata", []) diff --git a/tradingagents/default_config.py b/tradingagents/default_config.py index d5d82205..17548bd0 100644 --- a/tradingagents/default_config.py +++ b/tradingagents/default_config.py @@ -21,15 +21,13 @@ DEFAULT_CONFIG = { # Discovery settings "discovery": { # ======================================== - # GLOBAL SETTINGS (apply to all scanners) + # GLOBAL SETTINGS (ranking, analysis, output) # ======================================== "max_candidates_to_analyze": 200, # Maximum candidates for deep dive analysis "analyze_all_candidates": False, # If True, skip truncation and analyze all candidates "final_recommendations": 15, # Number of final opportunities to recommend "deep_dive_max_workers": 1, # Parallel workers for deep-dive analysis (1 = sequential) - - # Discovery mode: "traditional", "semantic", or "hybrid" - "discovery_mode": "hybrid", + "discovery_mode": "hybrid", # "traditional", "semantic", or "hybrid" # Ranking context truncation "truncate_ranking_context": False, # True = truncate to save tokens, False = full context @@ -37,27 +35,13 @@ DEFAULT_CONFIG = { "max_insider_chars": 300, # Only used if truncate_ranking_context=True "max_recommendations_chars": 300, # Only used if truncate_ranking_context=True - # Global filters (apply to all scanners) - "min_average_volume": 500_000, # Minimum average volume for liquidity filter - "volume_lookback_days": 10, # Days to average for liquidity filter - "filter_same_day_movers": True, # Filter stocks that moved significantly today - "intraday_movement_threshold": 10.0, # Intraday % change threshold to filter - "filter_recent_movers": True, # Filter stocks that already moved in recent days - "recent_movement_lookback_days": 7, # Days to check for recent move - "recent_movement_threshold": 10.0, # % change to consider as already moved - "recent_mover_action": "filter", # "filter" or "deprioritize" - - # Batch news enrichment - "batch_news_vendor": "google", # Vendor for batch news: "openai" or "google" - "batch_news_batch_size": 150, # Tickers per API call - # Tool execution logging "log_tool_calls": True, # Capture tool inputs/outputs to results logs "log_tool_calls_console": False, # Mirror tool logs to Python logger "tool_log_max_chars": 10_000, # Max chars stored per tool output "tool_log_exclude": ["validate_ticker"], # Tool names to exclude from logging - # Console price charts + # Console price charts (output formatting) "console_price_charts": True, # Render mini price charts in console output "price_chart_library": "plotille", # "plotille" (prettier) or "plotext" fallback "price_chart_windows": ["1d", "7d", "1m", "6m", "1y"], # Windows to render @@ -67,6 +51,32 @@ DEFAULT_CONFIG = { "price_chart_max_tickers": 10, # Max tickers to chart per run "price_chart_show_movement_stats": True, # Show movement stats in console + # ======================================== + # FILTER STAGE SETTINGS + # ======================================== + "filters": { + # Liquidity filter + "min_average_volume": 500_000, # Minimum average volume + "volume_lookback_days": 10, # Days to average for liquidity check + + # Same-day mover filter (remove stocks that already moved today) + "filter_same_day_movers": True, # Enable/disable filter + "intraday_movement_threshold": 10.0, # Intraday % change threshold + + # Recent mover filter (remove stocks that moved in recent days) + "filter_recent_movers": True, # Enable/disable filter + "recent_movement_lookback_days": 7, # Days to check for recent moves + "recent_movement_threshold": 10.0, # % change threshold + "recent_mover_action": "filter", # "filter" or "deprioritize" + }, + + # ======================================== + # ENRICHMENT STAGE SETTINGS + # ======================================== + "enrichment": { + "batch_news_vendor": "google", # Vendor for batch news: "openai" or "google" + "batch_news_batch_size": 150, # Tickers per API call + }, # ======================================== # PIPELINES (priority and budget per pipeline) # ======================================== @@ -75,33 +85,28 @@ DEFAULT_CONFIG = { "enabled": True, "priority": 1, "ranker_prompt": "edge_signals_ranker.txt", - "deep_dive_budget": 15 + "deep_dive_budget": 15, }, "momentum": { "enabled": True, "priority": 2, "ranker_prompt": "momentum_ranker.txt", - "deep_dive_budget": 10 + "deep_dive_budget": 10, }, "news": { "enabled": True, "priority": 3, "ranker_prompt": "news_catalyst_ranker.txt", - "deep_dive_budget": 5 + "deep_dive_budget": 5, }, "social": { "enabled": True, "priority": 4, "ranker_prompt": "social_signals_ranker.txt", - "deep_dive_budget": 5 + "deep_dive_budget": 5, }, - "events": { - "enabled": True, - "priority": 5, - "deep_dive_budget": 3 - } + "events": {"enabled": True, "priority": 5, "deep_dive_budget": 3}, }, - # ======================================== # SCANNER EXECUTION SETTINGS # ======================================== @@ -110,7 +115,6 @@ DEFAULT_CONFIG = { "max_workers": 8, # Max concurrent scanner threads "timeout_seconds": 30, # Timeout per scanner }, - # ======================================== # SCANNERS (each with scanner-specific settings) # ======================================== @@ -130,9 +134,28 @@ DEFAULT_CONFIG = { "unusual_volume_multiple": 2.0, # Min volume/OI ratio for unusual activity "min_premium": 25000, # Minimum premium ($) to filter noise "min_volume": 1000, # Minimum option volume to consider - "ticker_universe": ["AAPL", "MSFT", "GOOGL", "AMZN", "META", "NVDA", "AMD", "TSLA", - "TSMC", "ASML", "AVGO", "ORCL", "CRM", "ADBE", "INTC", "QCOM", - "TXN", "AMAT", "LRCX", "KLAC"], # Top 20 liquid options + "ticker_universe": [ + "AAPL", + "MSFT", + "GOOGL", + "AMZN", + "META", + "NVDA", + "AMD", + "TSLA", + "TSMC", + "ASML", + "AVGO", + "ORCL", + "CRM", + "ADBE", + "INTC", + "QCOM", + "TXN", + "AMAT", + "LRCX", + "KLAC", + ], # Top 20 liquid options }, "congress_trades": { "enabled": False, @@ -140,7 +163,6 @@ DEFAULT_CONFIG = { "limit": 10, "lookback_days": 7, # Days to look back for congressional trades }, - # Momentum - Price and volume signals "volume_accumulation": { "enabled": True, @@ -157,7 +179,6 @@ DEFAULT_CONFIG = { "pipeline": "momentum", "limit": 10, }, - # News - Catalyst-driven signals "semantic_news": { "enabled": True, @@ -176,7 +197,6 @@ DEFAULT_CONFIG = { "limit": 5, "lookback_days": 1, # Days to look back for rating changes }, - # Social - Community signals "reddit_trending": { "enabled": True, @@ -188,7 +208,6 @@ DEFAULT_CONFIG = { "pipeline": "social", "limit": 10, }, - # Events - Calendar-based signals "earnings_calendar": { "enabled": True, @@ -204,8 +223,8 @@ DEFAULT_CONFIG = { "limit": 5, "min_short_interest_pct": 15.0, # Minimum short interest % "min_days_to_cover": 5.0, # Minimum days to cover ratio - } - } + }, + }, }, # Memory settings "enable_memory": False, # Enable/disable embeddings and memory system