refactor: organize discovery config into dedicated filter/enrichment sections
- Created nested "filters" section for all filter-stage settings (min_average_volume, same-day movers, recent movers, etc.) - Created nested "enrichment" section for batch news settings - Updated CandidateFilter to read from new nested structure - Added backward compatibility fallback for old flat config - Improved config organization and clarity Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
41e91e72d1
commit
f1178b4a57
|
|
@ -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", [])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue