TradingAgents/tradingagents/graph/scanner_graph.py

74 lines
2.2 KiB
Python

# tradingagents/graph/scanner_graph.py
import datetime
from typing import Any, Dict, Optional
from tradingagents.dataflows.config import set_config
from tradingagents.default_config import DEFAULT_CONFIG
from .scanner_setup import ScannerGraphSetup
class MacroScannerGraph:
"""Orchestrates the Global Macro Scanner workflow.
The scanner runs three parallel data-collection phases followed by a
synthesis phase:
Phase 1 (parallel):
- Geopolitical / macro news scanner
- Market movers + index performance scanner
- Sector performance scanner
Phase 2 (sequential):
- Industry deep dive (technology sector by default)
Phase 3 (sequential):
- Macro synthesis — combines all outputs into a single summary
"""
def __init__(self, config: Optional[Dict[str, Any]] = None):
"""Initialise the scanner graph.
Args:
config: Optional configuration dictionary. Defaults to
``DEFAULT_CONFIG`` when not provided.
"""
self.config = config or DEFAULT_CONFIG
set_config(self.config)
self.graph_setup = ScannerGraphSetup()
self.graph = self.graph_setup.setup_graph()
def scan(self, scan_date: Optional[str] = None) -> Dict[str, Any]:
"""Execute the macro scan and return the final state.
Args:
scan_date: Date string in ``YYYY-MM-DD`` format. Defaults to
today's date when not provided.
Returns:
Final LangGraph state dictionary containing all scan reports and
the ``macro_scan_summary`` field.
"""
if scan_date is None:
scan_date = datetime.date.today().isoformat()
initial_state = {
"messages": [],
"scan_date": scan_date,
"geopolitical_report": "",
"market_movers_report": "",
"sector_performance_report": "",
"industry_deep_dive_report": "",
"macro_scan_summary": "",
"sender": "",
}
final_state = self.graph.invoke(
initial_state,
{"recursion_limit": self.config.get("max_recur_limit", 100)},
)
return final_state