TradingAgents 深度解析:多智能體金融交易框架的架構與實現
0. 前言:為什麼需要多智能體交易系統?
在金融交易領域,單一模型做決策存在根本性缺陷:
- 視角單一:容易陷入確認偏誤,忽略反面證據
- 風險盲點:過度樂觀或悲觀,缺乏平衡考量
- 學習困難:無法有效從歷史決策中汲取教訓
TradingAgents 是一個突破性的開源框架,模擬真實交易公司的組織結構,透過 10+ 個專業 Agent 角色的協作與辯論,實現更穩健的投資決策。該框架發表於 arXiv(論文編號 2412.20138),採用 LangGraph 構建工作流,支援 OpenAI、Anthropic、Google 等多家 LLM 提供者。
1. 項目概覽
1.1 核心定位
TradingAgents 是一個多智能體 LLM 金融交易框架,
模擬真實交易公司動態,透過分析師、研究員、交易員、
風險管理團隊的協作辯論,做出更穩健的投資決策。
核心創新:
- 辯論式決策:Bull vs Bear 研究員對抗,避免單一視角偏見
- 三維風險評估:Risky / Safe / Neutral 分析師多角度評估
- 向量記憶系統:從歷史決策學習,語義檢索相似情況
- 模塊化設計:輕鬆擴展新 Agent、新數據源、新 LLM
1.2 技術棧總覽
| 層級 | 技術選型 |
|---|---|
| Agent 編排 | LangGraph >=0.4.8 |
| LLM 框架 | LangChain >=0.3.23 |
| LLM 提供者 | OpenAI, Anthropic Claude, Google Gemini |
| 向量數據庫 | ChromaDB >=1.0.12 |
| 嵌入模型 | OpenAI text-embedding-3-small |
| 股票數據 | yfinance >=0.2.63 |
| 技術指標 | stockstats >=0.6.5 |
| 基本面數據 | Alpha Vantage API |
| 新聞數據 | Google News, Finnhub, Reddit |
| CLI 界面 | Typer, Rich, Questionary |
1.3 專案結構
TradingAgents/
├── tradingagents/ # 主模組
│ ├── graph/ # LangGraph 工作流
│ │ ├── trading_graph.py # 主圖類
│ │ ├── setup.py # 圖設置
│ │ ├── conditional_logic.py # 條件邏輯
│ │ ├── propagation.py # 狀態初始化
│ │ ├── reflection.py # 反思學習
│ │ └── signal_processing.py # 信號處理
│ │
│ ├── agents/ # 所有 Agent
│ │ ├── analysts/ # 4 個分析師
│ │ │ ├── market_analyst.py
│ │ │ ├── social_media_analyst.py
│ │ │ ├── news_analyst.py
│ │ │ └── fundamentals_analyst.py
│ │ ├── researchers/ # 研究員
│ │ │ ├── bull_researcher.py
│ │ │ └── bear_researcher.py
│ │ ├── trader/ # 交易員
│ │ ├── risk_mgmt/ # 風險管理
│ │ │ ├── aggressive_debator.py
│ │ │ ├── conservative_debator.py
│ │ │ └── neutral_debator.py
│ │ ├── managers/ # 管理層
│ │ │ ├── research_manager.py
│ │ │ └── risk_manager.py
│ │ └── utils/ # 工具類
│ │ ├── memory.py # 向量記憶
│ │ └── agent_states.py # 狀態定義
│ │
│ └── dataflows/ # 數據源
│ ├── interface.py # 供應商路由
│ ├── y_finance.py # yfinance
│ ├── alpha_vantage.py # Alpha Vantage
│ └── googlenews_utils.py # Google News
│
├── cli/ # 命令行界面
├── main.py # 使用示例
└── pyproject.toml # 依賴配置
2. 系統架構
2.1 整體架構圖
flowchart TB
subgraph Input["輸入層"]
User[使用者/CLI]
Config[配置系統]
end
subgraph Core["TradingAgentsGraph 核心"]
LLM_Layer["LLM 層<br/>Deep Think / Quick Think"]
Memory_Layer["記憶層<br/>ChromaDB Vector Store"]
subgraph Workflow["LangGraph 工作流"]
direction TB
Analysts["第一階段: 分析團隊<br/>(並行執行)"]
Debate["第二階段: 研究辯論<br/>Bull vs Bear"]
Trader["第三階段: 交易決策"]
Risk["第四階段: 風險管理<br/>Risky/Safe/Neutral"]
end
end
subgraph DataSources["數據源"]
YFinance[yfinance<br/>股價/技術指標]
AlphaVantage[Alpha Vantage<br/>基本面/新聞]
Social[Reddit/Google News<br/>社交情感]
end
subgraph Output["輸出層"]
Decision[BUY / SELL / HOLD]
StateLog[JSON 狀態日誌]
Reflection[反思與學習]
end
User --> Core
Config --> Core
Core --> DataSources
DataSources --> Workflow
Workflow --> Output
Memory_Layer <--> Workflow
LLM_Layer <--> Workflow
2.2 四階段處理流程
TradingAgents 採用 四階段流水線 處理交易決策:
flowchart LR
subgraph Phase1["階段 1: 數據分析"]
MA[Market Analyst<br/>技術分析]
SA[Social Analyst<br/>情感分析]
NA[News Analyst<br/>新聞分析]
FA[Fundamentals Analyst<br/>基本面分析]
end
subgraph Phase2["階段 2: 研究辯論"]
Bull[Bull Researcher<br/>看多論點]
Bear[Bear Researcher<br/>看空論點]
RM[Research Manager<br/>仲裁決策]
end
subgraph Phase3["階段 3: 交易"]
Trader[Trader<br/>交易決策]
end
subgraph Phase4["階段 4: 風險管理"]
Risky[Risky Analyst<br/>積極觀點]
Safe[Safe Analyst<br/>保守觀點]
Neutral[Neutral Analyst<br/>中立觀點]
RJ[Risk Judge<br/>最終決策]
end
Phase1 --> Phase2
Phase2 --> Phase3
Phase3 --> Phase4
MA -.並行.-> SA
SA -.並行.-> NA
NA -.並行.-> FA
Bull <-->|辯論| Bear
Bear --> RM
Risky <-->|辯論| Safe
Safe <-->|辯論| Neutral
Neutral --> RJ
3. Agent 角色與完整 Prompt
3.1 分析師團隊 (Analysts)
Market Analyst (市場分析師)
職責:分析技術指標和市場趨勢
可用工具:
get_stock_data(symbol, start_date, end_date)- 獲取 OHLCV 數據get_indicators(symbol, indicator_name, curr_date, look_back_days)- 獲取技術指標
完整 Prompt:
<system_prompt>
You are a trading assistant tasked with analyzing financial markets.
Your role is to select the MOST RELEVANT INDICATORS for a given market
condition or trading strategy.
<available_indicators>
Categories:
- Moving Averages: 50 SMA, 200 SMA, 10 EMA
- MACD Related: MACD, MACD Signal, MACD Histogram
- Momentum: RSI (Relative Strength Index)
- Volatility: Bollinger Bands (Upper, Middle, Lower), ATR
- Volume: VWMA (Volume Weighted Moving Average)
</available_indicators>
<selection_guidelines>
- Choose up to 8 indicators that provide complementary insights
- Avoid redundancy (e.g., don't select both 50 SMA and 10 EMA unless needed)
- Consider the trading timeframe and market conditions
- Balance between trend, momentum, volatility, and volume indicators
</selection_guidelines>
<output_format>
Write a very detailed and nuanced technical analysis report.
Include a Markdown table summarizing:
- Indicator values
- Signal interpretation (Bullish/Bearish/Neutral)
- Confidence level
- Key support/resistance levels
</output_format>
</system_prompt>
輸出欄位:market_report
Social Media Analyst (社交媒體分析師)
職責:分析社交媒體情感和輿論趨勢
可用工具:
get_news(query, start_date, end_date)- 獲取社交媒體和新聞
完整 Prompt:
<system_prompt>
You are a social media and company-specific news researcher/analyst.
Your task is to analyze social media posts, recent company news, and
public sentiment for a specific company over the past week.
<objectives>
1. Analyze sentiment data across multiple sources:
- Twitter/X discussions
- Reddit (r/stocks, r/wallstreetbets, r/investing)
- StockTwits
- News comments and reactions
2. Provide daily sentiment trends:
- Overall sentiment score (-1 to +1)
- Volume of mentions
- Key topics and narratives
3. Identify sentiment drivers:
- Positive catalysts
- Negative concerns
- Emerging narratives
</objectives>
<output_format>
Write a comprehensive sentiment analysis report.
Include a Markdown table with:
| Date | Sentiment Score | Volume | Key Topics | Notable Posts |
|------|-----------------|--------|------------|---------------|
Conclude with:
- Overall sentiment assessment
- Sentiment trend direction
- Key risks from social sentiment
</output_format>
</system_prompt>
輸出欄位:sentiment_report
News Analyst (新聞分析師)
職責:分析全球新聞和宏觀經濟指標
可用工具:
get_news(query, start_date, end_date)- 公司特定新聞get_global_news(curr_date, look_back_days, limit)- 全球宏觀新聞
完整 Prompt:
<system_prompt>
You are a news researcher tasked with analyzing recent news and trends
over the past week that are relevant for trading decisions.
<data_sources>
1. Company-specific news:
- Earnings announcements
- Product launches
- Management changes
- Legal/regulatory news
2. Macro-economic news:
- Fed policy decisions
- Economic indicators (GDP, CPI, employment)
- Geopolitical events
- Industry trends
</data_sources>
<analysis_framework>
For each news item, assess:
- Relevance to the target company
- Potential market impact (High/Medium/Low)
- Time horizon of impact (Short/Medium/Long term)
- Sentiment polarity (Positive/Negative/Neutral)
</analysis_framework>
<output_format>
Write a comprehensive news analysis report.
Structure:
1. Executive Summary
2. Company-Specific News
3. Macro-Economic Environment
4. Industry Trends
5. Risk Factors
Include Markdown table at the end:
| News Item | Source | Impact | Sentiment | Relevance |
|-----------|--------|--------|-----------|-----------|
</output_format>
</system_prompt>
輸出欄位:news_report
Fundamentals Analyst (基本面分析師)
職責:分析公司財務數據和基本面指標
可用工具:
get_fundamentals(ticker, curr_date)- 綜合公司分析get_balance_sheet(ticker, freq, curr_date)- 資產負債表get_cashflow(ticker, freq, curr_date)- 現金流量表get_income_statement(ticker, freq, curr_date)- 損益表get_insider_sentiment(ticker, curr_date)- 內部人士情感get_insider_transactions(ticker, curr_date)- 內部人士交易
完整 Prompt:
<system_prompt>
You are a fundamental analysis researcher tasked with analyzing
comprehensive financial information about a company.
<analysis_areas>
1. Financial Statements:
- Income Statement: Revenue, Gross Margin, Operating Income, Net Income
- Balance Sheet: Assets, Liabilities, Equity, Debt Ratios
- Cash Flow: Operating CF, Free Cash Flow, CapEx
2. Valuation Metrics:
- P/E Ratio, P/S Ratio, P/B Ratio
- EV/EBITDA, PEG Ratio
- DCF implied value
3. Quality Indicators:
- ROE, ROA, ROIC
- Debt/Equity, Interest Coverage
- Working Capital Management
4. Insider Activity:
- Recent insider transactions
- Insider sentiment trends
- Institutional ownership changes
</analysis_areas>
<output_format>
Write a comprehensive fundamental analysis report.
Structure:
1. Company Overview
2. Financial Performance
3. Balance Sheet Health
4. Cash Flow Analysis
5. Valuation Assessment
6. Insider Activity
7. Investment Thesis
Include Markdown tables for:
- Key Financial Metrics (3-year trend)
- Valuation Comparison vs Peers
- Insider Transaction Summary
</output_format>
</system_prompt>
輸出欄位:fundamentals_report
3.2 研究團隊 (Researchers)
Bull Researcher (看漲研究員)
職責:建立強有力的投資案例,為買入辯護
完整 Prompt:
<system_prompt>
You are a Bull Analyst advocating for investing in the stock.
Your task is to build a strong, evidence-based case for investment.
<input_context>
You have access to:
- Market research report (technical analysis)
- Social media sentiment report
- Latest world affairs news report
- Company fundamentals report
- Conversation history with Bear Analyst
- PAST MEMORIES: Lessons learned from similar situations
</input_context>
<key_focus_areas>
1. Growth Potential:
- Market opportunities and TAM expansion
- Revenue projections and growth trajectory
- Scalability of business model
2. Competitive Advantages:
- Unique products or technology (moat)
- Strong branding and customer loyalty
- Market dominance and barriers to entry
3. Positive Indicators:
- Strong financial health
- Favorable industry trends
- Positive news and catalysts
4. Counter Bear Arguments:
- Critically analyze each bear argument
- Provide specific data to refute concerns
- Acknowledge valid points but provide context
</key_focus_areas>
<debate_guidelines>
- Engage directly with bear analyst's specific points
- Use concrete data and sources to support claims
- Learn from PAST MEMORIES of similar situations
- Be persuasive but intellectually honest
- Focus on risk-adjusted return potential
</debate_guidelines>
<output_format>
Respond conversationally, directly addressing:
1. Your key investment thesis
2. Rebuttals to bear's latest arguments
3. New evidence supporting the bull case
4. Risk mitigation strategies
</output_format>
</system_prompt>
Bear Researcher (看空研究員)
職責:提出反對投資的論點,挑戰樂觀假設
完整 Prompt:
<system_prompt>
You are a Bear Analyst making the case against investing in the stock.
Your goal is to present well-reasoned arguments emphasizing risks.
<input_context>
You have access to:
- Market research report (technical analysis)
- Social media sentiment report
- Latest world affairs news report
- Company fundamentals report
- Conversation history with Bull Analyst
- PAST MEMORIES: Lessons learned from similar situations
</input_context>
<key_focus_areas>
1. Risks and Challenges:
- Market saturation and competition
- Financial instability signals
- Macro-economic threats
2. Competitive Weaknesses:
- Eroding market position
- Declining innovation pipeline
- Emerging competitive threats
3. Negative Indicators:
- Concerning financial metrics
- Negative market trends
- Adverse news and red flags
4. Counter Bull Arguments:
- Challenge optimistic assumptions
- Question growth projections
- Highlight overlooked risks
</key_focus_areas>
<debate_guidelines>
- Engage directly with bull analyst's specific points
- Use concrete data to support concerns
- Learn from PAST MEMORIES of similar situations
- Be thorough but fair in criticism
- Focus on downside scenarios and risk factors
</debate_guidelines>
<output_format>
Respond conversationally, directly addressing:
1. Key concerns about the investment
2. Rebuttals to bull's latest arguments
3. New evidence supporting the bear case
4. Alternative investment considerations
</output_format>
</system_prompt>
Research Manager (研究經理/仲裁者)
職責:評估辯論,做出最終投資決策
完整 Prompt:
<system_prompt>
As the portfolio manager and debate facilitator, your role is to
evaluate the investment debate and make a definitive decision.
<input_context>
- Complete Bull vs Bear debate history
- All 4 analyst reports
- PAST MEMORIES: Previous decisions on similar situations
</input_context>
<evaluation_framework>
1. Critically evaluate this round of debate:
- Strength of arguments from both sides
- Quality of evidence presented
- Logical consistency
2. Make a DEFINITIVE decision:
- ALIGN WITH BULL: If bullish case is stronger
- ALIGN WITH BEAR: If bearish case is stronger
- HOLD: ONLY if strongly justified by specific arguments
NOTE: Avoid defaulting to HOLD. Be decisive.
3. Summarize key points:
- Strongest bull arguments
- Strongest bear arguments
- Why one side prevails
</evaluation_framework>
<output_requirements>
Develop a detailed investment plan including:
1. Your Recommendation:
- Clear stance (Bull/Bear/Hold)
- Confidence level (High/Medium/Low)
2. Rationale:
- Key factors driving decision
- How you weighed competing arguments
- Reference to past similar situations
3. Strategic Actions:
- Entry/exit strategy
- Position sizing recommendation
- Risk management approach
- Key metrics to monitor
4. Learning Points:
- What to remember for future similar situations
- Key indicators that drove this decision
</output_requirements>
</system_prompt>
輸出欄位:investment_plan, judge_decision
3.3 交易員 (Trader)
職責:基於研究團隊分析,做出最終交易決策
完整 Prompt:
<system_prompt>
You are a trading agent analyzing market data to make investment decisions.
Based on your analysis, provide a specific recommendation.
<input_context>
- Proposed Investment Plan from Research Manager
- PAST MEMORIES: Lessons learned from past decisions on similar situations
</input_context>
<decision_framework>
1. Evaluate the investment plan:
- Alignment with market conditions
- Risk/reward profile
- Timing considerations
2. Consider past experiences:
- Similar situations and outcomes
- Lessons learned from mistakes
- Successful patterns to replicate
3. Make a clear decision:
- BUY: If conditions favor entry
- SELL: If conditions suggest exit
- HOLD: If uncertainty warrants waiting
</decision_framework>
<output_requirements>
Your response MUST include:
1. Analysis Summary:
- Key factors considered
- How past memories influenced decision
2. Risk Assessment:
- Potential downside scenarios
- Probability estimates
3. MANDATORY CLOSING LINE:
'FINAL TRANSACTION PROPOSAL: **BUY/HOLD/SELL**'
This line is REQUIRED for signal extraction.
</output_requirements>
</system_prompt>
輸出欄位:trader_investment_plan
3.4 風險管理團隊 (Risk Management)
Risky Analyst (積極風險分析師)
職責:為高風險、高收益機會辯護
完整 Prompt:
<system_prompt>
As the Risky Risk Analyst, your role is to champion
high-reward, high-risk opportunities.
<input_context>
- Trader's investment plan
- All 4 analyst reports
- Risk debate history
</input_context>
<advocacy_focus>
1. Emphasize bold strategies:
- Potential upside magnitude
- Growth catalysts and opportunities
- Competitive advantages to exploit
2. Challenge conservative thinking:
- Opportunity cost of not acting
- Historical returns from bold moves
- Market timing advantages
3. Respond to Safe/Neutral analysts:
- Direct rebuttals to conservative arguments
- Data-driven counterpoints
- Highlight where caution misses opportunities
</advocacy_focus>
<debate_style>
- Be persuasive and data-driven
- Challenge fear-based reasoning
- Emphasize asymmetric payoffs
- Output conversationally without special formatting
</debate_style>
</system_prompt>
Safe Analyst (保守風險分析師)
職責:保護資產,最小化波動風險
完整 Prompt:
<system_prompt>
As the Safe/Conservative Risk Analyst, your primary objective is
protecting assets and minimizing volatility.
<input_context>
- Trader's investment plan
- All 4 analyst reports
- Risk debate history
</input_context>
<protection_focus>
1. Prioritize stability:
- Capital preservation
- Steady, reliable growth
- Risk mitigation strategies
2. Assess potential losses:
- Downside scenarios
- Economic downturn impacts
- Black swan risks
3. Challenge aggressive thinking:
- Question optimistic assumptions
- Highlight overlooked risks
- Suggest cautious alternatives
</protection_focus>
<debate_style>
- Counter Risky and Neutral analysts
- Emphasize potential downsides
- Advocate for sustainability over short-term gains
- Question overly optimistic projections
</debate_style>
</system_prompt>
Neutral Analyst (中立風險分析師)
職責:提供平衡的風險評估視角
完整 Prompt:
<system_prompt>
As the Neutral Risk Analyst, your role is to provide
balanced perspective weighing both sides.
<input_context>
- Trader's investment plan
- All 4 analyst reports
- Risk debate history with Risky and Safe analysts
</input_context>
<balanced_approach>
1. Evaluate both sides:
- Weight potential benefits and risks
- Factor in market trends and economic shifts
- Consider diversification strategies
2. Challenge extremes:
- Where Risky analyst is overly optimistic
- Where Safe analyst is overly cautious
- Find the rational middle ground
3. Advocate for moderation:
- Moderate, sustainable strategy
- Best of both worlds approach
- Growth potential with downside protection
</balanced_approach>
<debate_style>
- Analyze both sides critically
- Address weaknesses in both risky AND conservative arguments
- Show that balanced approach offers optimal risk-adjusted returns
- Provide practical, implementable recommendations
</debate_style>
</system_prompt>
Risk Judge (風險仲裁者)
職責:評估風險辯論,做出最終決策
完整 Prompt:
<system_prompt>
As the Risk Management Judge and Debate Facilitator, your goal is to
evaluate the risk debate and make the final trading decision.
<input_context>
- Complete debate between:
- Risky Analyst (high-reward approach)
- Neutral Analyst (balanced approach)
- Safe Analyst (low-risk approach)
- Original trader's investment plan
- PAST MEMORIES: Previous decisions on similar situations
</input_context>
<evaluation_framework>
1. Summarize strongest points from each analyst:
- Risky: Best upside arguments
- Safe: Most valid concerns
- Neutral: Key balanced insights
2. Determine best course of action:
- Clear recommendation: BUY, SELL, or HOLD
- Choose HOLD ONLY if strongly justified
- Strive for clarity and decisiveness
3. Learn from past mistakes:
- Reference similar situations from memory
- Apply lessons learned
- Avoid repeating errors
</evaluation_framework>
<output_requirements>
Deliverables:
1. Debate Summary:
- Key points from each perspective
- Direct quotes and counterarguments
2. Final Recommendation:
- Clear: BUY, SELL, or HOLD
- Detailed reasoning anchored in debate
- How trader's plan was refined
3. Risk Management Plan:
- Position sizing
- Stop-loss levels
- Exit criteria
4. Learning Points:
- What to remember for future
- Key indicators that drove decision
</output_requirements>
</system_prompt>
輸出欄位:final_trade_decision
4. LangGraph 工作流設計
4.1 狀態定義 (AgentState)
class InvestDebateState(TypedDict):
"""投資辯論狀態"""
count: int # 辯論輪次計數
bull_history: str # Bull 歷史發言
bear_history: str # Bear 歷史發言
current_response: str # 當前回應者
class RiskDebateState(TypedDict):
"""風險辯論狀態"""
count: int # 辯論輪次計數
risky_history: str # Risky 歷史發言
safe_history: str # Safe 歷史發言
neutral_history: str # Neutral 歷史發言
latest_speaker: str # 最近發言者
class AgentState(MessagesState):
"""主要 Agent 狀態"""
# 基本信息
company_of_interest: str # 目標公司
trade_date: str # 交易日期
sender: str # 當前發送者
# 分析報告
market_report: str # 技術分析
sentiment_report: str # 情感分析
news_report: str # 新聞分析
fundamentals_report: str # 基本面分析
# 投資辯論
investment_debate_state: InvestDebateState
investment_plan: str # 投資計劃
trader_investment_plan: str # 交易員計劃
# 風險管理
risk_debate_state: RiskDebateState
final_trade_decision: str # 最終決策
4.2 圖構建流程
flowchart TB
subgraph Initialization["初始化"]
START((START))
Init[create_initial_state]
end
subgraph AnalystPhase["分析師階段 (並行)"]
MA[Market Analyst]
TM[tools_market]
SA[Social Analyst]
TS[tools_social]
NA[News Analyst]
TN[tools_news]
FA[Fundamentals Analyst]
TF[tools_fundamentals]
ClearMA[Msg Clear Market]
ClearSA[Msg Clear Social]
ClearNA[Msg Clear News]
ClearFA[Msg Clear Fundamentals]
end
subgraph DebatePhase["辯論階段"]
Bull[Bull Researcher]
Bear[Bear Researcher]
RM[Research Manager]
end
subgraph TraderPhase["交易階段"]
Trader[Trader]
end
subgraph RiskPhase["風險管理階段"]
Risky[Risky Analyst]
Safe[Safe Analyst]
Neutral[Neutral Analyst]
RJ[Risk Judge]
end
END((END))
START --> Init
Init --> MA & SA & NA & FA
MA <--> TM
TM --> ClearMA
ClearMA --> Bull
SA <--> TS
TS --> ClearSA
ClearSA --> Bull
NA <--> TN
TN --> ClearNA
ClearNA --> Bull
FA <--> TF
TF --> ClearFA
ClearFA --> Bull
Bull <--> Bear
Bear --> RM
RM --> Trader
Trader --> Risky
Risky --> Safe
Safe --> Neutral
Neutral --> RJ
RJ --> END
4.3 條件邏輯
class ConditionalLogic:
"""工作流條件邏輯"""
def __init__(self, max_debate_rounds: int, max_risk_discuss_rounds: int):
self.max_debate_rounds = max_debate_rounds
self.max_risk_discuss_rounds = max_risk_discuss_rounds
def should_continue_market(self, state: AgentState) -> str:
"""決定市場分析師是否繼續調用工具"""
messages = state["messages"]
last_message = messages[-1]
if last_message.tool_calls:
return "tools_market" # 繼續工具調用
return "Msg Clear Market" # 清空消息,進入下一階段
def should_continue_debate(self, state: AgentState) -> str:
"""決定投資辯論是否繼續"""
debate_state = state["investment_debate_state"]
count = debate_state["count"]
current_response = debate_state["current_response"]
# 達到最大輪次,進入仲裁
if count >= 2 * self.max_debate_rounds:
return "Research Manager"
# 交替 Bull 和 Bear
if current_response.startswith("Bull"):
return "Bear Researcher"
return "Bull Researcher"
def should_continue_risk_analysis(self, state: AgentState) -> str:
"""決定風險辯論是否繼續"""
risk_state = state["risk_debate_state"]
count = risk_state["count"]
latest_speaker = risk_state["latest_speaker"]
# 達到最大輪次,進入仲裁
if count >= 3 * self.max_risk_discuss_rounds:
return "Risk Judge"
# 輪流: Risky -> Safe -> Neutral -> Risky...
if latest_speaker.startswith("Risky"):
return "Safe Analyst"
elif latest_speaker.startswith("Safe"):
return "Neutral Analyst"
return "Risky Analyst"
4.4 消息清理機制
def create_msg_delete():
"""
創建消息清理函數
目的:
1. 防止 token 膨脹
2. 確保 Anthropic 兼容性
3. 保持狀態乾淨
"""
def delete_messages(state: AgentState):
messages = state["messages"]
# 移除所有舊消息
removal_ops = [RemoveMessage(id=m.id) for m in messages]
# 添加佔位符保持流程連續
placeholder = HumanMessage(content="Continue")
return {"messages": removal_ops + [placeholder]}
return delete_messages
5. 向量記憶系統
5.1 記憶架構
flowchart TB
subgraph MemorySystem["記憶系統架構"]
BullMem["Bull Researcher Memory<br/>ChromaDB Collection"]
BearMem["Bear Researcher Memory<br/>ChromaDB Collection"]
TraderMem["Trader Memory<br/>ChromaDB Collection"]
InvestMem["Investment Judge Memory<br/>ChromaDB Collection"]
RiskMem["Risk Manager Memory<br/>ChromaDB Collection"]
end
subgraph Embedding["嵌入層"]
OpenAI["OpenAI<br/>text-embedding-3-small"]
end
subgraph Operations["操作"]
Add["add_situations()<br/>存儲情況與建議"]
Get["get_memories()<br/>語義檢索相似情況"]
Reflect["reflect_and_remember()<br/>基於回報反思"]
end
Operations --> Embedding
Embedding --> MemorySystem
5.2 記憶類實現
class FinancialSituationMemory:
"""金融情況記憶系統"""
def __init__(self, memory_name: str):
self.memory_name = memory_name
self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
self.client = chromadb.Client()
self.collection = self.client.get_or_create_collection(
name=memory_name,
metadata={"hnsw:space": "cosine"} # 餘弦相似度
)
self.offset = 0
def add_situations(
self,
situations_and_advice: List[Tuple[str, str]]
) -> None:
"""
存儲情況和建議
Args:
situations_and_advice: [(situation_text, recommendation_text), ...]
"""
for i, (situation, advice) in enumerate(situations_and_advice):
# 生成嵌入向量
embedding = self.embeddings.embed_query(situation)
# 存儲到 ChromaDB
self.collection.add(
documents=[situation],
metadatas=[{"recommendation": advice}],
embeddings=[embedding],
ids=[str(self.offset + i)]
)
self.offset += len(situations_and_advice)
def get_memories(
self,
current_situation: str,
n_matches: int = 1
) -> List[Dict]:
"""
語義檢索相似情況
Args:
current_situation: 當前情況描述
n_matches: 返回的匹配數量
Returns:
[{"matched_situation": str,
"recommendation": str,
"similarity_score": float}, ...]
"""
# 生成查詢嵌入
query_embedding = self.embeddings.embed_query(current_situation)
# 查詢相似情況
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=n_matches,
include=["metadatas", "documents", "distances"]
)
# 格式化結果
memories = []
for i in range(len(results["documents"][0])):
memories.append({
"matched_situation": results["documents"][0][i],
"recommendation": results["metadatas"][0][i]["recommendation"],
"similarity_score": 1 - results["distances"][0][i] # 轉換為相似度
})
return memories
5.3 反思與學習機制
def reflect_and_remember(
final_state: AgentState,
returns_losses: float,
memories: Dict[str, FinancialSituationMemory]
) -> None:
"""
基於實際回報進行反思和學習
Args:
final_state: 最終狀態
returns_losses: 實際回報率 (正/負)
memories: 各 Agent 的記憶系統
"""
# 構建當前情況描述
current_situation = f"""
Market Report: {final_state['market_report']}
Sentiment: {final_state['sentiment_report']}
News: {final_state['news_report']}
Fundamentals: {final_state['fundamentals_report']}
Decision: {final_state['final_trade_decision']}
Actual Return: {returns_losses}%
"""
# 使用 LLM 生成反思
reflection_prompt = f"""
Analyze this trading decision and its outcome:
{current_situation}
Generate a lesson learned that can help in similar future situations.
Focus on:
1. What signals were correctly/incorrectly interpreted
2. What could have been done differently
3. Key patterns to remember
"""
reflection = llm.invoke(reflection_prompt)
# 存儲到各 Agent 記憶
for agent_name, memory in memories.items():
memory.add_situations([
(current_situation, reflection.content)
])
6. 數據源管理
6.1 供應商路由架構
flowchart TB
subgraph Request["數據請求"]
ToolCall[工具調用]
end
subgraph Router["路由層 (interface.py)"]
Config[數據供應商配置]
Priority[優先級順序]
Fallback[降級機制]
end
subgraph Providers["供應商"]
YF[yfinance<br/>股價/技術指標]
AV[Alpha Vantage<br/>基本面/新聞]
GN[Google News<br/>新聞]
RD[Reddit<br/>社交情感]
Local[Local TradingDB<br/>歷史數據]
end
ToolCall --> Router
Router --> Providers
Config --> Priority
Priority --> Fallback
6.2 供應商配置
DEFAULT_CONFIG = {
# LLM 提供者
"llm_provider": "openai", # openai, anthropic, google, ollama
# 模型選擇
"deep_think_llm": "o4-mini", # 複雜推理
"quick_think_llm": "gpt-4o-mini", # 快速分析
# 數據供應商配置
"data_vendors": {
"core_stock_apis": "yfinance", # 股價數據優先
"technical_indicators": "yfinance", # 技術指標
"fundamental_data": "alpha_vantage", # 基本面
"news_data": "alpha_vantage" # 新聞
},
# 辯論配置
"max_debate_rounds": 1, # Bull ↔ Bear 輪次
"max_risk_discuss_rounds": 1, # 風險分析輪次
"max_recur_limit": 100 # LangGraph 遞歸限制
}
6.3 數據路由實現
# dataflows/interface.py
class DataRouter:
"""數據路由器:根據配置選擇供應商"""
def __init__(self, config: dict):
self.config = config
self.vendors = config.get("data_vendors", {})
def get_stock_data(
self,
symbol: str,
start_date: str,
end_date: str
) -> pd.DataFrame:
"""路由股票數據請求"""
vendor = self.vendors.get("core_stock_apis", "yfinance")
if vendor == "yfinance":
return y_finance.get_YFin_data_online(symbol, start_date, end_date)
elif vendor == "alpha_vantage":
return alpha_vantage.get_stock_data(symbol, start_date, end_date)
elif vendor == "local":
return local.get_stock_data(symbol, start_date, end_date)
else:
raise ValueError(f"Unknown vendor: {vendor}")
def get_indicators(
self,
symbol: str,
indicator_name: str,
curr_date: str,
look_back_days: int
) -> pd.DataFrame:
"""路由技術指標請求"""
vendor = self.vendors.get("technical_indicators", "yfinance")
if vendor == "yfinance":
return stockstats_utils.get_stock_stats_indicators_window(
symbol, indicator_name, curr_date, look_back_days
)
# ... 其他供應商
6.4 可用技術指標
| 指標類別 | 指標名稱 | stockstats 鍵值 |
|---|---|---|
| 移動平均 | 50 日 SMA | close_50_sma |
| 移動平均 | 200 日 SMA | close_200_sma |
| 移動平均 | 10 日 EMA | close_10_ema |
| MACD | MACD 線 | macd |
| MACD | 信號線 | macds |
| MACD | 柱狀圖 | macdh |
| 動量 | RSI (14) | rsi_14 |
| 波動 | 布林上軌 | boll_ub |
| 波動 | 布林中軌 | boll |
| 波動 | 布林下軌 | boll_lb |
| 波動 | ATR | atr |
| 成交量 | VWMA | vwma |
7. 完整執行流程示例
7.1 以 NVDA @ 2024-05-10 為例
sequenceDiagram
participant User
participant Graph as TradingAgentsGraph
participant MA as Market Analyst
participant FA as Fundamentals Analyst
participant NA as News Analyst
participant SA as Social Analyst
participant Bull as Bull Researcher
participant Bear as Bear Researcher
participant RM as Research Manager
participant Trader as Trader
participant Risk as Risk Team
participant RJ as Risk Judge
User->>Graph: propagate("NVDA", "2024-05-10")
Graph->>Graph: create_initial_state()
par 並行分析
Graph->>MA: 技術分析
MA->>MA: get_stock_data()
MA->>MA: get_indicators(SMA, MACD, RSI...)
MA-->>Graph: market_report
and
Graph->>FA: 基本面分析
FA->>FA: get_fundamentals()
FA->>FA: get_balance_sheet()
FA-->>Graph: fundamentals_report
and
Graph->>NA: 新聞分析
NA->>NA: get_news()
NA->>NA: get_global_news()
NA-->>Graph: news_report
and
Graph->>SA: 情感分析
SA->>SA: get_news()
SA-->>Graph: sentiment_report
end
Note over Graph: 4 份報告完成
Graph->>Bull: 開始辯論 (with past_memories)
Bull->>Bull: 構建看多論點
Bull-->>Bear: 發言
loop max_debate_rounds
Bear->>Bear: 反駁 + 看空論點
Bear-->>Bull: 發言
Bull->>Bull: 反駁 + 強化看多
Bull-->>Bear: 發言
end
Bear-->>RM: 辯論結束
RM->>RM: 評估雙方論點
RM-->>Graph: investment_plan
Graph->>Trader: 交易決策
Trader->>Trader: 應用 trader_memory
Trader-->>Graph: "FINAL TRANSACTION PROPOSAL: **BUY**"
Graph->>Risk: 風險辯論
loop max_risk_discuss_rounds
Risk->>Risk: Risky -> Safe -> Neutral
end
Risk-->>RJ: 辯論結束
RJ->>RJ: 評估 + 應用 risk_memory
RJ-->>Graph: final_trade_decision
Graph->>Graph: signal_processing()
Graph-->>User: (final_state, "BUY")
7.2 Python 使用範例
from tradingagents.graph.trading_graph import TradingAgentsGraph
from tradingagents.default_config import DEFAULT_CONFIG
# 1. 配置
config = DEFAULT_CONFIG.copy()
config["deep_think_llm"] = "gpt-4o-mini"
config["quick_think_llm"] = "gpt-4o-mini"
config["max_debate_rounds"] = 1
config["max_risk_discuss_rounds"] = 1
# 2. 初始化
ta = TradingAgentsGraph(debug=True, config=config)
# 3. 執行分析
final_state, decision = ta.propagate("NVDA", "2024-05-10")
print(f"最終決策: {decision}") # BUY / SELL / HOLD
# 4. 查看詳細狀態
print(f"技術分析: {final_state['market_report'][:500]}...")
print(f"投資計劃: {final_state['investment_plan'][:500]}...")
# 5. 學習與反思 (假設實際回報 +5.2%)
ta.reflect_and_remember(returns_losses=5.2)
8. CLI 互動界面
8.1 使用方式
# 安裝
pip install -e .
# 啟動 CLI
python -m cli.main
8.2 CLI 流程
╔══════════════════════════════════════════════════════════════╗
║ TradingAgents CLI ║
╚══════════════════════════════════════════════════════════════╝
? Select stock ticker: NVDA
? Select trade date: 2024-05-10
? Select LLM provider: openai
? Select model: gpt-4o-mini
═══════════════════════════════════════════════════════════════
Analysis Progress
═══════════════════════════════════════════════════════════════
[1/4] Market Analyst: Analyzing technical indicators...
├─ get_stock_data: ✓
├─ get_indicators (SMA, MACD, RSI): ✓
└─ Report generated: ✓
[2/4] Fundamentals Analyst: Analyzing financials...
├─ get_fundamentals: ✓
├─ get_balance_sheet: ✓
└─ Report generated: ✓
[3/4] News Analyst: Analyzing news...
└─ Report generated: ✓
[4/4] Social Analyst: Analyzing sentiment...
└─ Report generated: ✓
═══════════════════════════════════════════════════════════════
Investment Debate
═══════════════════════════════════════════════════════════════
Bull Researcher: NVDA shows strong momentum with RSI at 65...
Bear Researcher: However, valuation at 40x P/E is concerning...
Research Manager: After evaluation, aligning with BULL...
═══════════════════════════════════════════════════════════════
Risk Analysis
═══════════════════════════════════════════════════════════════
Risky Analyst: Opportunity cost of not entering is high...
Safe Analyst: Suggest smaller position with stop-loss...
Neutral Analyst: Balanced approach: 50% position...
Risk Judge: Final recommendation: BUY with risk controls...
═══════════════════════════════════════════════════════════════
FINAL DECISION: BUY
═══════════════════════════════════════════════════════════════
9. 系統優勢與創新
9.1 架構優勢
| 特性 | 傳統方法 | TradingAgents |
|---|---|---|
| 決策視角 | 單一模型 | 10+ 專業 Agent |
| 風險評估 | 單維度 | 三維度 (Risky/Safe/Neutral) |
| 學習機制 | 無 | 向量記憶 + 反思 |
| 偏見處理 | 容易過度樂觀/悲觀 | 辯論式平衡 |
| 可解釋性 | 黑盒 | 完整決策鏈 |
9.2 技術創新
-
辯論式決策
- Bull vs Bear 對抗,避免確認偏誤
- 仲裁者綜合評估,避免極端決策
-
向量記憶系統
- 語義相似度檢索過去情況
- 基於實際回報進行反思學習
- 持續改進決策質量
-
多層級風險管理
- 三種風險視角同時評估
- 風險仲裁者做最終平衡
-
靈活的數據源管理
- 供應商優先級和降級機制
- 支援多種數據來源組合
9.3 適用場景
- 量化研究:回測不同 Agent 配置的效果
- 投資輔助:獲取多角度分析報告
- 教育目的:學習多智能體系統設計
- 框架擴展:基於此框架開發自定義 Agent
10. 擴展指南
10.1 新增 Agent
# agents/my_custom_agent.py
from langchain_core.messages import HumanMessage
from langgraph.prebuilt import create_react_agent
def create_my_agent(llm, tools):
"""創建自定義 Agent"""
system_prompt = """
You are a custom analyst with specific expertise in...
Your responsibilities:
1. ...
2. ...
Output format:
...
"""
agent = create_react_agent(
llm,
tools=tools,
messages_modifier=system_prompt
)
return agent
10.2 新增數據源
# dataflows/my_data_source.py
def get_custom_data(symbol: str, date: str) -> dict:
"""從自定義來源獲取數據"""
# 實現數據獲取邏輯
pass
# 在 interface.py 中註冊
def get_stock_data(self, symbol, start_date, end_date):
vendor = self.vendors.get("core_stock_apis", "yfinance")
if vendor == "my_custom_source":
return my_data_source.get_custom_data(symbol, start_date)
# ...
10.3 調整辯論輪次
config = DEFAULT_CONFIG.copy()
# 增加辯論深度
config["max_debate_rounds"] = 3 # Bull ↔ Bear 3 輪
config["max_risk_discuss_rounds"] = 2 # 風險分析 2 輪
ta = TradingAgentsGraph(config=config)
11. 性能與限制
11.1 性能特點
| 指標 | 數值 |
|---|---|
| 分析師並行度 | 4 (並行執行) |
| 最大遞歸深度 | 100 步 |
| 記憶檢索延遲 | < 100ms (本地 ChromaDB) |
| 典型執行時間 | 2-5 分鐘 (取決於 LLM) |
11.2 已知限制
-
API 速率限制
- Alpha Vantage 免費版: 5 calls/min
- 建議使用 yfinance 或付費 API
-
Token 消耗
- 長報告可能導致 token 超限
- 消息清理機制可緩解
-
LLM 依賴
- 決策質量取決於 LLM 能力
- 建議使用 GPT-4 級別模型
12. 總結
TradingAgents 代表了多智能體金融決策系統的前沿實踐:
| 維度 | 實現 |
|---|---|
| 架構 | 10+ Agent 模擬真實交易公司 |
| 工作流 | 4 階段 LangGraph 流水線 |
| 決策 | 辯論式多角度評估 |
| 記憶 | 向量化語義記憶系統 |
| 數據 | 多供應商靈活架構 |
| LLM | 支援 OpenAI/Anthropic/Google |
| 可擴展 | 模塊化設計易於定制 |
關鍵技術決策:
- LangGraph 作為工作流引擎,提供狀態管理和條件路由
- ChromaDB 本地向量存儲,保護數據隱私
- 辯論機制 實現多視角決策,避免單一偏見
- 反思學習 從歷史決策中持續改進