TradingAgents/tradingagents/agents/researchers/bear_researcher.py

128 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
from langchain_core.messages import AIMessage
import time
import json
from tradingagents.agents.utils.output_filter import fix_common_llm_errors, validate_and_warn
def create_bear_researcher(llm, memory):
"""
建立一個看跌研究員節點。
這個節點在辯論中扮演看跌分析師的角色,提出反對投資某支股票的論點。
它會利用市場研究、情緒分析、新聞和基本面報告,並結合過去的經驗(記憶),
來強調風險、挑戰和負面指標,並反駁看漲方的觀點。
Args:
llm: 用於生成回應的語言模型。
memory: 儲存過去情況和反思的記憶體物件。
Returns:
function: 一個代表看跌研究員節點的函式,可在 langgraph 中使用。
"""
def bear_node(state) -> dict:
"""
看跌研究員節點的執行函式。
Args:
state (dict): 當前的圖狀態。
Returns:
dict: 更新後的狀態,包含新的投資辯論狀態。
"""
# 從狀態中獲取投資辯論的相關資訊
investment_debate_state = state["investment_debate_state"]
history = investment_debate_state.get("history", "")
bear_history = investment_debate_state.get("bear_history", "")
current_response = investment_debate_state.get("current_response", "")
# 從狀態中獲取各類分析報告
market_research_report = state["market_report"]
sentiment_report = state["sentiment_report"]
news_report = state["news_report"]
fundamentals_report = state["fundamentals_report"]
# 整合當前情況 - 移除截斷邏輯以保留完整報告內容
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}"
# 從記憶體中獲取過去相似情況的經驗
past_memories = memory.get_memories(curr_situation, n_matches=2)
# 將過去的經驗格式化為字串
past_memory_str = ""
for i, rec in enumerate(past_memories, 1):
recommendation = rec["recommendation"]
past_memory_str += recommendation + "\n\n"
# 建立提示 (prompt) - 保留完整歷史以確保context完整性
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
**嚴格禁止:請勿在回覆中使用任何 emoji 表情符號(如 ✅ ❌ 📊 📈 🚀 等)。**
**請只使用純文字、數字、標點符號和必要的 Unicode 符號(如 ↑ ↓ ★ ●等)。**
【專業身份】
您是看跌方研究員,負責提出賣出論據,強調投資風險與下跌壓力。**您必須採取激進做空立場,不惜一切代價找出所有看跌風險因子,並強力反駁看漲論點。**
【分析重點】
1. **成長疑慮**:檢視營收成長減速、市場飽和或競爭加劇跡象,放大成長隱憂
2. **競爭劣勢**:評估護城河侵蝕、市佔率流失或定價能力弱化,強調競爭威脅
3. **財務問題**:識別現金流惡化、債務風險或獲利品質下降,揭露財務危機
4. **負面催化**:指出可能觸發股價下跌的事件或結構性問題,放大利空影響
5. **反駁看漲****強力反駁看漲方論點,直指其盲目樂觀,揭露其論據的致命缺陷**
【可用資源】
- 市場分析:{market_research_report}
- 社群情緒:{sentiment_report}
- 新聞:{news_report}
- 基本面:{fundamentals_report}
- 辯論歷史:{history}
- 看漲論點:{current_response}
- 過往經驗:{past_memory_str}
【輸出要求】
**字數要求****800-1500字**
**嚴格遵守字數限制少於800字或超過1500字的報告將被退回**
**內容結構**
1. 核心警示150字以上清晰且強勢地陳述看跌理由展現堅定立場
2. 風險論證450-500字用詳實數據支撐風險分析層層揭露隱患
3. 反駁看漲100字以上**激進地反駁看漲觀點,直指對方論據的盲目樂觀與邏輯漏洞**
4. 投資建議100字以上明確且謹慎的操作建議建議減倉或觀望
**撰寫原則**
- **激進做空**:採取極度謹慎立場,強調所有風險因素
- **強力反駁**:對看漲論點窮追猛打,揭露其盲目樂觀與忽略的風險
- 論據扎實,以數據與事實為基礎,但解讀偏向悲觀
- 直接指出對方論點的漏洞,不留情面
- 強調風險遠大於機會
**結尾提示**
請在報告最後加上以下結尾:
「---
🐻 **本報告為看跌方研究分析,立場偏向謹慎保守。建議搭配看漲方觀點與市場情緒綜合研判。投資有風險,請謹慎評估。**」
請提供有說服力且激進的看跌分析報告。
"""
# 呼叫 LLM 生成回應
response = llm.invoke(prompt)
# CRITICAL FIX: Apply output filtering to fix common LLM errors
response.content = fix_common_llm_errors(response.content)
validate_and_warn(response.content, "Bear_Researcher")
# 格式化論點
argument = f"看跌分析師:{response.content}"
# 更新投資辯論狀態
new_investment_debate_state = {
"history": history + "\n" + argument,
"bear_history": bear_history + "\n" + argument,
"bull_history": investment_debate_state.get("bull_history", ""),
"current_response": argument,
"count": investment_debate_state["count"] + 1,
}
return {"investment_debate_state": new_investment_debate_state}
return bear_node