This commit is contained in:
MarkLo 2025-11-25 17:03:17 +08:00
parent 15babc2bea
commit 8d679007bf
40 changed files with 551 additions and 1021 deletions

View File

@ -1,10 +1,10 @@
# TradingAgents - 多代理交易分析系統 # TradingAgentsX - 多代理交易分析系統
<div align="center"> <div align="center">
**基於 LangGraph 的智能股票交易分析平台,結合多個 AI 代理進行協作決策** **基於 LangGraph 的智能股票交易分析平台,結合多個 AI 代理進行協作決策**
[![GitHub](https://img.shields.io/badge/GitHub-MarkLo127/TradingAgents-blue?logo=github)](https://github.com/MarkLo127/TradingAgents) [![GitHub](https://img.shields.io/badge/GitHub-MarkLo127/TradingAgentsX-blue?logo=github)](https://github.com/MarkLo127/TradingAgentsX)
[![Python](https://img.shields.io/badge/Python-3.10+-blue?logo=python)](https://www.python.org/) [![Python](https://img.shields.io/badge/Python-3.10+-blue?logo=python)](https://www.python.org/)
[![Next.js](https://img.shields.io/badge/Next.js-16-black?logo=next.js)](https://nextjs.org/) [![Next.js](https://img.shields.io/badge/Next.js-16-black?logo=next.js)](https://nextjs.org/)
[![FastAPI](https://img.shields.io/badge/FastAPI-Latest-009688?logo=fastapi)](https://fastapi.tiangolo.com/) [![FastAPI](https://img.shields.io/badge/FastAPI-Latest-009688?logo=fastapi)](https://fastapi.tiangolo.com/)
@ -16,9 +16,9 @@
## 📖 簡介 ## 📖 簡介
**TradingAgents** 是一個先進的多代理 AI 交易分析系統,模擬真實世界的交易公司運作模式。透過 LangGraph 編排多個專業化的 AI 代理(分析師、研究員、交易員、風險管理者),系統能夠從不同角度分析股票市場,並通過結構化的辯論與協作流程產生高質量的交易決策。 **TradingAgentsX** 是一個先進的多代理 AI 交易分析系統,模擬真實世界的交易公司運作模式。透過 LangGraph 編排多個專業化的 AI 代理(分析師、研究員、交易員、風險管理者),系統能夠從不同角度分析股票市場,並通過結構化的辯論與協作流程產生高質量的交易決策。
> 💡 **致敬原作**: 本專案基於 [TauricResearch/TradingAgents](https://github.com/TauricResearch/TradingAgents) 進行改進和擴展,加入了完整的 Web 前端介面、RESTful API、Docker 部署支援等功能。感謝原作者的卓越工作和開源貢獻! > 💡 **致敬原作**: 本專案基於 [TauricResearch/TradingAgentsX](https://github.com/TauricResearch/TradingAgentsX) 進行改進和擴展,加入了完整的 Web 前端介面、RESTful API、Docker 部署支援等功能。感謝原作者的卓越工作和開源貢獻!
### 🎯 核心特色 ### 🎯 核心特色
@ -37,7 +37,7 @@
## 🤖 LLM 模型支援 ## 🤖 LLM 模型支援
TradingAgents 支援業界領先的多家 LLM 提供商,並為每個模型配置**獨立的 API Key 和 Base URL**,實現最大靈活性。 TradingAgentsX 支援業界領先的多家 LLM 提供商,並為每個模型配置**獨立的 API Key 和 Base URL**,實現最大靈活性。
### 📋 支援的 LLM 提供商矩陣 ### 📋 支援的 LLM 提供商矩陣
@ -96,12 +96,12 @@ TradingAgents 支援業界領先的多家 LLM 提供商,並為每個模型配
## 🏗️ 系統架構 ## 🏗️ 系統架構
TradingAgents 採用前後端分離架構,後端使用 FastAPI 提供 RESTful API前端使用 Next.js 打造現代化的使用者介面。 TradingAgentsX 採用前後端分離架構,後端使用 FastAPI 提供 RESTful API前端使用 Next.js 打造現代化的使用者介面。
### 📂 專案結構概覽 ### 📂 專案結構概覽
``` ```
TradingAgents/ TradingAgentsX/
├── backend/ # FastAPI 後端服務 ├── backend/ # FastAPI 後端服務
│ ├── __main__.py # 後端應用入口 │ ├── __main__.py # 後端應用入口
│ ├── requirements.txt # Python 依賴列表 │ ├── requirements.txt # Python 依賴列表
@ -116,7 +116,7 @@ TradingAgents/
│ ├── models/ # 資料模型 │ ├── models/ # 資料模型
│ │ └── schemas.py # Pydantic 資料結構 │ │ └── schemas.py # Pydantic 資料結構
│ └── services/ # 業務邏輯層 │ └── services/ # 業務邏輯層
│ ├── trading_service.py # TradingAgents 核心整合 │ ├── trading_service.py # TradingAgentsX 核心整合
│ └── task_manager.py # 異步任務管理 │ └── task_manager.py # 異步任務管理
├── frontend/ # Next.js 前端應用 ├── frontend/ # Next.js 前端應用
@ -225,8 +225,8 @@ TradingAgents/
#### 1⃣ 克隆專案 #### 1⃣ 克隆專案
```bash ```bash
git clone https://github.com/MarkLo127/TradingAgents.git git clone https://github.com/MarkLo127/TradingAgentsX.git
cd TradingAgents cd TradingAgentsX
``` ```
#### 2⃣ 後端設置 #### 2⃣ 後端設置
@ -252,7 +252,7 @@ tradingagents\Scripts\activate # Windows
##### 2.2 安裝 Python 依賴 ##### 2.2 安裝 Python 依賴
```bash ```bash
# 安裝 TradingAgents 核心套件 # 安裝 TradingAgentsX 核心套件
pip install -e . pip install -e .
# 安裝後端 API 依賴 # 安裝後端 API 依賴
@ -535,7 +535,7 @@ docker compose down -v
### API 使用範例 ### API 使用範例
如果您想要透過 API 整合 TradingAgents可以參考以下範例 如果您想要透過 API 整合 TradingAgentsX,可以參考以下範例:
#### 健康檢查 #### 健康檢查
@ -579,7 +579,7 @@ curl "http://localhost:8000/api/price-data/NVDA?start_date=2024-01-01&end_date=2
### 多代理協作系統 ### 多代理協作系統
TradingAgents 模擬真實交易公司的組織架構,每個代理都有其專業職責: TradingAgentsX 模擬真實交易公司的組織架構,每個代理都有其專業職責:
| 代理角色 | 主要職責 | 輸出內容 | | 代理角色 | 主要職責 | 輸出內容 |
| ---------------- | -------- | ----------------------------------------------------- | | ---------------- | -------- | ----------------------------------------------------- |
@ -673,7 +673,7 @@ TradingAgents 模擬真實交易公司的組織架構,每個代理都有其專
### 首頁 - 系統介紹 ### 首頁 - 系統介紹
展示 TradingAgents 的核心功能與多代理協作工作流程 展示 TradingAgentsX 的核心功能與多代理協作工作流程
![首頁](web_screenshot/1.png) ![首頁](web_screenshot/1.png)
@ -814,7 +814,7 @@ TradingAgents 模擬真實交易公司的組織架構,每個代理都有其專
### 特別感謝 ### 特別感謝
本專案基於 [TauricResearch/TradingAgents](https://github.com/TauricResearch/TradingAgents) 的原始專案進行改進和擴展。衷心感謝原作者創建了如此優秀的多代理交易分析框架,為我們提供了堅實的基礎。 本專案基於 [TauricResearch/TradingAgentsX](https://github.com/TauricResearch/TradingAgentsX) 的原始專案進行改進和擴展。衷心感謝原作者創建了如此優秀的多代理交易分析框架,為我們提供了堅實的基礎。
### 使用的開源專案 ### 使用的開源專案

View File

@ -20,7 +20,7 @@ def main():
port = int(os.getenv("BACKEND_PORT", "8000")) port = int(os.getenv("BACKEND_PORT", "8000"))
reload = os.getenv("BACKEND_RELOAD", "true").lower() == "true" reload = os.getenv("BACKEND_RELOAD", "true").lower() == "true"
print(f"🚀 Starting TradingAgents Backend Server...") print(f"🚀 Starting TradingAgentsX Backend Server...")
print(f"📍 Host: {host}") print(f"📍 Host: {host}")
print(f"🔌 Port: {port}") print(f"🔌 Port: {port}")
print(f"🔄 Reload: {reload}") print(f"🔄 Reload: {reload}")

View File

@ -1,5 +1,5 @@
""" """
API route definitions for TradingAgents Backend API route definitions for TradingAgentsX Backend
""" """
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from datetime import datetime from datetime import datetime
@ -24,7 +24,7 @@ from backend.app.core.config import settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Create API router # Create API router
router = APIRouter(prefix="/api", tags=["TradingAgents"]) router = APIRouter(prefix="/api", tags=["TradingAgentsX"])
@router.get("/health", response_model=HealthResponse) @router.get("/health", response_model=HealthResponse)

View File

@ -1,5 +1,5 @@
""" """
Configuration management for TradingAgents Backend API Configuration management for TradingAgentsX Backend API
""" """
from pydantic_settings import BaseSettings from pydantic_settings import BaseSettings
from typing import Optional from typing import Optional
@ -11,7 +11,7 @@ class Settings(BaseSettings):
"""Application settings loaded from environment variables""" """Application settings loaded from environment variables"""
# Application settings # Application settings
app_name: str = "TradingAgents API" app_name: str = "TradingAgentsX API"
app_version: str = "1.0.0" app_version: str = "1.0.0"
debug: bool = Field(default=False) debug: bool = Field(default=False)
results_dir: str = Field(default="./results") results_dir: str = Field(default="./results")
@ -29,7 +29,7 @@ class Settings(BaseSettings):
"https://*.railway.app", # Railway deployments "https://*.railway.app", # Railway deployments
] ]
# TradingAgents Configuration # TradingAgentsX Configuration
results_dir: str = "./results" results_dir: str = "./results"
max_debate_rounds: int = 1 max_debate_rounds: int = 1
max_risk_discuss_rounds: int = 1 max_risk_discuss_rounds: int = 1

View File

@ -1,5 +1,5 @@
""" """
FastAPI application entry point for TradingAgents Backend FastAPI application entry point for TradingAgentsX Backend
""" """
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
@ -38,7 +38,7 @@ app.include_router(router)
async def root(): async def root():
"""Root endpoint""" """Root endpoint"""
return { return {
"message": "Welcome to TradingAgents API", "message": "Welcome to TradingAgentsX API",
"version": settings.app_version, "version": settings.app_version,
"docs": "/docs", "docs": "/docs",
"health": "/api/health", "health": "/api/health",

View File

@ -1,5 +1,5 @@
""" """
TradingAgents service integration TradingAgentsX service integration
""" """
import sys import sys
import os import os
@ -10,7 +10,7 @@ import logging
# Add parent directory to path to import tradingagents # Add parent directory to path to import tradingagents
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
from tradingagents.graph.trading_graph import TradingAgentsGraph from tradingagents.graph.trading_graph import TradingAgentsXGraph
from tradingagents.default_config import DEFAULT_CONFIG from tradingagents.default_config import DEFAULT_CONFIG
from backend.app.core.config import settings from backend.app.core.config import settings
@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
class TradingService: class TradingService:
"""Service class for interacting with TradingAgents""" """Service class for interacting with TradingAgentsX"""
def __init__(self): def __init__(self):
self.default_config = DEFAULT_CONFIG.copy() self.default_config = DEFAULT_CONFIG.copy()
@ -29,7 +29,7 @@ class TradingService:
deep_think_llm: str = "gpt-5-mini-2025-08-07", deep_think_llm: str = "gpt-5-mini-2025-08-07",
quick_think_llm: str = "gpt-5-mini-2025-08-07", quick_think_llm: str = "gpt-5-mini-2025-08-07",
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""Create configuration for TradingAgents""" """Create configuration for TradingAgentsX"""
config = self.default_config.copy() config = self.default_config.copy()
config["max_debate_rounds"] = research_depth config["max_debate_rounds"] = research_depth
config["max_risk_discuss_rounds"] = research_depth config["max_risk_discuss_rounds"] = research_depth
@ -91,7 +91,7 @@ class TradingService:
os.environ["ALPHA_VANTAGE_API_KEY"] = alpha_vantage_api_key os.environ["ALPHA_VANTAGE_API_KEY"] = alpha_vantage_api_key
# Create configuration # Create configuration
logger.info(f"Initializing TradingAgents for {ticker} on {analysis_date}") logger.info(f"Initializing TradingAgentsX for {ticker} on {analysis_date}")
config = self.create_config(research_depth, deep_think_llm, quick_think_llm) config = self.create_config(research_depth, deep_think_llm, quick_think_llm)
# Normalize base URLs (ensure lowercase paths, common issue with custom endpoints) # Normalize base URLs (ensure lowercase paths, common issue with custom endpoints)
@ -122,8 +122,8 @@ class TradingService:
config["embedding_base_url"] = normalize_base_url(embedding_base_url) config["embedding_base_url"] = normalize_base_url(embedding_base_url)
config["embedding_api_key"] = embedding_api_key if embedding_api_key else openai_api_key config["embedding_api_key"] = embedding_api_key if embedding_api_key else openai_api_key
# Initialize TradingAgents graph # Initialize TradingAgentsX graph
graph = TradingAgentsGraph(analysts, config=config, debug=True) graph = TradingAgentsXGraph(analysts, config=config, debug=True)
# Run analysis # Run analysis
logger.info(f"Running analysis for {ticker}") logger.info(f"Running analysis for {ticker}")

View File

@ -1,4 +1,4 @@
# Backend requirements for FastAPI TradingAgents API # Backend requirements for FastAPI TradingAgentsX API
# Core Framework # Core Framework
fastapi>=0.104.0 fastapi>=0.104.0
@ -12,7 +12,7 @@ python-multipart==0.0.6
# Environment and configuration # Environment and configuration
python-dotenv==1.0.0 python-dotenv==1.0.0
# Existing TradingAgents dependencies # Existing TradingAgentsX dependencies
typing-extensions typing-extensions
langchain-openai langchain-openai
langchain-experimental langchain-experimental
@ -41,3 +41,6 @@ tenacity>=8.2.0
# PDF and document generation # PDF and document generation
reportlab>=4.0.0 reportlab>=4.0.0
markdown>=3.5.0 markdown>=3.5.0
# Toon format for token optimization
git+https://github.com/toon-format/toon-python.git

View File

@ -25,7 +25,7 @@ from rich.align import Align
from rich.rule import Rule from rich.rule import Rule
# 匯入專案內的模組 # 匯入專案內的模組
from tradingagents.graph.trading_graph import TradingAgentsGraph from tradingagents.graph.trading_graph import TradingAgentsXGraph
from tradingagents.default_config import DEFAULT_CONFIG from tradingagents.default_config import DEFAULT_CONFIG
from cli.models import AnalystType from cli.models import AnalystType
from cli.utils import * from cli.utils import *
@ -35,8 +35,8 @@ console = Console()
# 建立 Typer 應用程式 # 建立 Typer 應用程式
app = typer.Typer( app = typer.Typer(
name="TradingAgents", name="TradingAgentsX",
help="TradingAgents CLI多代理 LLM 金融交易框架", help="TradingAgentsX CLI多代理 LLM 金融交易框架",
add_completion=True, # 啟用 shell 自動補全 add_completion=True, # 啟用 shell 自動補全
) )
@ -212,9 +212,9 @@ def update_display(layout, spinner_text=None):
# 包含歡迎訊息的頁首 # 包含歡迎訊息的頁首
layout["header"].update( layout["header"].update(
Panel( Panel(
"[bold green]歡迎使用 TradingAgents CLI[/bold green]\n" "[bold green]歡迎使用 TradingAgentsX CLI[/bold green]\n"
"[dim]© [Tauric Research](https://github.com/TauricResearch)[/dim]", "[dim]© [Tauric Research](https://github.com/TauricResearch)[/dim]",
title="歡迎使用 TradingAgents", title="歡迎使用 TradingAgentsX",
border_style="green", border_style="green",
padding=(1, 2), padding=(1, 2),
expand=True, expand=True,
@ -421,7 +421,7 @@ def get_user_selections():
# 建立歡迎框內容 # 建立歡迎框內容
welcome_content = f"{welcome_ascii}\n" welcome_content = f"{welcome_ascii}\n"
welcome_content += "[bold green]TradingAgents:多代理 LLM 金融交易框架 - CLI[/bold green]\n\n" welcome_content += "[bold green]TradingAgentsX:多代理 LLM 金融交易框架 - CLI[/bold green]\n\n"
welcome_content += "[bold]工作流程步驟:[/bold]\n" welcome_content += "[bold]工作流程步驟:[/bold]\n"
welcome_content += "I. 分析師團隊 → II. 研究團隊 → III. 交易員 → IV. 風險管理 → V. 投資組合管理\n\n" welcome_content += "I. 分析師團隊 → II. 研究團隊 → III. 交易員 → IV. 風險管理 → V. 投資組合管理\n\n"
welcome_content += ( welcome_content += (
@ -433,7 +433,7 @@ def get_user_selections():
welcome_content, welcome_content,
border_style="green", border_style="green",
padding=(1, 2), padding=(1, 2),
title="歡迎使用 TradingAgents", title="歡迎使用 TradingAgentsX",
subtitle="多代理 LLM 金融交易框架", subtitle="多代理 LLM 金融交易框架",
) )
console.print(Align.center(welcome_box)) console.print(Align.center(welcome_box))
@ -822,7 +822,7 @@ def run_analysis():
os.environ["ALPHA_VANTAGE_API_KEY"] = selections["alpha_vantage_api_key"] os.environ["ALPHA_VANTAGE_API_KEY"] = selections["alpha_vantage_api_key"]
# 初始化圖 # 初始化圖
graph = TradingAgentsGraph( graph = TradingAgentsXGraph(
[analyst.value for analyst in selections["analysts"]], config=config, debug=True [analyst.value for analyst in selections["analysts"]], config=config, debug=True
) )

View File

@ -9,7 +9,7 @@ import { ThemeProvider } from "@/components/theme/ThemeProvider";
const inter = Inter({ subsets: ["latin"] }); const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = { export const metadata: Metadata = {
title: "TradingAgents - 多代理 LLM 金融交易", title: "TradingAgentsX - 多代理 LLM 金融交易",
description: "由 AI 驅動的多代理 LLM 金融交易框架", description: "由 AI 驅動的多代理 LLM 金融交易框架",
}; };
@ -25,9 +25,7 @@ export default function RootLayout({
<AnalysisProvider> <AnalysisProvider>
<div className="flex flex-col min-h-screen"> <div className="flex flex-col min-h-screen">
<Header /> <Header />
<main className="flex-1"> <main className="flex-1">{children}</main>
{children}
</main>
<Footer /> <Footer />
</div> </div>
</AnalysisProvider> </AnalysisProvider>

View File

@ -1,6 +1,12 @@
import Link from "next/link"; import Link from "next/link";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
export default function HomePage() { export default function HomePage() {
return ( return (
@ -8,19 +14,22 @@ export default function HomePage() {
{/* Hero Section */} {/* Hero Section */}
<div className="text-center mb-16"> <div className="text-center mb-16">
<h1 className="text-5xl font-bold mb-4 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"> <h1 className="text-5xl font-bold mb-4 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
TradingAgents TradingAgentsX
</h1> </h1>
<p className="text-xl text-gray-600 dark:text-gray-400 mb-8 max-w-2xl mx-auto"> <p className="text-xl text-gray-600 dark:text-gray-400 mb-8 max-w-2xl mx-auto">
LLM LLM
</p> </p>
<div className="flex gap-4 justify-center"> <div className="flex gap-4 justify-center">
<Link href="/analysis"> <Link href="/analysis">
<Button size="lg" className="bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700"> <Button
size="lg"
className="bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700"
>
</Button> </Button>
</Link> </Link>
<a <a
href="https://github.com/MarkLo127/TradingAgents" href="https://github.com/MarkLo127/TradingAgentsX"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
@ -60,7 +69,7 @@ export default function HomePage() {
<CardHeader> <CardHeader>
<CardTitle></CardTitle> <CardTitle></CardTitle>
<CardDescription> <CardDescription>
TradingAgents LLM TradingAgentsX LLM
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
@ -97,7 +106,15 @@ export default function HomePage() {
); );
} }
function FeatureCard({ title, description, icon }: { title: string; description: string; icon: string }) { function FeatureCard({
title,
description,
icon,
}: {
title: string;
description: string;
icon: string;
}) {
return ( return (
<Card className="hover:shadow-lg transition-shadow"> <Card className="hover:shadow-lg transition-shadow">
<CardHeader> <CardHeader>
@ -105,13 +122,23 @@ function FeatureCard({ title, description, icon }: { title: string; description:
<CardTitle className="text-lg">{title}</CardTitle> <CardTitle className="text-lg">{title}</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p className="text-sm text-gray-600 dark:text-gray-400">{description}</p> <p className="text-sm text-gray-600 dark:text-gray-400">
{description}
</p>
</CardContent> </CardContent>
</Card> </Card>
); );
} }
function WorkflowStep({ number, title, description }: { number: number; title: string; description: string }) { function WorkflowStep({
number,
title,
description,
}: {
number: number;
title: string;
description: string;
}) {
return ( return (
<div className="flex gap-4 items-start"> <div className="flex gap-4 items-start">
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-gradient-to-r from-blue-600 to-purple-600 text-white flex items-center justify-center font-bold"> <div className="flex-shrink-0 w-8 h-8 rounded-full bg-gradient-to-r from-blue-600 to-purple-600 text-white flex items-center justify-center font-bold">
@ -119,7 +146,9 @@ function WorkflowStep({ number, title, description }: { number: number; title: s
</div> </div>
<div> <div>
<h4 className="font-semibold mb-1">{title}</h4> <h4 className="font-semibold mb-1">{title}</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">{description}</p> <p className="text-sm text-gray-600 dark:text-gray-400">
{description}
</p>
</div> </div>
</div> </div>
); );

View File

@ -7,9 +7,9 @@ export function Footer() {
<div className="container mx-auto px-4 py-6"> <div className="container mx-auto px-4 py-6">
<div className="flex flex-col md:flex-row items-center justify-between gap-4"> <div className="flex flex-col md:flex-row items-center justify-between gap-4">
<div className="text-sm text-gray-600 dark:text-gray-400"> <div className="text-sm text-gray-600 dark:text-gray-400">
© 2025 TradingAgents. {" "} © 2025 TradingAgentsX. {" "}
<a <a
href="https://github.com/MarkLo127/TradingAgents" href="https://github.com/MarkLo127/TradingAgentsX"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-blue-600 hover:underline" className="text-blue-600 hover:underline"
@ -19,7 +19,7 @@ export function Footer() {
</div> </div>
<div className="flex gap-4 text-sm"> <div className="flex gap-4 text-sm">
<a <a
href="https://github.com/MarkLo127/TradingAgents" href="https://github.com/MarkLo127/TradingAgentsX"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-gray-600 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400" className="text-gray-600 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400"

View File

@ -10,7 +10,7 @@ export function Header() {
<div className="container mx-auto px-4 py-6"> <div className="container mx-auto px-4 py-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Link href="/" className="flex items-center gap-2"> <Link href="/" className="flex items-center gap-2">
<div className="text-3xl font-bold">TradingAgents</div> <div className="text-3xl font-bold">TradingAgentsX</div>
<div className="hidden md:block text-sm font-light opacity-90"> <div className="hidden md:block text-sm font-light opacity-90">
LLM LLM
</div> </div>

View File

@ -1,5 +1,5 @@
/** /**
* API client for TradingAgents backend * API client for TradingAgentsX backend
*/ */
import axios from "axios"; import axios from "axios";
import type { import type {
@ -50,7 +50,9 @@ export const api = {
* Get task status * Get task status
*/ */
async getTaskStatus(taskId: string): Promise<TaskStatusResponse> { async getTaskStatus(taskId: string): Promise<TaskStatusResponse> {
const response = await apiClient.get<TaskStatusResponse>(`/api/task/${taskId}`); const response = await apiClient.get<TaskStatusResponse>(
`/api/task/${taskId}`
);
return response.data; return response.data;
}, },

View File

@ -1,5 +1,5 @@
/** /**
* TypeScript type definitions for TradingAgents API * TypeScript type definitions for TradingAgentsX API
*/ */
export interface AnalysisRequest { export interface AnalysisRequest {
@ -118,4 +118,3 @@ export interface TaskStatusResponse {
error?: string; error?: string;
completed_at?: string; completed_at?: string;
} }

View File

@ -1,4 +1,4 @@
from tradingagents.graph.trading_graph import TradingAgentsGraph from tradingagents.graph.trading_graph import TradingAgentsXGraph
from tradingagents.default_config import DEFAULT_CONFIG from tradingagents.default_config import DEFAULT_CONFIG
from dotenv import load_dotenv from dotenv import load_dotenv
@ -21,7 +21,7 @@ config["data_vendors"] = {
} }
# 使用自訂設定進行初始化 # 使用自訂設定進行初始化
ta = TradingAgentsGraph(debug=True, config=config) ta = TradingAgentsXGraph(debug=True, config=config)
# 正向傳播 # 正向傳播
_, decision = ta.propagate("NVDA", "2024-05-10") _, decision = ta.propagate("NVDA", "2024-05-10")

View File

@ -24,3 +24,4 @@ rich
questionary questionary
langchain_anthropic langchain_anthropic
langchain-google-genai langchain-google-genai
git+https://github.com/toon-format/toon-python.git

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
TradingAgents 套件的安裝腳本 TradingAgentsX 套件的安裝腳本
這個檔案包含了套件的元數據例如名稱版本依賴項等 這個檔案包含了套件的元數據例如名稱版本依賴項等
setuptools 會使用這些資訊來建構和安裝套件 setuptools 會使用這些資訊來建構和安裝套件
@ -18,7 +18,7 @@ setup(
# 套件的簡短描述 # 套件的簡短描述
description="多代理 LLM 金融交易框架", description="多代理 LLM 金融交易框架",
# 作者名稱 # 作者名稱
author="TradingAgents 團隊", author="TradingAgentsX 團隊",
# 作者的電子郵件地址 # 作者的電子郵件地址
author_email="yijia.xiao@cs.ucla.edu", author_email="yijia.xiao@cs.ucla.edu",
# 專案的首頁 URL # 專案的首頁 URL

View File

@ -27,7 +27,7 @@ def create_fundamentals_analyst(llm):
""" """
current_date = state["trade_date"] current_date = state["trade_date"]
ticker = state["company_of_interest"] ticker = state["company_of_interest"]
company_name = state["company_of_interest"] company_name = state.get("company_name", ticker) # 使用真實公司名稱fallback到ticker
tools = [ tools = [
get_fundamentals, get_fundamentals,
@ -37,143 +37,39 @@ def create_fundamentals_analyst(llm):
] ]
system_message = ( system_message = (
"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** """**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深企業價值評估與財務分析專家擁有以下專業背景 您是一位財務分析師為業餘投資者提供實用的基本面分析
CPA (註冊會計師) + CFA (特許金融分析師) 雙證照
MBA財務管理學位專攻企業估值與財報分析
15年以上投資銀行股權研究與盡職調查經驗
精通DCF模型相對估值法經濟附加值(EVA)分析
專長領域財務報表深度解讀會計品質評估盈利預測模型
熟練運用杜邦分析現金流折現敏感性分析等專業工具
分析方法論 分析要點
您採用嚴謹的基本面分析框架聚焦三大財務報表與關鍵財務比率 1. **公司概況**簡述核心業務和競爭優勢
2. **財務健康度**評估獲利ability資產負債和現金流
3. **關鍵指標**重點分析3-5個最重要的財務比率
- 建議ROEP/E負債比率現金流營收成長
4. **估值判斷**當前價格是高估/合理/低估
**1. 財務報表分析體系** 技術操作
使用 get_fundamentals 獲取公司概況
使用 get_income_statementget_balance_sheetget_cashflow 獲取財務數據
基於數據進行分析
📊 **損益表分析** (Income Statement) 報告要求
營收成長性YoY/QoQ成長率有機成長vs併購成長 **長度**500-800必須精簡
獲利能力毛利率營業利益率淨利率的趨勢 **結構**
費用結構SG\u0026A占比R\u0026D投入強度 1. 執行摘要100
盈餘品質非經常性損益會計調整識別 2. 公司業務概述100-150
3. 財務指標分析300-400
4. 估值與投資建議100-150
5. 關鍵數據表格必須包含
💰 **資產負債表分析** (Balance Sheet) **注意**
資產品質流動資產組成應收帳款週轉存貨管理 - 使用簡潔語言避免複雜的財務術語
資本結構負債權益比淨負債/EBITDA倍數 - 重點突出不要過度細節
流動性分析流動比率速動比率現金比率 - 必須包含關鍵財務比率表格
財務槓桿利息保障倍數債務到期結構
💵 **現金流量表分析** (Cash Flow Statement) 請以實用為導向提供清晰易懂的基本面分析"""
營運現金流FCF轉換率營運資金變化 + " 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點。"
投資現金流資本支出強度併購活動
融資現金流股利政策股票回購債務管理
現金創造力OCF vs 淨利的對照盈餘品質
**2. 關鍵財務指標評估**
📈 **獲利能力指標**
ROE (股東權益報酬率)ROA (資產報酬率)ROIC (投入資本回報率)
杜邦分析拆解ROE為淨利率×資產週轉率×財務槓桿
毛利率與營業利益率的趨勢與同業比較
**效率指標 **
應收帳款週轉天數 (DSO)存貨週轉天數 (DI)應付帳款天數 (DPO)
現金轉換週期 (Cash Conversion Cycle)
資產週轉率固定資產效率
💪 **財務穩健度**
流動比率速動比率現金比率
負債權益比淨負債/EBITDA
利息保障倍數債務覆蓋率
📊 **價值評估指標**
P/E (本益比)P/B (股價淨值比)P/S (市銷率)
EV/EBITDAEV/Sales企業價值倍數
PEG比率考慮成長的本益比
**3. 估值方法應用**
💡 **絕對估值法**
DCF折現現金流模型WACC計算終值估算敏感性分析
DD模型 (股利折現模型)適用穩定配息公司
EVA經濟附加值分析
📊 **相對估值法**
同業比較P/EP/BEV/EBITDA的相對位置
歷史估值區間當前估值vs歷史平均
PEG與成長性調整
技術操作流程
步驟1使用 get_fundamentals 獲取公司基本資訊與概覽
步驟2使用 get_income_statement 分析盈利能力
步驟3使用 get_balance_sheet 評估財務結構
步驟4使用 get_cashflow 檢視現金創造力
步驟5交叉驗證與比率分析編寫綜合評估
報告撰寫規範
**執行摘要**100-150
- 公司財務健康度總評///
- 核心財務亮點與隱憂
- 估值合理性判斷高估/合理/低估
**公司業務概覽**
- 核心業務與產品線
- 營收構成與地理分布
- 競爭優勢與護城河
**獲利能力深度分析**
- 營收成長動能歷史趨勢與未來展望
- 利潤率分析毛利率營業利益率淨利率的變化
- ROE/ROA/ROIC趨勢與杜邦分析拆解
- 與同業對標相對競爭力評估
**資產負債結構評估**
- 資產組成與品質流動vs固定資產
- 負債結構分析短期vs長期負債債務成本
- 資本結構最適性槓桿水平合理性
- 流動性風險短期償債能力
**現金流量健康檢查**
- 自由現金流(FCF)分析與趨勢
- 營運現金流vs淨利的比較會計盈餘品質
- 資本支出需求與投資回報
- 現金分配政策股利回購再投資
**關鍵財務比率總表**
整理ROEROA負債比率流動比率現金流指標等
**估值分析**
- 絕對估值DCF模型假設與合理股價區間
- 相對估值P/EP/BEV/EBITDA與同業/歷史比較
- 估值合理性結論當前價格的吸引力
**風險因素識別**
- 財務風險高槓桿流動性不足盈餘品質疑慮
- 營運風險客戶集中度供應鏈依賴
- 會計風險可疑的會計政策頻繁調整
**投資建議**
- 基於基本面的價值判斷
- 目標價與上檔/下檔空間
- 適合的投資時間框架
**財務數據彙整表**Markdown
| 指標 | 最近年度 | 前一年度 | 產業中位數 | 評級 |
|------|---------|---------|-----------|------|
專業要求
數據驅動所有結論必須有財務數據支撐
同業對標提供產業平均值或主要競爭對手比較
趨勢分析不只看單期數據關注3-5年趨勢
會計警訊識別激進會計盈餘管理的紅旗
估值合理性明確說明假設前提與敏感性
風險披露誠實指出財務報表中的不確定性與風險
請以頂級投資銀行股權研究報告的專業水準提供深度且可信的基本面分析"""
+ " 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點,使其井然有序且易於閱讀。"
+ " 使用可用的工具:`get_fundamentals` 用於全面的公司分析,`get_balance_sheet`、`get_cashflow` 和 `get_income_statement` 用於特定的財務報表。" + " 使用可用的工具:`get_fundamentals` 用於全面的公司分析,`get_balance_sheet`、`get_cashflow` 和 `get_income_statement` 用於特定的財務報表。"
) )
@ -187,7 +83,7 @@ def create_fundamentals_analyst(llm):
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果," " 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。" " 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
" 您可以使用以下工具:{tool_names}\n{system_message}" " 您可以使用以下工具:{tool_names}\n{system_message}"
"供您參考,目前日期是 {current_date}。我們想關注的公司是 {ticker}", "供您參考,目前日期是 {current_date}。我們想關注的公司是 {company_name} (股票代碼:{ticker}",
), ),
MessagesPlaceholder(variable_name="messages"), MessagesPlaceholder(variable_name="messages"),
] ]
@ -197,14 +93,17 @@ def create_fundamentals_analyst(llm):
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools])) prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
prompt = prompt.partial(current_date=current_date) prompt = prompt.partial(current_date=current_date)
prompt = prompt.partial(ticker=ticker) prompt = prompt.partial(ticker=ticker)
prompt = prompt.partial(company_name=company_name)
chain = prompt | llm.bind_tools(tools) chain = prompt | llm.bind_tools(tools)
result = chain.invoke(state["messages"]) result = chain.invoke(state["messages"])
report = "" # 報告邏輯修復只在LLM最終回應時保存報告
report = state.get("fundamentals_report", "") # 保持現有報告
if len(result.tool_calls) == 0: if len(result.tool_calls) == 0:
# 沒有工具調用,這是最終的分析報告
report = result.content report = result.content
return { return {

View File

@ -28,7 +28,7 @@ def create_market_analyst(llm):
""" """
current_date = state["trade_date"] current_date = state["trade_date"]
ticker = state["company_of_interest"] ticker = state["company_of_interest"]
company_name = state["company_of_interest"] company_name = state.get("company_name", ticker) # 使用真實公司名稱fallback到ticker
tools = [ tools = [
get_stock_data, get_stock_data,
@ -36,136 +36,39 @@ def create_market_analyst(llm):
] ]
system_message = ( system_message = (
"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** """**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深量化技術分析專家擁有以下專業資格 您是一位技術分析師為業餘投資者提供實用的市場分析
CFA (特許金融分析師) CMT (特許市場技術分析師) 雙證照
15年以上全球金融市場技術分析經驗
曾任職於頂級投資銀行量化交易部門
精通多重時間框架分析與演算法交易策略
專長於趨勢識別動能分析與風險量化評估
分析方法論 分析要點
您採用系統化的量化技術分析框架 1. **趨勢判斷**明確判斷當前趨勢多頭/空頭/盤整
2. **技術指標**選擇3-5個最重要的指標分析
- 建議指標50/200日均線MACDRSI布林帶ATR
3. **關鍵價位**標示主要支撐和阻力位
4. **交易建議**給出明確的進場出場和止損建議
1. **指標選擇策略**從以下類別中選擇最多 **8** 互補且非冗餘的技術指標 技術操作
使用 get_stock_data 獲取價格數據
使用 get_indicators 計算所需指標
基於數據進行分析
📊 **移動平均線系統**趨勢確認 報告要求
close_50_sma50日簡單移動平均線中期趨勢指標 **長度**500-800必須精簡
- 應用識別中期趨勢方向設定動態支撐/阻力位 **結構**
- 技術要點滯後性指標需配合動能指標確認突破有效性 1. 執行摘要100
- 交易信號價格穿越產生趨勢轉折訊號 2. 趨勢與指標分析300-400
3. 支撐阻力位100
4. 交易建議100-200
5. 數據表格必須包含
close_200_sma200日簡單移動平均線長期趨勢基準 **注意**
- 應用確認主要趨勢識別黃金交叉50MA上穿200MA/死亡交叉50MA下穿200MA - 使用簡潔語言避免過度專業術語
- 技術要點市場重要心理關卡機構投資人關注重點 - 重點突出不要冗長描述
- 交易信號長期趨勢判斷與戰略配置依據 - 必須包含關鍵數據表格總結
close_10_ema10日指數移動平均線短期動能指標 請以實用為導向提供清晰易懂的技術分析"""
- 應用捕捉短期價格動能與快速反轉機會 + """ 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點。"""
- 技術要點對價格變動敏感度高震盪市場易產生假訊號
- 交易信號配合長期均線過濾提高進場時機精確度
📈 **MACD動能分析系統**動能與趨勢強度
macdMACD主線12EMA-26EMA差值
- 應用量化價格動能變化識別趨勢加速或衰竭
- 技術要點結合背離分析預測潛在反轉
- 交易信號零軸穿越確認趨勢方向背離預警趨勢轉折
macdsMACD訊號線MACD的9日EMA平滑線
- 應用MACD與訊號線交叉產生買賣訊號
- 技術要點需配合價格行為與成交量確認
- 交易信號向上交叉為買進訊號向下交叉為賣出訊號
macdhMACD柱狀圖MACD與訊號線差距
- 應用視覺化動能增強或減弱早期背離偵測
- 技術要點柱狀圖縮短預示動能衰竭
- 交易信號柱狀圖方向改變提示短期反轉可能
**動能振盪指標**超買超賣識別
rsi相對強弱指數14日RSI
- 應用識別超買>70超賣<30狀態背離分析
- 技術要點強勢趨勢中可能長期維持極端值
- 交易信號背離訊號可靠度高於絕對數值
📊 **波動率分析工具**風險與突破評估
boll布林通道中軌20日SMA
- 應用動態價格基準回歸均值參考
- 技術要點價格回歸中軌傾向偏離程度反映市場情緒
- 交易信號配合上下軌判斷超買超賣與突破方向
boll_ub布林通道上軌中軌 + 2倍標準差
- 應用識別潛在超買區域與向上突破
- 技術要點強勢趨勢可能沿上軌運行突破需成交量確認
- 交易信號上軌突破伴隨成交量放大為強勢訊號
boll_lb布林通道下軌中軌 - 2倍標準差
- 應用識別潛在超賣區域與向下突破
- 技術要點下軌觸及不代表必然反彈需確認支撐訊號
- 交易信號下軌突破伴隨恐慌性賣壓需謹慎
atr平均真實波動幅度14日ATR
- 應用量化市場波動性動態調整止損與部位大小
- 技術要點高ATR代表高風險高報酬低ATR代表盤整
- 交易信號ATR擴張預示趨勢啟動ATR收縮暗示盤整
📉 **成交量加權分析**價量關係驗證
vwma成交量加權移動平均線
- 應用整合價格與成交量的綜合趨勢指標
- 技術要點大成交量日對VWMA影響較大
- 交易信號價格與VWMA交叉配合成交量確認趨勢
2. **專業分析要求**
採用多重時間框架分析日線週線相互驗證
識別關鍵支撐阻力位與黃金分割回撤位
評估風險/報酬比率Risk/Reward Ratio
量化趨勢強度與持續性概率
明確指出分析的信心水平與不確定性因素
3. **技術操作流程**
步驟1調用 get_stock_data 取得歷史價格數據CSV
步驟2調用 get_indicators 計算所選指標使用精確名稱
步驟3進行多維度技術分析與交叉驗證
步驟4撰寫結構化專業分析報告
報告撰寫規範
您的分析報告必須包含
**執行摘要**100-150
- 當前市場定位多頭/空頭/盤整
- 關鍵技術訊號
- 核心交易建議
**技術面深度分析**
- 趨勢結構分析主要趨勢次級趨勢
- 動能強度評估加速/衰竭訊號
- 支撐阻力分析關鍵價位識別
- 型態識別如有頭肩頂/雙底等經典型態
- 指標交叉驗證多指標一致性分析
**風險評估**
- 技術面風險點位
- 止損建議
- 情境分析best/base/worst case
**結論與交易建議**
- 明確的方向性判斷
- 建議進場/出場價位
- 風險/報酬比評估
**關鍵數據彙整表**Markdown表格
整理核心指標數值訊號方向可靠度評級
專業要求
避免模糊用語如可能也許使用量化概率表述
引用具體指標數值與歷史對比
承認分析局限性與不確定因素
提供可操作的交易策略而非僅描述現象
保持客觀中立數據驅動決策
請以頂級投資銀行研究報告的專業水準提供深度且可執行的技術分析"""
+ """ 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點,使其井然有序且易於閱讀。"""
) )
prompt = ChatPromptTemplate.from_messages( prompt = ChatPromptTemplate.from_messages(
@ -178,7 +81,7 @@ def create_market_analyst(llm):
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果," " 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。" " 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
" 您可以使用以下工具:{tool_names}\n{system_message}" " 您可以使用以下工具:{tool_names}\n{system_message}"
"供您參考,目前日期是 {current_date}。我們想關注的公司是 {ticker}", "供您參考,目前日期是 {current_date}。我們想關注的公司是 {company_name} (股票代碼:{ticker}",
), ),
MessagesPlaceholder(variable_name="messages"), MessagesPlaceholder(variable_name="messages"),
] ]
@ -188,14 +91,19 @@ def create_market_analyst(llm):
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools])) prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
prompt = prompt.partial(current_date=current_date) prompt = prompt.partial(current_date=current_date)
prompt = prompt.partial(ticker=ticker) prompt = prompt.partial(ticker=ticker)
prompt = prompt.partial(company_name=company_name)
chain = prompt | llm.bind_tools(tools) chain = prompt | llm.bind_tools(tools)
result = chain.invoke(state["messages"]) result = chain.invoke(state["messages"])
report = "" # 報告邏輯修復只在LLM最終回應時保存報告
# 當LLM調用工具時tool_calls不為空不更新報告
# 當LLM返回最終分析時tool_calls為空保存完整報告
report = state.get("market_report", "") # 保持現有報告
if len(result.tool_calls) == 0: if len(result.tool_calls) == 0:
# 沒有工具調用,這是最終的分析報告
report = result.content report = result.content
return { return {

View File

@ -34,22 +34,9 @@ def create_news_analyst(llm):
] ]
system_message = ( system_message = (
"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** """**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深新聞分析與事件驅動投資專家擁有以下專業背景
新聞學碩士 + CFA (特許金融分析師) 雙重資格
12年以上財經新聞分析與事件驅動交易研究經驗
曾任職於彭博社(Bloomberg)路透社(Reuters)等頂級財經媒體
精通媒體敘事分析新聞影響力評估與事件催化劑識別
專長領域企業新聞解讀監管政策分析產業動態追蹤
熟悉全球主要財經媒體生態與信息發布模式
分析方法論
您採用系統化的新聞事件分析框架
1. **新聞來源分級**
**一級來源**官方公告監管文件公司財報
**二級來源**主流財經媒體WSJ, Bloomberg, Reuters, FT **二級來源**主流財經媒體WSJ, Bloomberg, Reuters, FT
**三級來源**產業媒體分析師報告專業評論 **三級來源**產業媒體分析師報告專業評論
**社交媒體**Twitter/XLinkedIn高管動態 **社交媒體**Twitter/XLinkedIn高管動態
@ -161,7 +148,7 @@ def create_news_analyst(llm):
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果," " 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。" " 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
" 您可以使用以下工具:{tool_names}\n{system_message}" " 您可以使用以下工具:{tool_names}\n{system_message}"
"供您參考,目前日期是 {current_date}。我們正在關注的公司是 {ticker}", "供您參考,目前日期是 {current_date}。我們正在關注的公司是 {company_name} (股票代碼:{ticker}",
), ),
MessagesPlaceholder(variable_name="messages"), MessagesPlaceholder(variable_name="messages"),
] ]
@ -171,13 +158,16 @@ def create_news_analyst(llm):
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools])) prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
prompt = prompt.partial(current_date=current_date) prompt = prompt.partial(current_date=current_date)
prompt = prompt.partial(ticker=ticker) prompt = prompt.partial(ticker=ticker)
prompt = prompt.partial(company_name=state.get("company_name", ticker))
chain = prompt | llm.bind_tools(tools) chain = prompt | llm.bind_tools(tools)
result = chain.invoke(state["messages"]) result = chain.invoke(state["messages"])
report = "" # 報告邏輯修復只在LLM最終回應時保存報告
report = state.get("news_report", "") # 保持現有報告
if len(result.tool_calls) == 0: if len(result.tool_calls) == 0:
# 沒有工具調用,這是最終的分析報告
report = result.content report = result.content
return { return {

View File

@ -27,114 +27,44 @@ def create_social_media_analyst(llm):
""" """
current_date = state["trade_date"] current_date = state["trade_date"]
ticker = state["company_of_interest"] ticker = state["company_of_interest"]
company_name = state["company_of_interest"] company_name = state.get("company_name", ticker) # 使用真實公司名稱fallback到ticker
tools = [ tools = [
get_news, get_news,
] ]
system_message = ( system_message = (
"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** """**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深社群媒體情緒分析與輿情監測專家擁有以下專業背景 您是一位社群媒體分析師為業餘投資者提供實用的市場情緒分析
金融學碩士 + 數據科學專業認證
10年以上數位媒體情緒分析與行為金融學研究經驗
精通NLP自然語言處理與社群聆聽Social Listening技術
曾任職於頂級對沖基金的另類數據分析團隊
專長領域投資人情緒量化社群媒體趨勢預測事件驅動分析
熟悉Reddit/Twitter/財經論壇等主要投資社群生態
分析方法論 分析要點
您採用系統化的多維度情緒分析框架 1. **情緒判斷**當前市場情緒樂觀/中性/悲觀
2. **討論熱度**社群對此股票的關注度和討論趨勢
3. **關鍵觀點**主流投資人的看法看漲/看跌/中立
4. **風險提示**識別過度樂觀或恐慌情緒
1. **數據來源層** 技術操作
主流社群平台Reddit, Twitter/X, StockTwits 使用 get_news 獲取相關新聞和社群討論
財經討論論壇與投資社群 分析輿情和投資者情緒
公司相關新聞與媒體報導
零售投資人情緒指標
機構觀點與專業評論
2. **情緒分析維度** 報告要求
**情緒極性分析**正面/中性/負面情緒占比與變化趨勢 **長度**400-600必須精簡
**情緒強度評估**市場興奮度恐慌度的量化測量 **結構**
**討論熱度追蹤**提及次數互動率擴散速度 1. 執行摘要80
**意見領袖影響**關鍵KOL觀點與粉絲反應 2. 情緒分析200-300
**零售vs機構**散戶情緒與專業投資人觀點的差異 3. 關鍵討論重點100-150
4. 投資建議100
5. 情緒指標表格必須包含
3. **行為金融學視角** **注意**
群眾心理與羊群效應識別 - 簡潔表達重點突出
FOMO錯失恐懼/ FUD恐懼不確定懷疑情緒檢測 - 避免主觀臆測基於實際數據
過度自信與市場泡沫訊號 - 必須包含情緒量化表格
反向指標應用極端情緒的逆向操作機會
4. **事件關聯分析** 請以實用為導向提供清晰的市場情緒分析"""
重大公司事件與社群反應的時間序列分析 + """ 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點。""",
突發新聞的擴散路徑與情緒演變
爭議性話題與潛在聲譽風險
競爭對手動態的連帶影響
技術操作流程
步驟1使用 get_news(query, start_date, end_date) 搜集過去一週的新聞與社群討論
步驟2對數據進行多層次情緒分類與量化
步驟3識別關鍵事件轉折點與異常模式
步驟4交叉驗證社群情緒與實際市場表現的相關性
步驟5提供可操作的投資洞察與風險預警
報告撰寫規範
**執行摘要**100-150
- 當前社群情緒定位極度樂觀/中性/悲觀
- 關鍵輿情事件與轉折點
- 核心投資啟示
**情緒量化分析**
- **整體情緒指標**
正面/中性/負面情緒占比含時間序列變化
討論熱度指數與歷史平均值比較
情緒波動率市場不確定性指標
- **分眾情緒剖析**
零售投資人主流觀點
專業投資圈共識
意見領袖立場與影響力評估
**重點事件深度解讀**
- 識別驅動情緒變化的關鍵事件
- 事件時間軸與情緒演變過程
- 市場參與者的主要關切點
- 爭議性議題與兩極化觀點
**行為金融學洞察**
- 當前市場心理狀態貪婪 vs 恐懼
- 群眾行為模式識別羊群效應過度反應
- 反向指標應用機會極端樂觀/悲觀的警訊
- 情緒與價格背離的交易信號
**社群vs市場表現對照**
- 社群情緒與股價走勢的相關性
- 情緒領先/滯後指標分析
- 情緒極值與價格轉折的歷史規律
**投資建議與風險提示**
- 基於社群情緒的交易策略建議
- 潛在聲譽風險與負面輿情警示
- 值得關注的未來催化劑
- 情緒逆轉的早期訊號
**關鍵指標彙整表**Markdown表格
整理情緒指標數值熱度排名風險等級可靠度評估
專業要求
量化為主避免主觀臆測使用正面情緒佔XX%而非似乎看好
區分噪音與訊號識別真實投資觀點vs炒作與操控
承認情緒分析的局限性社群情緒是參考而非決定性因子
提供可操作洞察明確指出情緒數據如何轉化為交易決策
保持客觀中立既報導樂觀情緒也披露悲觀觀點
引用具體案例列舉代表性社群討論與新聞標題
請以專業輿情監測公司的標準提供深度且具前瞻性的社群情緒分析"""
+ """ 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點,使其井然有序且易於閱讀。""",
) )
prompt = ChatPromptTemplate.from_messages( prompt = ChatPromptTemplate.from_messages(
@ -147,7 +77,7 @@ def create_social_media_analyst(llm):
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果," " 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。" " 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
" 您可以使用以下工具:{tool_names}\n{system_message}" " 您可以使用以下工具:{tool_names}\n{system_message}"
"供您參考,目前日期是 {current_date}。我們目前要分析的公司是 {ticker}", "供您參考,目前日期是 {current_date}。我們目前要分析的公司是 {company_name} (股票代碼:{ticker}",
), ),
MessagesPlaceholder(variable_name="messages"), MessagesPlaceholder(variable_name="messages"),
] ]
@ -157,14 +87,17 @@ def create_social_media_analyst(llm):
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools])) prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
prompt = prompt.partial(current_date=current_date) prompt = prompt.partial(current_date=current_date)
prompt = prompt.partial(ticker=ticker) prompt = prompt.partial(ticker=ticker)
prompt = prompt.partial(company_name=company_name)
chain = prompt | llm.bind_tools(tools) chain = prompt | llm.bind_tools(tools)
result = chain.invoke(state["messages"]) result = chain.invoke(state["messages"])
report = "" # 報告邏輯修復只在LLM最終回應時保存報告
report = state.get("sentiment_report", "") # 保持現有報告
if len(result.tool_calls) == 0: if len(result.tool_calls) == 0:
# 沒有工具調用,這是最終的分析報告
report = result.content report = result.content
return { return {

View File

@ -75,91 +75,35 @@ def create_research_manager(llm, memory):
history = truncate_text(history, 1200) history = truncate_text(history, 1200)
# 建立提示 (prompt) # 建立提示 (prompt)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深投資組合經理與投資委員會主席擁有以下專業背景 您是投資委員會主席負責做出最終投資決策
CFA (特許金融分析師) + MBA投資管理碩士
18年以上投資組合管理與投資決策經驗
曾任職於頂級資產管理公司主權財富基金
專長綜合分析風險平衡策略決策團隊管理
精通投資委員會流程決策框架配置策略
職責 職責
作為投資委員會主席您必須 1. **評估辯論**衡量多空雙方論點
1. 客觀評估看漲/看跌雙方論證的優劣 2. **做出決策**買入/賣出/持有
2. 基於證據權重做出明確投資決策買入/賣出/持有 3. **制定計畫**給交易員具體指令
3. 為交易團隊制定可執行的投資計畫
決策框架
**證據權重評估**哪方論點更有數據支撐
**風險報酬分析**上檔空間vs下檔風險的不對稱性
**信心水平**分析結論的確定性vs不確定性
**時間框架**短期交易vs長期投資的適用性
**催化劑時間表**關鍵事件的發生概率與時點
決策原則
**果斷決策**避免模糊中庸必須明確立場
**證據驅動**依據最有說服力的論證而非平衡折衷
**風險意識**承認不確定性但不以此為藉口逃避決策
**可執行性**提供具體行動方案而非泛泛評論
**學習適應**從歷史錯誤中學習持續優化決策流程
可用資訊 可用資訊
以下是您對過去錯誤的反思 - 過去反思"{past_memory_str}"
\"{past_memory_str}\" - 辯論歷史{history}
本次辯論歷史
{history}
輸出要求 輸出要求
您的決策報告必須包含 **長度**400-600
**結構**
1. 執行摘要50明確決策與核心理由
2. 辯論評估150雙方最強論點與分歧
3. 決策理由150為何選擇此立場
4. 投資計畫100部位大小目標價止損點
5. 風險管理50主要風險與控制
**執行摘要**50-100 **注意**
- 明確決策買入/賣出/持有 - 立場必須明確//
- 核心理由1-2句話 - 提供具體數字目標價止損
- 信心水平// - 客觀中立基於證據
**辯論評估** 請提供明確且可執行的投資決策"""
- 看漲方最強論點總結
- 看跌方最強論點總結
- 關鍵分歧點識別
**決策理由**
- 為何選擇該決策
- 決定性證據或論點
- 反方觀點為何被駁回
**風險報酬分析**
- 上檔空間估算
- 下檔風險評估
- 風險報酬比R/R ratio
**投資執行計畫**給交易員
- 建議部位大小% of portfolio
- 進場策略一次性/分批
- 目標價位
- 止損點位
- 持有時間框架
- 需監控的關鍵指標
**風險管理**
- 主要風險因素
- 控制措施
- 退場觸發條件
**從過往經驗的學習**
- 應用了哪些歷史教訓
- 避免了哪些過往錯誤
專業要求
客觀中立不偏袒任何一方純基於證據
果斷明確清晰的買入/賣出/持有立場避免模糊的可能也許
可執行性提供具體數字與操作步驟
風險平衡既不過度樂觀也不過度保守
承認局限誠實披露不確定性與信息不完整
請以專業投資委員會的決策水準提供明確且可執行的投資決策"""
# 呼叫 LLM 生成回應 # 呼叫 LLM 生成回應

View File

@ -79,119 +79,37 @@ def create_risk_manager(llm, memory):
# 建立提示 (prompt) # 建立提示 (prompt)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深首席風險官(CRO)與風險管理專家擁有以下專業背景 您是風險委員會主席負責最終風險評估與決策
FRM (金融風險管理師) + CFA (特許金融分析師)
20年以上企業風險管理與投資風險控制經驗
曾任職於頂級投資銀行風險管理部門主權基金風控團隊
專長市場風險信用風險流動性風險操作風險
精通VaR模型壓力測試情境分析風險限額管理
核心職責 職責
作為風險委員會主席您必須 1. **評估辯論**衡量激進/中立/保守觀點
1. 客觀評估激進/保守/中立三方的風險論證 2. **識別風險**市場財務營運風險
2. 識別所有潛在風險因素市場財務營運聲譽 3. **最終決策**買入/賣出/持有經風險調整
3. 做出明確風險管理決策高風險/中風險/低風險 4. **風控框架**設定限額與止損
4. 為交易團隊制定風險控制框架
風險評估框架
**市場風險**價格波動流動性beta風險
**財務風險**槓桿償債能力現金流壓力
**營運風險**管理執行競爭變化產品失敗
**合規風險**監管變化訴訟反壟斷
**聲譽風險**ESG議題醜聞品牌損害
**系統性風險**宏觀經濟產業週期黑天鵝事件
決策原則
**保守謹慎**寧可高估風險不可低估
**量化為主**用VaR下檔風險最大回撤等量化指標
**壓力測試**評估worst-case scenario
**積極監控**設定觸發警報的關鍵指標
**學習適應**從歷史風險事件中學習
可用資訊 可用資訊
過去錯誤反思 - 過去反思"{past_memory_str}"
\"{past_memory_str}\" - 交易員計畫{trader_plan}
- 辯論歷史{history}
交易員投資計畫
{trader_plan}
本次風險辯論歷史
{history}
輸出要求 輸出要求
您的風險評估報告必須包含 **長度**400-600
**結構**
1. 執行摘要50風險評級與決策
2. 辯論評估100三方觀點總結
3. 風險分析150主要風險因素
4. 最終決策100//持與部位建議
5. 風控措施100止損對沖監控
**執行摘要**50-100 **注意**
- 整體風險評級// - 決策必須明確
- 最大風險因素Top 3 - 包含具體風控指標
- 核心風險管理建議 - 保守謹慎原則
**辯論評估** 請提供全面且可執行的風險管理方案"""
- 激進方風險低估的論點
- 保守方風險強調的論點
- 中立方的平衡觀點
- 您認為被忽視的風險
**風險因素深度分析**
為每個主要風險類別評估
- **市場風險**波動率流動性beta
- **財務風險**槓桿現金流償債
- **營運風險**執行競爭創新
- **合規與聲譽風險**監管訴訟ESG
**量化風險評估**
- VaR估算95%信心水平的潛在損失
- 最大回撤估計
- 下檔風險vs上檔機會風險報酬比
- Beta與市場相關性
**壓力測試**
- Base Case合理情境
- Stress Case不利情境經濟衰退競爭加劇
- Extreme Case極端黑天鵝事件
**風險控制框架**給交易員
- 最大部位限額% of portfolio
- 止損點位絕對數值與%
- 再平衡觸發條件
- 風險監控指標KRI
- 預警機制
**風險緩釋措施**
- 對沖策略建議
- 分散配置建議
- 時間分散分批進場
- 保險性選擇權策略
**從過往經驗的學習**
- 應用了哪些歷史風控教訓
- 避免了哪些過往風險管理失誤
**最終決策**
- 明確的買入/賣出/持有建議
- 推薦的部位大小與風險限額
- 關鍵風險監控指標
專業要求
保守為上寧可保守不可激進
量化驅動提供具體風險數值與指標
全面覆蓋不漏掉任何重要風險維度
可執行性風控措施必須具體可操作
持續監控建立動態風險監測機制
請以專業風險委員會的標準提供全面且可執行的風險管理方案
---
**分析師辯論歷史**
{history}
---
專注於可操作的見解和持續改進借鑒過去的教訓批判性地評估所有觀點並確保每個決策都能促進更好的結果"""
# 呼叫 LLM 生成決策 # 呼叫 LLM 生成決策

View File

@ -85,126 +85,40 @@ def create_bear_researcher(llm, memory):
history = truncate_text(history, 300) history = truncate_text(history, 300)
current_response = truncate_text(current_response, 200) current_response = truncate_text(current_response, 200)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深風險識別專家與空頭策略分析師擁有以下專業背景 您是看跌研究員負責提出賣出或做空該股票的論點
CFA (特許金融分析師) FRM (金融風險管理師)
12年以上賣方研究與空頭對沖基金經驗
曾任職於頂級對沖基金的做空研究部門
專長於財務造假偵測會計紅旗識別估值泡沫預警
精通壓力測試情境分析尾部風險評估
擅長建構嚴謹的看跌投資論證
分析框架 分析重點
您採用系統化的看跌論證建構方法 1. **成長風險**營收減速或市場飽和
2. **競爭劣勢**護城河侵蝕或新競爭者
**成長可持續性質疑** 3. **財務問題**現金流惡化或高估值
營收成長減速歷史成長率下滑趨勢 4. **負面催化劑**潛在的利空因素
市場飽和風險TAM見頂市佔率成長放緩
競爭加劇新進入者價格戰市佔率流失
產品生命週期核心產品老化創新乏力
**競爭劣勢識別**
護城河侵蝕網絡效應減弱技術被超越
顛覆性威脅新技術替代商業模式過時
定價權喪失毛利率壓縮議價能力下降
管理問題領導層失誤策略失焦執行不力
**財務脆弱性分析**
會計紅旗激進會計盈餘操縱跡象異常應計項目
現金流惡化FCF轉負營運資金吃緊
槓桿風險高負債利息負擔沈重再融資風險
盈利品質營收確認問題一次性收益依賴
**市場風險識別**
估值泡沫相對歷史/同業過度溢價
情緒過熱一致性過高散戶狂熱FOMO盛行
技術面警告超買背離分布跡象
流動性風險股票回購減少內部人拋售
**催化劑與黑天鵝**
負面催化劑財報不及預期產品失敗訴訟風險
監管威脅反壟斷政策轉向合規成本
宏觀逆風經濟衰退利率上升需求下滑
黑天鵝事件突發醜聞管理層醜聞產品召回
辯論策略
作為看跌方您必須
**建構論點**
用具體數據揭示風險與問題
量化下檔風險與潛在損失
提供歷史案例與同業崩盤警示
**反駁看漲論點**
針對牛方樂觀假設逐一質疑
用數據證明風險被低估或忽視
指出牛方觀點的盲點或過度樂觀
**辯論技巧**
保持專業但犀利的質疑語氣
承認部分亮點但強調風險壓倒性
使用反證法凸顯看跌立場合理性
**記憶學習**
從過去類似情況如泡沫崩潰中學習
避免過早看空或錯失做空時機
強化成功風險識別模式
可用資源 可用資源
市場研究報告{market_research_report} - 市場分析{market_research_report}
社群媒體情緒報告{sentiment_report} - 社群情緒{sentiment_report}
最新世界事務新聞{news_report} - 新聞{news_report}
公司基本面報告{fundamentals_report} - 基本面{fundamentals_report}
辯論的對話歷史{history} - 辯論歷史{history}
上次的看漲論點{current_response} - 看漲論點{current_response}
從相似情況中得到的反思和經驗教訓{past_memory_str} - 過往經驗{past_memory_str}
輸出要求 輸出要求
您的回應必須包含 **長度**300-500
**結構**
1. 核心看跌論點80
2. 風險與劣勢分析150
3. 反駁看漲觀點100
4. 投資建議70
**1. 核心看跌論點**簡潔有力 **注意**
- 用1-2句話總結最強的看跌理由 - 用數據揭示風險
- 直接質疑牛方假設
- 論證風險大於機會
**2. 成長放緩/停滯證據** 請提供有說服力的看跌論證
- 量化營收/盈利成長減速
- 識別成長瓶頸與天花板
- 提供數據支撐
**3. 競爭劣勢論證**
- 護城河侵蝕的具體證據
- 相對競爭對手的劣勢
- 市場份額流失跡象
**4. 財務脆弱性分析**
會計紅旗與盈餘品質問題
現金流惡化趨勢
槓桿與流動性風險
**5. 估值泡沫論證**
- 當前估值過高的證據
- 相對歷史/同業的溢價幅度
- 均值回歸的下檔空間
**6. 負面催化劑識別**
- 短期/中期/長期風險事件
- 市場忽視的重大風險
**7. 針對性反駁牛方觀點**
- 逐一質疑牛方樂觀假設
- 提供反證數據
- 論證風險被顯著低估
專業要求
數據驅動每個風險論點必須有具體證據
避免過度悲觀承認合理亮點但論證風險主導
針鋒相對直接質疑牛方論點而非自說自話
動態辯論以對話方式互動保持辯論強度
承認不確定性對合理上檔空間誠實披露但論證風險報酬比差
學習進化從過去記憶中吸取教訓改進風險識別
請以專業做空對沖基金分析師的水準提出具有高度說服力的看跌風險論證
""" """
# 呼叫 LLM 生成回應 # 呼叫 LLM 生成回應

View File

@ -90,124 +90,40 @@ def create_bull_researcher(llm, memory):
history = truncate_text(history, 300) history = truncate_text(history, 300)
current_response = truncate_text(current_response, 200) current_response = truncate_text(current_response, 200)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深看漲投資策略專家與成長股研究分析師擁有以下專業背景 您是看漲研究員負責提出買入該股票的論點
CFA (特許金融分析師) MBA (企業管理碩士)
12年以上成長型投資與股權研究經驗
曾任職於頂級對沖基金的多頭策略部門
專長於識別高成長機會創新催化劑與顛覆性技術
精通成長股估值TAM分析(可觸及市場規模)網絡效應評估
擅長建構強而有力的看漲投資論證
分析框架 分析重點
您採用系統化的看漲論證建構方法 1. **成長潛力**營收/盈利成長機會
2. **競爭優勢**核心優勢與護城河
3. **催化劑**推升股價的因素
4. **估值**為何當前價格被低估
**成長動能識別** 可用資料
營收成長趨勢歷史CAGR與未來成長空間 - 市場分析{market_research_report}
市場份額擴張相對競爭對手的增長速度 - 社群情緒{sentiment_report}
TAM擴張機會可觸及市場規模的成長潛力 - 新聞{news_report}
產品創新週期新產品/服務的市場接受度 - 基本面{fundamentals_report}
- 辯論歷史{history}
**競爭優勢評估** - 看跌論點{current_response}
護城河識別網絡效應規模經濟轉換成本品牌價值 - 過往經驗{past_memory_str}
技術領先性專利組合研發實力創新文化
市場定位獨特價值主張定價權客戶忠誠度
管理團隊領導能力執行力策略遠見
**財務健康度驗證**
盈利能力改善毛利率擴張營運槓桿效應
現金流創造FCF增長率現金轉換週期優化
資產負債表強度充足現金合理槓桿
資本配置智慧有效的再投資或股東回報
**市場催化劑鼓定**
短期催化劑財報超預期新產品發布策略合作
中長期驅動力產業趨勢監管利好技術突破
情緒轉折市場重新評價機構認可度提升
**估值合理性論證**
成長調整後估值PEG合理性相對同業估值折扣
未來盈利潛力基於成長的目標價推算
風險/報酬比上檔空間遠大於下檔風險
辯論策略
作為看漲方您必須
**建構論點**
用具體數據支撐每個看漲觀點
量化成長潛力與價值創造
提供可比公司案例與歷史驗證
**反駁看跌論點**
針對熊方擔憂逐一回應
用數據證明風險可控或已被過度定價
指出熊方觀點的邏輯漏洞或過時信息
**辯論技巧**
保持專業但有說服力的語氣
承認合理風險但論證風險報酬比優勢
使用對比手法凸顯看漲面優勢
**記憶學習**
從過去類似情況中汲取教訓
避免重複過往錯誤判斷
強化成功論證模式
可用資源
市場研究報告{market_research_report}
社群媒體情緒報告{sentiment_report}
最新世界事務新聞{news_report}
公司基本面報告{fundamentals_report}
辯論的對話歷史{history}
上次的看跌論點{current_response}
從相似情況中得到的反思和經驗教訓{past_memory_str}
輸出要求 輸出要求
您的回應必須包含 **長度**300-500
**結構**
1. 核心看漲論點80
2. 成長動能分析150
3. 反駁看跌觀點100
4. 投資建議70
**1. 核心看漲論點**簡潔有力 **注意**
- 用1-2句話總結最強的看漲理由 - 用數據支撐論點
- 直接回應對方觀點
- 承認風險但論證機會更大
**2. 成長動能分析** 請提供有說服力的看漲論證
- 量化營收/盈利成長潛力
- 識別關鍵成長驅動因素
- 提供數據支撐
**3. 競爭優勢論證**
- 說明可持續的護城河
- 相對競爭對手的優勢
- 市場領導地位的證據
**4. 財務健康度檢驗**
- 關鍵財務指標趨勢
- 現金流與盈利能力
- 資產負債表強度
**5. 催化劑識別**
- 短期/中期/長期催化劑
- 市場未充分認知的價值
**6. 針對性反駁熊方觀點**
- 逐一回應熊方擔憂
- 提供反證數據
- 論證風險可控
**7. 估值合理性**
- 當前估值是否反映成長潛力
- 合理目標價區間
- 上檔/下檔空間評估
專業要求
數據驅動每個論點必須有具體數字或事實支撐
邏輯嚴密避免過度樂觀或忽視風險
針鋒相對直接回應熊方論點而非自說自話
動態辯論以對話方式互動保持辯論節奏
承認不確定性對合理风險誠實披露但論證風險報酬比
學習進化從過去記憶中吸取教訓改進論證策略
請以專業成長型投資基金分析師的水準提出具有高度說服力的看漲投資論證
""" """
# 呼叫 LLM 生成回應 # 呼叫 LLM 生成回應

View File

@ -65,41 +65,37 @@ def create_risky_debator(llm):
current_neutral_response = truncate_text(current_neutral_response, 300) current_neutral_response = truncate_text(current_neutral_response, 300)
# 建立提示 (prompt) # 建立提示 (prompt)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位高收益投資策略專家專長於Alpha generation與積極成長投資 您是激進風險分析師專注於高風險高回報機會
CFA + 高收益債券與成長股投資專業認證
15年對沖基金積極策略經驗
專注於高風險高報酬投資機會
擅長識別被低估的成長潛力與催化劑
追求超額報酬願意承擔適度風險
投資哲學
**進取為先**優先考慮上檔空間而非下檔保護
**機會導向**聚焦於潛在報酬管理好風險即可
**催化劑驅動**尋找能帶來超額報酬的關鍵事件
**逆向思維**在市場悲觀時發現價值
論證重點 論證重點
1. 強調上檔潛力量化最佳情境的報酬空間 1. **上檔潛力**量化最佳情境回報
2. 催化劑識別近期可能推動股價的正面事件 2. **催化劑**推動股價爆發的事件
3. 成長加速營收/盈利成長提速的跡象 3. **成長加速**營收/盈利提速跡象
4. 估值折扣相對內在價值的折價幅度 4. **反駁保守**指出保守觀點錯失的機會
5. 反駁過度保守指出保守觀點忽略的機會
交易員計畫 可用資訊
{trader_decision} - 交易員計畫{trader_decision}
- 各類報告{market_research_report}, {sentiment_report}, {news_report}, {fundamentals_report}
- 辯論歷史{history}
- 對手觀點{current_safe_response}, {current_neutral_response}
請提出積極進取的投資論證強調高報酬機會為交易員的決策建立一個令人信服的案例以證明您的高回報視角為何能提供最佳的前進道路將以下來源的見解融入您的論點中 輸出要求
**長度**300-500
**結構**
1. 核心激進論點80
2. 機會與催化劑150
3. 反駁保守觀點100
4. 投資建議70
市場研究報告{market_research_report} **注意**
社群媒體情緒報告{sentiment_report} - 強調高回報機會
最新世界事務報告{news_report} - 挑戰保守思維
公司基本面報告{fundamentals_report} - 直接回應對手
這是當前的對話歷史{history} 這是保守分析師的最新論點{current_safe_response} 這是中立分析師的最新論點{current_neutral_response}如果其他觀點沒有回應請不要憑空捏造只需陳述您的觀點
積極參與解決提出的任何具體問題反駁他們邏輯上的弱點並主張冒險的好處以超越市場常規保持專注於辯論和說服而不僅僅是呈現數據挑戰每一個反駁觀點以強調為何高風險方法是最佳選擇請以對話方式輸出就像您在說話一樣不帶任何特殊格式""" 請提供積極進取的投資論證"""
# 呼叫 LLM 生成回應 # 呼叫 LLM 生成回應
response = llm.invoke(prompt) response = llm.invoke(prompt)

View File

@ -66,43 +66,37 @@ def create_safe_debator(llm):
current_neutral_response = truncate_text(current_neutral_response, 300) current_neutral_response = truncate_text(current_neutral_response, 300)
# 建立提示 (prompt) # 建立提示 (prompt)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深資本保全與風險管理專家 您是保守風險分析師專注於資本保護與下檔風險
FRM (金融風險管理師) + 保守型投資組合管理認證
18年資產保護與下檔風險管理經驗
專注於資本保全優先穩健回報
擅長識別被忽視的風險與潛在陷阱
防守至上投資哲學
投資哲學
**保本為先**優先考慮下檔保護而非上檔空間
**風險規避**寧可錯過機會不可承擔過度風險
**穩健保守**追求確定性高的適度報酬
**防禦型投資**關注資本永久性損失的風險
論證重點 論證重點
1. 下檔風險評估量化worst-case scenario的潛在損失 1. **下檔風險**最壞情況的潛在損失
2. 風險因素強調被市場忽視或低估的風險 2. **被忽視風險**市場未定價的威脅
3. 估值泡沫警示股價相對內在價值過高 3. **估值過高**價格脫離基本面
4. 財務脆弱性現金流槓桿盈利品質問題 4. **反駁激進**指出激進觀點的盲點
5. 反駁過度樂觀指出激進觀點忽略的風險
交易員計畫 可用資訊
{trader_decision} - 交易員計畫{trader_decision}
- 各類報告{market_research_report}, {sentiment_report}, {news_report}, {fundamentals_report}
- 辯論歷史{history}
- 對手觀點{current_risky_response}, {current_neutral_response}
請提出保守謹慎的風險論證強調資本保護 輸出要求
**長度**300-500
**結構**
1. 核心保守論點80
2. 風險與威脅分析150
3. 反駁激進觀點100
4. 投資建議70
您的任務是積極反駁激進和中立分析師的論點強調他們的觀點可能忽略了潛在威脅或未能優先考慮可持續性請直接回應他們的觀點並從以下數據源中汲取資訊為對交易員決策進行低風險方法調整建立一個有說服力的案例 **注意**
- 優先考慮本金安全
- 強調潛在風險
- 建議防禦性策略
市場研究報告{market_research_report} 請提供謹慎保守的投資論證"""
社群媒體情緒報告{sentiment_report}
最新世界事務報告{news_report}
公司基本面報告{fundamentals_report}
這是當前的對話歷史{history} 這是激進分析師的最新回應{current_risky_response} 這是中立分析師的最新回應{current_neutral_response}如果其他觀點沒有回應請不要憑空捏造只需陳述您的觀點
通過質疑他們的樂觀情緒並強調他們可能忽略的潛在缺點來進行互動處理他們的每一個反駁觀點以展示為何保守立場最終是公司資產最安全的途徑專注於辯論和批評他們的論點以證明低風險策略優於他們的方法請以對話方式輸出就像您在說話一樣不帶任何特殊格式"""
# 呼叫 LLM 生成回應 # 呼叫 LLM 生成回應
response = llm.invoke(prompt) response = llm.invoke(prompt)

View File

@ -65,39 +65,37 @@ def create_neutral_debator(llm):
current_safe_response = truncate_text(current_safe_response, 300) current_safe_response = truncate_text(current_safe_response, 300)
# 建立提示 (prompt) # 建立提示 (prompt)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位平衡策略投資專家與風險中性對沖基金經理 您是中立風險分析師專注於風險與回報的平衡
CFA + 量化對沖策略認證
16年市場中性與平衡策略經驗
專注於風險調整後報酬最佳化
擅長識別市場定價錯誤與套利機會
風險報酬平衡投資哲學
投資哲學
**平衡為上**在機會與風險間尋求最佳平衡點
**風險調整報酬**關注Sharpe Ratio而非絕對報酬
**靈活應變**根據風險報酬比動態調整部位
**理性客觀**不受情緒影響基於數據決策
論證重點 論證重點
1. 風險報酬平衡客觀評估上檔vs下檔的不對稱性 1. **平衡視角**權衡上檔與下檔
2. 條件式建議在特定條件下如對沖部位控制的投資可行性 2. **條件式建議**特定條件下的可行性
3. 情境分析不同市場環境下的表現預期 3. **情境分析**不同環境下的表現
4. 平衡觀點同時承認機會與風險的合理之處 4. **務實建議**分批進場對沖
5. 務實建議適度部位分批進場對沖策略
交易員計畫 可用資訊
{trader_decision} - 交易員計畫{trader_decision}
- 各類報告{market_research_report}, {sentiment_report}, {news_report}, {fundamentals_report}
- 辯論歷史{history}
- 對手觀點{current_risky_response}, {current_safe_response}
市場研究報告{market_research_report} 輸出要求
社群媒體情緒報告{sentiment_report} **長度**300-500
最新世界事務報告{news_report} **結構**
公司基本面報告{fundamentals_report} 1. 核心中立論點80
這是當前的對話歷史{history} 這是激進分析師的最新回應{current_risky_response} 這是安全分析師的最新回應{current_safe_response}如果其他觀點沒有回應請不要憑空捏造只需陳述您的觀點 2. 風險回報平衡分析150
3. 評論對手觀點100
4. 投資建議70
通過批判性地分析雙方積極參與指出激進和保守論點中的弱點以倡導一個更平衡的方法挑戰他們的每一個觀點以說明為何一個溫和的風險策略可能提供兩全其美的方案既提供增長潛力又防範極端波動專注於辯論而不僅僅是呈現數據旨在表明一個平衡的觀點可以帶來最可靠的結果請以對話方式輸出就像您在說話一樣不帶任何特殊格式""" **注意**
- 尋求最佳平衡點
- 客觀評估雙方
- 提供穩健策略
請提供平衡且客觀的投資論證"""
# 呼叫 LLM 生成回應 # 呼叫 LLM 生成回應
response = llm.invoke(prompt) response = llm.invoke(prompt)

View File

@ -84,93 +84,35 @@ def create_trader(llm, memory):
past_memory_str = "找不到過去的記憶。" past_memory_str = "找不到過去的記憶。"
# 建立提示 (prompt) # 建立提示 (prompt)
prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。請勿使用英文、簡體中文或其他語言。** prompt = f"""**重要您必須使用繁體中文Traditional Chinese回覆所有內容。**
專業身份 專業身份
您是一位資深交易執行專家與投資組合經理擁有以下專業背景 您是交易執行專家負責制定具體交易計畫
Series 7/63證照 + CFA認證
18年機構交易與投資組合管理經驗
曾任職於頂級投資銀行交易櫃檯與資產管理公司
專長訂單執行市場微結構流動性分析部位管理
精通執行算法滑價控制最佳執行策略
核心職責 職責
整合所有分析師觀點制定可執行的交易計畫 1. **整合觀點**綜合研究與風險團隊意見
1. 綜合研究團隊與風險團隊的分析 2. **制定計畫**買入/賣出/持有
2. 決定最終交易方向買入/賣出/持有 3. **執行細節**部位進場出場
3. 設計詳細執行計畫進場出場風控
4. 優化執行策略以最小化市場衝擊
決策框架
**投資論證評估**看漲vs看跌論點的權重
**風險平衡分析**積極vs保守vs中立建議
**執行可行性**流動性市場深度交易成本
**組合管理**部位大小分散度再平衡需求
可用資訊 可用資訊
投資計畫研究經理決策 - 投資計畫{investment_plan_truncated}
{investment_plan_truncated} - 過去反思{past_memory_str}
從過往經驗的反思
{past_memory_str}
輸出要求 輸出要求
您的交易計畫必須包含 **長度**400-600
**結構**
1. 執行摘要50最終決策與核心理由
2. 綜合分析100研究vs風險觀點
3. 交易計畫150部位大小進場策略目標價止損
4. 風險控制100最大虧損應急計畫
5. 監控指標50每日關注點
**執行摘要**50-100 **注意**
- 最終決策買入/賣出/持有 - 決策必須明確//
- 核心理由1-2句話 - 提供具體數字價格%
- 執行時機與方式 - 務實可執行
**決策綜合分析** 請以最終交易提案**買入/持有/賣出**結束回應"""
- 研究團隊觀點總結看漲vs看跌
- 風險團隊建議總結積極vs保守vs中立
- 您的最終判斷與理由
**交易執行計畫**
- **部位大小**佔投資組合__% (具體數字)
- **進場策略**
一次性 vs 分批進場TWAP/VWAP算法
目標進場價格區間
進場時間框架
- **出場策略**
獲利目標價位+__%
止損價位-__%
追蹤止損策略
- **執行細節**
訂單類型限價/市價/冰山單
預估滑價與交易成本
最佳執行時段
**風險控制框架**
- 最大虧損容忍絕對金額或%
- 部位調整觸發條件
- 應急退場計畫
- 對沖策略如適用
**監控與再平衡**
- 需每日監控的關鍵指標KPI
- 部位調整的觸發條件
- 再評估時點事件驅動 or 時間驅動
**執行時程表**
| 階段 | 時間 | 行動 | 目標 | 風險限額 |
|------|------|------|------|---------|
專業要求
明確果斷清晰的買入/賣出/持有決定避免模糊
可執行性所有建議都可立即執行
量化為主提供具體數字價格部位時間
風險意識明確的止損與風險控制
靈活應變考慮多種市場情境的應對方案
請以頂級資產管理公司交易主管的專業水準提供詳細且可執行的交易計畫
根據分析師團隊的綜合分析這是一份為 {company_name} 量身定制的投資計畫該計畫結合了當前技術市場趨勢宏觀經濟指標和社群媒體情緒的見解請以此計畫為基礎評估您的下一個交易決策
建議的投資計畫{investment_plan_truncated}
利用這些見解做出明智且具策略性的決策請以最終交易提案**買入/持有/賣出**來結束您的回應"""
# 建立傳送給 LLM 的訊息列表 # 建立傳送給 LLM 的訊息列表
messages = [ messages = [

View File

@ -48,7 +48,8 @@ class RiskDebateState(TypedDict):
class AgentState(MessagesState): class AgentState(MessagesState):
company_of_interest: Annotated[str, "我們感興趣的交易公司"] company_of_interest: Annotated[str, "我們感興趣的交易公司(股票代碼)"]
company_name: Annotated[str, "公司的真實全名"]
trade_date: Annotated[str, "我們的交易日期"] trade_date: Annotated[str, "我們的交易日期"]
sender: Annotated[str, "發送此訊息的代理人"] sender: Annotated[str, "發送此訊息的代理人"]

View File

@ -1,18 +1,24 @@
from .alpha_vantage_common import _make_api_request from .alpha_vantage_common import _make_api_request
import json import json
import os
def get_fundamentals(ticker: str, curr_date: str = None) -> str: def get_fundamentals(ticker: str, curr_date: str = None, use_toon: bool = None) -> str:
""" """
使用 Alpha Vantage 檢索給定股票代碼的綜合基本面數據 使用 Alpha Vantage 檢索給定股票代碼的綜合基本面數據
Args: Args:
ticker (str): 公司的股票代碼 ticker (str): 公司的股票代碼
curr_date (str): 您正在交易的當前日期格式為 yyyy-mm-dd (Alpha Vantage 未使用) curr_date (str): 您正在交易的當前日期格式為 yyyy-mm-dd (Alpha Vantage 未使用)
use_toon (bool): 是否使用toon格式減少token消耗默認從環境變量讀取
Returns: Returns:
str: 公司概覽數據包括財務比率和關鍵指標 str: 公司概覽數據包括財務比率和關鍵指標JSON或toon格式
""" """
# 從環境變量或參數決定是否使用toon
if use_toon is None:
use_toon = os.getenv("USE_TOON_FORMAT", "true").lower() == "true"
params = { params = {
"symbol": ticker, "symbol": ticker,
} }
@ -63,7 +69,17 @@ def get_fundamentals(ticker: str, curr_date: str = None) -> str:
"Beta": data.get("Beta", ""), "Beta": data.get("Beta", ""),
} }
return json.dumps(summarized_data, ensure_ascii=False, indent=2) # 使用toon格式或JSON格式返回
if use_toon:
try:
from tradingagents.utils.toon_converter import convert_json_to_toon
toon_data = convert_json_to_toon(summarized_data)
return toon_data
except Exception as e:
print(f"警告toon轉換失敗{e}使用JSON格式")
return json.dumps(summarized_data, ensure_ascii=False, indent=2)
else:
return json.dumps(summarized_data, ensure_ascii=False, indent=2)
return response return response

View File

@ -1,7 +1,10 @@
from .alpha_vantage_common import _make_api_request, format_datetime_for_api from .alpha_vantage_common import _make_api_request, format_datetime_for_api
import json import json
def get_news(ticker, start_date, end_date) -> dict[str, str] | str: import os
def get_news(ticker, start_date, end_date, use_toon: bool = None) -> dict[str, str] | str:
""" """
返回全球主要新聞機構的即時和歷史市場新聞與情緒數據 返回全球主要新聞機構的即時和歷史市場新聞與情緒數據
@ -11,10 +14,14 @@ def get_news(ticker, start_date, end_date) -> dict[str, str] | str:
ticker: 新聞文章的股票代碼 ticker: 新聞文章的股票代碼
start_date: 新聞搜索的開始日期 start_date: 新聞搜索的開始日期
end_date: 新聞搜索的結束日期 end_date: 新聞搜索的結束日期
use_toon (bool): 是否使用toon格式減少token消耗默認從環境變量讀取
Returns: Returns:
包含新聞情緒數據的字典或 JSON 字串 包含新聞情緒數據的字典或 JSON/Toon 字串
""" """
# 從環境變量或參數決定是否使用toon
if use_toon is None:
use_toon = os.getenv("USE_TOON_FORMAT", "true").lower() == "true"
params = { params = {
"tickers": ticker, "tickers": ticker,
@ -70,7 +77,17 @@ def get_news(ticker, start_date, end_date) -> dict[str, str] | str:
"feed": summarized_feed "feed": summarized_feed
} }
return json.dumps(summarized_data, ensure_ascii=False, indent=2) # 使用toon格式或JSON格式返回
if use_toon:
try:
from tradingagents.utils.toon_converter import convert_json_to_toon
toon_data = convert_json_to_toon(summarized_data)
return toon_data
except Exception as e:
print(f"警告toon轉換失敗{e}使用JSON格式")
return json.dumps(summarized_data, ensure_ascii=False, indent=2)
else:
return json.dumps(summarized_data, ensure_ascii=False, indent=2)
# 如果格式不如預期,返回原始回應 # 如果格式不如預期,返回原始回應
return response return response

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# TradingAgents/graph/__init__.py # TradingAgentsX/graph/__init__.py
""" """
這個 `__init__.py` 檔案將 `graph` 目錄標記為一個 Python 套件 這個 `__init__.py` 檔案將 `graph` 目錄標記為一個 Python 套件
@ -8,7 +8,7 @@
而不需要知道每個類別所在的具體模組檔案 而不需要知道每個類別所在的具體模組檔案
匯出的類別包括 匯出的類別包括
- TradingAgentsGraph: 整個交易代理圖的主要協調器 - TradingAgentsXGraph: 整個交易代理圖的主要協調器
- ConditionalLogic: 處理圖中條件分支邏輯的類別 - ConditionalLogic: 處理圖中條件分支邏輯的類別
- GraphSetup: 負責設定和建立圖結構的類別 - GraphSetup: 負責設定和建立圖結構的類別
- Propagator: 管理狀態在圖中節點之間傳播的類別 - Propagator: 管理狀態在圖中節點之間傳播的類別
@ -17,7 +17,7 @@
""" """
# 從同層級的模組中匯入類別 # 從同層級的模組中匯入類別
from .trading_graph import TradingAgentsGraph from .trading_graph import TradingAgentsXGraph
from .conditional_logic import ConditionalLogic from .conditional_logic import ConditionalLogic
from .setup import GraphSetup from .setup import GraphSetup
from .propagation import Propagator from .propagation import Propagator
@ -27,7 +27,7 @@ from .signal_processing import SignalProcessor
# `__all__` 變數定義了當 `from tradingagents.graph import *` 被執行時, # `__all__` 變數定義了當 `from tradingagents.graph import *` 被執行時,
# 哪些名稱會被匯入。這是一種控制命名空間的良好實踐。 # 哪些名稱會被匯入。這是一種控制命名空間的良好實踐。
__all__ = [ __all__ = [
"TradingAgentsGraph", "TradingAgentsXGraph",
"ConditionalLogic", "ConditionalLogic",
"GraphSetup", "GraphSetup",
"Propagator", "Propagator",

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# TradingAgents/graph/conditional_logic.py # TradingAgentsX/graph/conditional_logic.py
from tradingagents.agents.utils.agent_states import AgentState from tradingagents.agents.utils.agent_states import AgentState

View File

@ -1,12 +1,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# TradingAgents/graph/propagation.py # TradingAgentsX/graph/propagation.py
from typing import Dict, Any from typing import Dict, Any
import json
from tradingagents.agents.utils.agent_states import ( from tradingagents.agents.utils.agent_states import (
AgentState, AgentState,
InvestDebateState, InvestDebateState,
RiskDebateState, RiskDebateState,
) )
from tradingagents.dataflows.interface import route_to_vendor
class Propagator: class Propagator:
@ -38,9 +41,28 @@ class Propagator:
Returns: Returns:
Dict[str, Any]: 初始狀態的字典 Dict[str, Any]: 初始狀態的字典
""" """
# 獲取真實公司名稱從Alpha Vantage獲取公司概況
ticker = company_name # company_name實際上是ticker
actual_company_name = ticker # 預設值為ticker
try:
# 嘗試從fundamentals數據中獲取公司全名
fundamentals_data = route_to_vendor("get_fundamentals", ticker, trade_date)
if fundamentals_data:
# 解析JSON數據
data = json.loads(fundamentals_data) if isinstance(fundamentals_data, str) else fundamentals_data
if isinstance(data, dict) and "Name" in data:
actual_company_name = data["Name"]
print(f"成功獲取公司名稱:{ticker} -> {actual_company_name}")
else:
print(f"警告無法從fundamentals數據中提取公司名稱使用ticker: {ticker}")
except Exception as e:
print(f"警告:獲取公司名稱時發生錯誤:{e}使用ticker: {ticker}")
return { return {
"messages": [("human", company_name)], # 初始訊息,觸發第一個代理 "messages": [("human", ticker)], # 初始訊息,觸發第一個代理
"company_of_interest": company_name, # 感興趣的公司 "company_of_interest": ticker, # 股票代碼
"company_name": actual_company_name, # 真實公司全名
"trade_date": str(trade_date), # 交易日期 "trade_date": str(trade_date), # 交易日期
"investment_debate_state": InvestDebateState( "investment_debate_state": InvestDebateState(
{"history": "", "current_response": "", "count": 0} {"history": "", "current_response": "", "count": 0}
@ -60,6 +82,7 @@ class Propagator:
"news_report": "", # 新聞報告的初始值 "news_report": "", # 新聞報告的初始值
} }
def get_graph_args(self) -> Dict[str, Any]: def get_graph_args(self) -> Dict[str, Any]:
""" """
獲取圖呼叫的參數 獲取圖呼叫的參數

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# TradingAgents/graph/reflection.py # TradingAgentsX/graph/reflection.py
from typing import Dict, Any from typing import Dict, Any
from langchain_openai import ChatOpenAI from langchain_openai import ChatOpenAI

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# TradingAgents/graph/setup.py # TradingAgentsX/graph/setup.py
from typing import Dict, Any from typing import Dict, Any
from langchain_openai import ChatOpenAI from langchain_openai import ChatOpenAI

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# TradingAgents/graph/signal_processing.py # TradingAgentsX/graph/signal_processing.py
from langchain_openai import ChatOpenAI from langchain_openai import ChatOpenAI

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# TradingAgents/graph/trading_graph.py # TradingAgentsX/graph/trading_graph.py
import os import os
from pathlib import Path from pathlib import Path
@ -48,7 +48,7 @@ from .reflection import Reflector
from .signal_processing import SignalProcessor from .signal_processing import SignalProcessor
class TradingAgentsGraph: class TradingAgentsXGraph:
""" """
協調交易代理框架的主要類別 協調交易代理框架的主要類別
這個類別整合了所有組件包括 LLM記憶體工具和圖的邏輯 這個類別整合了所有組件包括 LLM記憶體工具和圖的邏輯
@ -271,11 +271,11 @@ class TradingAgentsGraph:
} }
# 儲存到檔案 # 儲存到檔案
directory = Path(f"eval_results/{self.ticker}/TradingAgentsStrategy_logs/") directory = Path(f"eval_results/{self.ticker}/TradingAgentsXStrategy_logs/")
directory.mkdir(parents=True, exist_ok=True) directory.mkdir(parents=True, exist_ok=True)
with open( with open(
f"eval_results/{self.ticker}/TradingAgentsStrategy_logs/full_states_log_{trade_date}.json", f"eval_results/{self.ticker}/TradingAgentsXStrategy_logs/full_states_log_{trade_date}.json",
"w", "w",
) as f: ) as f:
json.dump(self.log_states_dict, f, indent=4) json.dump(self.log_states_dict, f, indent=4)

View File

@ -0,0 +1,89 @@
"""
Toon格式轉換工具
將JSON數據轉換為toon格式以減少token消耗
"""
from toon_format import encode, decode, estimate_savings, compare_formats
import json
from typing import Union, Dict, List
def convert_json_to_toon(json_data: Union[str, dict, list]) -> str:
"""
將JSON數據轉換為toon格式
Args:
json_data: JSON字符串或Python字典/列表
Returns:
toon格式的字符串
"""
if isinstance(json_data, str):
try:
data = json.loads(json_data)
except json.JSONDecodeError:
# 如果無法解析,直接返回原始字符串
return json_data
else:
data = json_data
try:
return encode(data)
except Exception as e:
print(f"警告toon轉換失敗{e},返回原始數據")
return json.dumps(data, ensure_ascii=False) if not isinstance(json_data, str) else json_data
def convert_toon_to_json(toon_data: str) -> dict:
"""
將toon數據轉換回JSON/Python字典
Args:
toon_data: toon格式的字符串
Returns:
Python字典
"""
try:
return decode(toon_data)
except Exception as e:
print(f"警告toon解碼失敗{e}")
# 嘗試作為JSON解析
try:
return json.loads(toon_data)
except:
return {"error": "無法解析數據", "原始數據": toon_data}
def show_toon_savings(data: Union[dict, list]) -> Dict[str, float]:
"""
顯示使用toon格式的token節省情況
Args:
data: Python字典或列表
Returns:
包含節省百分比和token數的字典
"""
try:
result = estimate_savings(data)
print(f"Token節省: {result['savings_percent']:.1f}%")
print(f"JSON tokens: {result['json_tokens']}")
print(f"Toon tokens: {result['toon_tokens']}")
return result
except Exception as e:
print(f"警告:無法計算節省:{e}")
return {"savings_percent": 0, "json_tokens": 0, "toon_tokens": 0}
def compare_format_display(data: Union[dict, list]) -> None:
"""
顯示JSON與toon格式的直觀比較
Args:
data: Python字典或列表
"""
try:
print(compare_formats(data))
except Exception as e:
print(f"警告:無法顯示格式比較:{e}")