How to Configure Risk Management Debate Rounds and Conditional Logic in TradingAgents-CN
TradingAgents-CN controls risk-management debate iterations through the max_risk_discuss_rounds configuration parameter, which the ConditionalLogic class uses to determine when to route the LangGraph workflow to the Risk Judge node.
The TradingAgents-CN repository implements a multi-agent debate system where risk analysts argue investment safety before a final decision is rendered. You can configure how many rounds these risk-management debates execute and define custom conditional logic to control the flow. This guide explains the configuration architecture, the state management mechanism, and practical implementation patterns using the actual source code.
Understanding the Risk Management Debate Architecture
TradingAgents-CN runs the investment-research and risk-management teams as debates inside a LangGraph workflow. The system tracks debate progress through a dedicated state object and uses a conditional logic helper to determine when to continue debating versus when to render a final judgment.
State Tracking with RiskDebateState
The risk debate state is defined in tradingagents/agents/utils/agent_states.py within the RiskDebateState TypedDict. This structure tracks the conversation history for each analyst (risky, safe, and neutral), identifies the latest speaker, stores current responses, records the judge's decision, and maintains a turn counter.
# tradingagents/agents/utils/agent_states.py
class RiskDebateState(TypedDict):
risky_history: str
safe_history: str
neutral_history: str
history: str
latest_speaker: str # "Risky Analyst", "Safe Analyst", or "Neutral Analyst"
current_risky_response: str
current_safe_response: str
current_neutral_response: str
judge_decision: str
count: int # total turns taken by the risk team
The count field increments with every analyst response and serves as the primary metric for enforcing round limits.
The ConditionalLogic Controller
The ConditionalLogic class in tradingagents/graph/conditional_logic.py implements the core routing decisions. It receives configuration parameters during graph construction and uses them to determine the next node in the workflow.
Configuring Debate Rounds
The number of risk-management discussion rounds is configurable via the max_risk_discuss_rounds setting. This value flows through multiple configuration layers before reaching the conditional logic controller.
Default Configuration Settings
The default value resides in tradingagents/default_config.py. By default, the system allows one full round of risk discussion (meaning each of the three analysts speaks once before evaluation).
# tradingagents/default_config.py (lines 17-19)
MAX_RISK_DISCUSS_ROUNDS = 1
When the graph initializes, this value propagates to the ConditionalLogic instance in tradingagents/graph/trading_graph.py (lines 777-785).
CLI-Based Configuration
You can adjust the debate depth through the command-line interface. The CLI maps research depth selections to specific max_risk_discuss_rounds values in cli/main.py around line 1045.
python -m tradingagents.cli --research-depth 4
In this example, a research depth of 4 maps to max_risk_discuss_rounds = 2, allowing six total analyst turns (two rounds × three analysts) before the Risk Judge intervenes.
Programmatic Configuration
For custom integrations, override the configuration dictionary before instantiating TradingGraph:
from tradingagents.graph.trading_graph import TradingGraph
from tradingagents.utils.config import load_config
# Load defaults and modify risk rounds
cfg = load_config()
cfg["max_risk_discuss_rounds"] = 2 # Allow two full rounds
graph = TradingGraph(config=cfg)
graph.propagate("AAPL", "2024-09-30")
The ConditionalLogic class receives this value during graph construction and enforces it throughout the workflow execution.
How Conditional Logic Enforces Round Limits
The should_continue_risk_analysis method in tradingagents/graph/conditional_logic.py (lines 19-43) implements the round-limit enforcement. It calculates the maximum allowed turns as 3 × max_risk_discuss_rounds because each round consists of three analysts (Risky, Safe, and Neutral).
def should_continue_risk_analysis(self, state: AgentState) -> str:
current_count = state["risk_debate_state"]["count"]
max_count = 3 * self.max_risk_discuss_rounds # ← 3 analysts per round
latest_speaker = state["risk_debate_state"]["latest_speaker"]
if current_count >= max_count:
return "Risk Judge"
# Logic to determine next speaker based on rotation...
When the count reaches the threshold, the method returns "Risk Judge", routing the LangGraph workflow to the judge node that aggregates the debate into a final risk assessment stored in risk_debate_state["judge_decision"].
Customizing Conditional Behavior (Advanced)
While the default ConditionalLogic class handles standard round-based termination, you can implement custom stopping criteria by subclassing the controller. For example, you might want to terminate early if the Risky Analyst mentions "high risk" in their response.
from tradingagents.graph.conditional_logic import ConditionalLogic
class EarlyStopLogic(ConditionalLogic):
def should_continue_risk_analysis(self, state):
# Check for early termination condition
if "high risk" in state["risk_debate_state"]["risky_history"]:
return "Risk Judge"
return super().should_continue_risk_analysis(state)
# Use custom logic in graph construction
graph = TradingGraph(config=cfg, conditional_logic_cls=EarlyStopLogic)
Note that the base TradingGraph class in the repository instantiates ConditionalLogic directly; extending it with custom logic classes requires modifying the graph initialization or using dependency injection patterns as shown above.
Summary
- Configuration Location: Set
max_risk_discuss_roundsintradingagents/default_config.py, via CLI flags incli/main.py, or programmatically in the config dictionary. - Calculation Logic: The
ConditionalLogicclass multiplies this setting by 3 (one per analyst) to determine the total turn count before invoking the Risk Judge. - State Management: The
RiskDebateStateTypedDict intradingagents/agents/utils/agent_states.pytracks thecount,latest_speaker, and individual analyst histories. - Routing Decision: The
should_continue_risk_analysismethod intradingagents/graph/conditional_logic.pyreturns"Risk Judge"when limits are reached, terminating the debate.
Frequently Asked Questions
How do I increase the number of risk debate rounds in TradingAgents-CN?
You can increase the rounds by setting the max_risk_discuss_rounds configuration value to 2 or higher. Modify tradingagents/default_config.py directly, use the CLI --research-depth flag (where higher depths map to more rounds), or override the value programmatically when constructing the TradingGraph instance. Each increment adds three additional analyst turns (one per analyst) before the Risk Judge finalizes the assessment.
What happens when the risk debate reaches the maximum round limit?
When the debate counter in risk_debate_state["count"] reaches 3 × max_risk_discuss_rounds, the should_continue_risk_analysis method in tradingagents/graph/conditional_logic.py returns the string "Risk Judge". This return value routes the LangGraph workflow to the Risk Judge node, which aggregates the debate history from all three analysts and writes the final decision into risk_debate_state["judge_decision"], terminating the risk analysis phase.
Where is the risk debate state stored during execution?
The risk debate state is stored within the main AgentState under the key risk_debate_state. The structure is defined by the RiskDebateState TypedDict in tradingagents/agents/utils/agent_states.py. It contains fields for each analyst's conversation history (risky_history, safe_history, neutral_history), their current responses, the latest_speaker identifier, the judge_decision, and the integer count that tracks total turns taken.
Can I implement custom logic to stop the risk debate early?
Yes, you can implement custom stopping logic by subclassing the ConditionalLogic class from tradingagents/graph/conditional_logic.py and overriding the should_continue_risk_analysis method. For example, you could parse the risky_history or safe_history strings for specific keywords like "high risk" or "market crash" and return "Risk Judge" immediately to trigger early termination. Pass your custom class to the TradingGraph constructor or modify the graph initialization to use your logic instead of the default implementation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →