diff --git a/run_analysis.py b/run_analysis.py new file mode 100644 index 00000000..ffed320d --- /dev/null +++ b/run_analysis.py @@ -0,0 +1,99 @@ +""" +TradingAgents 分析脚本 +用途:对持仓标的(NVDA / VOO)进行多 Agent 分析 +用法: + python run_analysis.py NVDA # 分析 NVDA,使用今日日期 + python run_analysis.py VOO # 分析 VOO + python run_analysis.py NVDA 2025-03-01 # 分析指定日期 +""" + +import sys +import os +import time +from datetime import date +from dotenv import load_dotenv + +load_dotenv() + +from tradingagents.graph.trading_graph import TradingAgentsGraph +from tradingagents.default_config import DEFAULT_CONFIG + +# ── 配置 ──────────────────────────────────────────────────────────────────── +config = DEFAULT_CONFIG.copy() +config["llm_provider"] = "google" +config["deep_think_llm"] = "gemini-2.5-flash" +config["quick_think_llm"] = "gemini-2.5-flash" +config["max_debate_rounds"] = 1 # 减少辩论轮次,降低单次请求量 +config["max_risk_discuss_rounds"] = 1 +config["data_vendors"] = { + "core_stock_apis": "yfinance", + "technical_indicators": "yfinance", + "fundamental_data": "yfinance", + "news_data": "yfinance", +} + +# ── 入参解析 ───────────────────────────────────────────────────────────────── +ticker = sys.argv[1].upper() if len(sys.argv) > 1 else "NVDA" +analysis_date = sys.argv[2] if len(sys.argv) > 2 else str(date.today()) + +print(f"\n{'='*60}") +print(f"🤖 TradingAgents 多 Agent 分析") +print(f" 标的:{ticker}") +print(f" 日期:{analysis_date}") +print(f" 模型:Gemini 2.5 Flash") +print(f"{'='*60}\n") + +# ── 执行分析(带 retry)──────────────────────────────────────────────────────── +MAX_RETRIES = 3 +for attempt in range(1, MAX_RETRIES + 1): + try: + print(f"[尝试 {attempt}/{MAX_RETRIES}]") + ta = TradingAgentsGraph( + selected_analysts=["market", "social", "news", "fundamentals"], + debug=False, + config=config, + ) + final_state, decision = ta.propagate(ticker, analysis_date) + break # 成功则退出重试 + except Exception as e: + print(f"⚠️ 第 {attempt} 次失败: {type(e).__name__}: {str(e)[:120]}") + if attempt < MAX_RETRIES: + wait = 10 * attempt + print(f" 等待 {wait}s 后重试...") + time.sleep(wait) + else: + print("❌ 全部重试失败,退出。") + sys.exit(1) + +# ── 输出结果 ────────────────────────────────────────────────────────────────── +print(f"\n{'='*60}") +print(f"📊 {ticker} 最终决策({analysis_date}):{decision}") +print(f"{'='*60}\n") + +# 保存完整报告 +output_dir = os.path.join(os.path.dirname(__file__), "results") +os.makedirs(output_dir, exist_ok=True) +output_file = os.path.join(output_dir, f"{ticker}_{analysis_date}.txt") + +with open(output_file, "w", encoding="utf-8") as f: + f.write(f"标的:{ticker}\n日期:{analysis_date}\n最终决策:{decision}\n\n") + f.write("="*60 + "\n") + + f.write("【交易员决策报告】\n") + f.write(str(final_state.get("trader_investment_plan", "N/A"))) + f.write("\n\n" + "="*60 + "\n") + + debate = final_state.get("investment_debate_state", {}) + f.write("【多空辩论结论】\n") + f.write(str(debate.get("judge_decision", "N/A"))) + f.write("\n\n" + "="*60 + "\n") + + risk = final_state.get("risk_debate_state", {}) + f.write("【风控审核结论】\n") + f.write(str(risk.get("judge_decision", "N/A"))) + f.write("\n\n" + "="*60 + "\n") + + f.write("【最终决策原文】\n") + f.write(str(final_state.get("final_trade_decision", "N/A"))) + +print(f"✅ 完整报告已保存:{output_file}")