125 lines
5.5 KiB
Python
125 lines
5.5 KiB
Python
# -*- coding: utf-8 -*-
|
||
import time
|
||
import json
|
||
|
||
|
||
def create_neutral_debator(llm):
|
||
"""
|
||
建立一個中立的風險辯論員節點。
|
||
|
||
這個節點在風險評估辯論中扮演中立派的角色。
|
||
其目標是提供一個平衡的視角,權衡交易員決策的潛在利益和風險。
|
||
它會挑戰過於樂觀或過於謹慎的觀點,並倡導一個溫和、可持續的策略。
|
||
|
||
Args:
|
||
llm: 用於生成回應的語言模型。
|
||
|
||
Returns:
|
||
function: 一個代表中立辯論員節點的函式,可在 langgraph 中使用。
|
||
"""
|
||
|
||
def neutral_node(state) -> dict:
|
||
"""
|
||
中立辯論員節點的執行函式。
|
||
|
||
Args:
|
||
state (dict): 當前的圖狀態。
|
||
|
||
Returns:
|
||
dict: 更新後的狀態,包含新的風險辯論狀態。
|
||
"""
|
||
# 從狀態中獲取風險辯論的相關資訊
|
||
risk_debate_state = state["risk_debate_state"]
|
||
history = risk_debate_state.get("history", "")
|
||
neutral_history = risk_debate_state.get("neutral_history", "")
|
||
|
||
# 獲取其他辯論者的最新回應
|
||
current_risky_response = risk_debate_state.get("current_risky_response", "")
|
||
current_safe_response = risk_debate_state.get("current_safe_response", "")
|
||
|
||
# 從狀態中獲取各類分析報告
|
||
market_research_report = state["market_report"]
|
||
sentiment_report = state["sentiment_report"]
|
||
news_report = state["news_report"]
|
||
fundamentals_report = state["fundamentals_report"]
|
||
|
||
# 獲取交易員的決策
|
||
trader_decision = state["trader_investment_plan"]
|
||
|
||
# 定義文本截斷函數以避免超過 token 限制
|
||
def truncate_text(text, max_chars):
|
||
"""截斷文本到指定字符數"""
|
||
if len(text) <= max_chars:
|
||
return text
|
||
return text[:max_chars] + "\n...(內容已截斷)"
|
||
|
||
# 截斷各類輸入以控制 token 使用量
|
||
# 模型限制: 8192 tokens,目標: < 3500 字符
|
||
market_research_report = truncate_text(market_research_report, 500)
|
||
sentiment_report = truncate_text(sentiment_report, 500)
|
||
news_report = truncate_text(news_report, 600)
|
||
fundamentals_report = truncate_text(fundamentals_report, 600)
|
||
trader_decision = truncate_text(trader_decision, 800)
|
||
history = truncate_text(history, 400)
|
||
current_risky_response = truncate_text(current_risky_response, 300)
|
||
current_safe_response = truncate_text(current_safe_response, 300)
|
||
|
||
# 建立提示 (prompt)
|
||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||
|
||
【專業身份】
|
||
您是一位平衡策略投資專家與風險中性對沖基金經理:
|
||
• CFA + 量化對沖策略認證
|
||
• 16年市場中性與平衡策略經驗
|
||
• 專注於風險調整後報酬最佳化
|
||
• 擅長識別市場定價錯誤與套利機會
|
||
• 風險報酬平衡投資哲學
|
||
|
||
【投資哲學】
|
||
• **平衡為上**:在機會與風險間尋求最佳平衡點
|
||
• **風險調整報酬**:關注Sharpe Ratio而非絕對報酬
|
||
• **靈活應變**:根據風險報酬比動態調整部位
|
||
• **理性客觀**:不受情緒影響,基於數據決策
|
||
|
||
【論證重點】
|
||
1. 風險報酬平衡:客觀評估上檔vs下檔的不對稱性
|
||
2. 條件式建議:在特定條件下(如對沖、部位控制)的投資可行性
|
||
3. 情境分析:不同市場環境下的表現預期
|
||
4. 平衡觀點:同時承認機會與風險的合理之處
|
||
5. 務實建議:適度部位、分批進場、對沖策略
|
||
|
||
交易員計畫:
|
||
{trader_decision}
|
||
|
||
市場研究報告:{market_research_report}
|
||
社群媒體情緒報告:{sentiment_report}
|
||
最新世界事務報告:{news_report}
|
||
公司基本面報告:{fundamentals_report}
|
||
這是當前的對話歷史:{history} 這是激進分析師的最新回應:{current_risky_response} 這是安全分析師的最新回應:{current_safe_response}。如果其他觀點沒有回應,請不要憑空捏造,只需陳述您的觀點。
|
||
|
||
通過批判性地分析雙方,積極參與,指出激進和保守論點中的弱點,以倡導一個更平衡的方法。挑戰他們的每一個觀點,以說明為何一個溫和的風險策略可能提供兩全其美的方案,既提供增長潛力,又防範極端波動。專注於辯論,而不僅僅是呈現數據,旨在表明一個平衡的觀點可以帶來最可靠的結果。請以對話方式輸出,就像您在說話一樣,不帶任何特殊格式。"""
|
||
|
||
# 呼叫 LLM 生成回應
|
||
response = llm.invoke(prompt)
|
||
|
||
# 格式化論點
|
||
argument = f"中立分析師:{response.content}"
|
||
|
||
# 更新風險辯論狀態
|
||
new_risk_debate_state = {
|
||
"history": history + "\n" + argument,
|
||
"risky_history": risk_debate_state.get("risky_history", ""),
|
||
"safe_history": risk_debate_state.get("safe_history", ""),
|
||
"neutral_history": neutral_history + "\n" + argument,
|
||
"latest_speaker": "Neutral", # 記錄最新的發言者
|
||
"current_risky_response": risk_debate_state.get(
|
||
"current_risky_response", ""
|
||
),
|
||
"current_safe_response": risk_debate_state.get("current_safe_response", ""),
|
||
"current_neutral_response": argument,
|
||
"count": risk_debate_state["count"] + 1,
|
||
}
|
||
|
||
return {"risk_debate_state": new_risk_debate_state}
|
||
|
||
return neutral_node |