TradingAgents/tradingagents/graph/scanner_setup.py

62 lines
2.2 KiB
Python

"""Setup for the scanner workflow graph."""
from langgraph.graph import StateGraph, START, END
from tradingagents.agents.utils.scanner_states import ScannerState
class ScannerGraphSetup:
"""Sets up the scanner graph with LLM agent nodes.
Phase 1a (parallel from START):
geopolitical_scanner, market_movers_scanner, sector_scanner
Phase 1b (sequential after sector_scanner):
smart_money_scanner — runs after sector data is available so it can
use sector rotation context when interpreting Finviz signals
Phase 2: industry_deep_dive (fan-in from all Phase 1 nodes)
Phase 3: macro_synthesis -> END
"""
def __init__(self, agents: dict) -> None:
"""
Args:
agents: Dict mapping node names to agent node functions:
- geopolitical_scanner
- market_movers_scanner
- sector_scanner
- smart_money_scanner
- industry_deep_dive
- macro_synthesis
"""
self.agents = agents
def setup_graph(self):
"""Build and compile the scanner workflow graph.
Returns:
A compiled LangGraph graph ready to invoke.
"""
workflow = StateGraph(ScannerState)
for name, node_fn in self.agents.items():
workflow.add_node(name, node_fn)
# Phase 1a: parallel fan-out from START
workflow.add_edge(START, "geopolitical_scanner")
workflow.add_edge(START, "market_movers_scanner")
workflow.add_edge(START, "sector_scanner")
# Phase 1b: smart_money runs after sector (gets sector rotation context)
workflow.add_edge("sector_scanner", "smart_money_scanner")
# Fan-in: all Phase 1 nodes must complete before Phase 2
workflow.add_edge("geopolitical_scanner", "industry_deep_dive")
workflow.add_edge("market_movers_scanner", "industry_deep_dive")
workflow.add_edge("smart_money_scanner", "industry_deep_dive")
# Phase 2 -> Phase 3 -> END
workflow.add_edge("industry_deep_dive", "macro_synthesis")
workflow.add_edge("macro_synthesis", END)
return workflow.compile()