This commit is contained in:
parent
15babc2bea
commit
8d679007bf
30
README.md
30
README.md
|
|
@ -1,10 +1,10 @@
|
|||
# TradingAgents - 多代理交易分析系統
|
||||
# TradingAgentsX - 多代理交易分析系統
|
||||
|
||||
<div align="center">
|
||||
|
||||
**基於 LangGraph 的智能股票交易分析平台,結合多個 AI 代理進行協作決策**
|
||||
|
||||
[](https://github.com/MarkLo127/TradingAgents)
|
||||
[](https://github.com/MarkLo127/TradingAgentsX)
|
||||
[](https://www.python.org/)
|
||||
[](https://nextjs.org/)
|
||||
[](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 模型支援
|
||||
|
||||
TradingAgents 支援業界領先的多家 LLM 提供商,並為每個模型配置**獨立的 API Key 和 Base URL**,實現最大靈活性。
|
||||
TradingAgentsX 支援業界領先的多家 LLM 提供商,並為每個模型配置**獨立的 API Key 和 Base URL**,實現最大靈活性。
|
||||
|
||||
### 📋 支援的 LLM 提供商矩陣
|
||||
|
||||
|
|
@ -96,12 +96,12 @@ TradingAgents 支援業界領先的多家 LLM 提供商,並為每個模型配
|
|||
|
||||
## 🏗️ 系統架構
|
||||
|
||||
TradingAgents 採用前後端分離架構,後端使用 FastAPI 提供 RESTful API,前端使用 Next.js 打造現代化的使用者介面。
|
||||
TradingAgentsX 採用前後端分離架構,後端使用 FastAPI 提供 RESTful API,前端使用 Next.js 打造現代化的使用者介面。
|
||||
|
||||
### 📂 專案結構概覽
|
||||
|
||||
```
|
||||
TradingAgents/
|
||||
TradingAgentsX/
|
||||
├── backend/ # FastAPI 後端服務
|
||||
│ ├── __main__.py # 後端應用入口
|
||||
│ ├── requirements.txt # Python 依賴列表
|
||||
|
|
@ -116,7 +116,7 @@ TradingAgents/
|
|||
│ ├── models/ # 資料模型
|
||||
│ │ └── schemas.py # Pydantic 資料結構
|
||||
│ └── services/ # 業務邏輯層
|
||||
│ ├── trading_service.py # TradingAgents 核心整合
|
||||
│ ├── trading_service.py # TradingAgentsX 核心整合
|
||||
│ └── task_manager.py # 異步任務管理
|
||||
|
||||
├── frontend/ # Next.js 前端應用
|
||||
|
|
@ -225,8 +225,8 @@ TradingAgents/
|
|||
#### 1️⃣ 克隆專案
|
||||
|
||||
```bash
|
||||
git clone https://github.com/MarkLo127/TradingAgents.git
|
||||
cd TradingAgents
|
||||
git clone https://github.com/MarkLo127/TradingAgentsX.git
|
||||
cd TradingAgentsX
|
||||
```
|
||||
|
||||
#### 2️⃣ 後端設置
|
||||
|
|
@ -252,7 +252,7 @@ tradingagents\Scripts\activate # Windows
|
|||
##### 2.2 安裝 Python 依賴
|
||||
|
||||
```bash
|
||||
# 安裝 TradingAgents 核心套件
|
||||
# 安裝 TradingAgentsX 核心套件
|
||||
pip install -e .
|
||||
|
||||
# 安裝後端 API 依賴
|
||||
|
|
@ -535,7 +535,7 @@ docker compose down -v
|
|||
|
||||
### 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 的核心功能與多代理協作工作流程
|
||||
|
||||

|
||||
|
||||
|
|
@ -814,7 +814,7 @@ TradingAgents 模擬真實交易公司的組織架構,每個代理都有其專
|
|||
|
||||
### 特別感謝
|
||||
|
||||
本專案基於 [TauricResearch/TradingAgents](https://github.com/TauricResearch/TradingAgents) 的原始專案進行改進和擴展。衷心感謝原作者創建了如此優秀的多代理交易分析框架,為我們提供了堅實的基礎。
|
||||
本專案基於 [TauricResearch/TradingAgentsX](https://github.com/TauricResearch/TradingAgentsX) 的原始專案進行改進和擴展。衷心感謝原作者創建了如此優秀的多代理交易分析框架,為我們提供了堅實的基礎。
|
||||
|
||||
### 使用的開源專案
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ def main():
|
|||
port = int(os.getenv("BACKEND_PORT", "8000"))
|
||||
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"🔌 Port: {port}")
|
||||
print(f"🔄 Reload: {reload}")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
API route definitions for TradingAgents Backend
|
||||
API route definitions for TradingAgentsX Backend
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from datetime import datetime
|
||||
|
|
@ -24,7 +24,7 @@ from backend.app.core.config import settings
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Create API router
|
||||
router = APIRouter(prefix="/api", tags=["TradingAgents"])
|
||||
router = APIRouter(prefix="/api", tags=["TradingAgentsX"])
|
||||
|
||||
|
||||
@router.get("/health", response_model=HealthResponse)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
Configuration management for TradingAgents Backend API
|
||||
Configuration management for TradingAgentsX Backend API
|
||||
"""
|
||||
from pydantic_settings import BaseSettings
|
||||
from typing import Optional
|
||||
|
|
@ -11,7 +11,7 @@ class Settings(BaseSettings):
|
|||
"""Application settings loaded from environment variables"""
|
||||
|
||||
# Application settings
|
||||
app_name: str = "TradingAgents API"
|
||||
app_name: str = "TradingAgentsX API"
|
||||
app_version: str = "1.0.0"
|
||||
debug: bool = Field(default=False)
|
||||
results_dir: str = Field(default="./results")
|
||||
|
|
@ -29,7 +29,7 @@ class Settings(BaseSettings):
|
|||
"https://*.railway.app", # Railway deployments
|
||||
]
|
||||
|
||||
# TradingAgents Configuration
|
||||
# TradingAgentsX Configuration
|
||||
results_dir: str = "./results"
|
||||
max_debate_rounds: int = 1
|
||||
max_risk_discuss_rounds: int = 1
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
FastAPI application entry point for TradingAgents Backend
|
||||
FastAPI application entry point for TradingAgentsX Backend
|
||||
"""
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import JSONResponse
|
||||
|
|
@ -38,7 +38,7 @@ app.include_router(router)
|
|||
async def root():
|
||||
"""Root endpoint"""
|
||||
return {
|
||||
"message": "Welcome to TradingAgents API",
|
||||
"message": "Welcome to TradingAgentsX API",
|
||||
"version": settings.app_version,
|
||||
"docs": "/docs",
|
||||
"health": "/api/health",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
TradingAgents service integration
|
||||
TradingAgentsX service integration
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
|
|
@ -10,7 +10,7 @@ import logging
|
|||
# Add parent directory to path to import tradingagents
|
||||
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 backend.app.core.config import settings
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
class TradingService:
|
||||
"""Service class for interacting with TradingAgents"""
|
||||
"""Service class for interacting with TradingAgentsX"""
|
||||
|
||||
def __init__(self):
|
||||
self.default_config = DEFAULT_CONFIG.copy()
|
||||
|
|
@ -29,7 +29,7 @@ class TradingService:
|
|||
deep_think_llm: str = "gpt-5-mini-2025-08-07",
|
||||
quick_think_llm: str = "gpt-5-mini-2025-08-07",
|
||||
) -> Dict[str, Any]:
|
||||
"""Create configuration for TradingAgents"""
|
||||
"""Create configuration for TradingAgentsX"""
|
||||
config = self.default_config.copy()
|
||||
config["max_debate_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
|
||||
|
||||
# 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)
|
||||
|
||||
# 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_api_key"] = embedding_api_key if embedding_api_key else openai_api_key
|
||||
|
||||
# Initialize TradingAgents graph
|
||||
graph = TradingAgentsGraph(analysts, config=config, debug=True)
|
||||
# Initialize TradingAgentsX graph
|
||||
graph = TradingAgentsXGraph(analysts, config=config, debug=True)
|
||||
|
||||
# Run analysis
|
||||
logger.info(f"Running analysis for {ticker}")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Backend requirements for FastAPI TradingAgents API
|
||||
# Backend requirements for FastAPI TradingAgentsX API
|
||||
|
||||
# Core Framework
|
||||
fastapi>=0.104.0
|
||||
|
|
@ -12,7 +12,7 @@ python-multipart==0.0.6
|
|||
# Environment and configuration
|
||||
python-dotenv==1.0.0
|
||||
|
||||
# Existing TradingAgents dependencies
|
||||
# Existing TradingAgentsX dependencies
|
||||
typing-extensions
|
||||
langchain-openai
|
||||
langchain-experimental
|
||||
|
|
@ -41,3 +41,6 @@ tenacity>=8.2.0
|
|||
# PDF and document generation
|
||||
reportlab>=4.0.0
|
||||
markdown>=3.5.0
|
||||
|
||||
# Toon format for token optimization
|
||||
git+https://github.com/toon-format/toon-python.git
|
||||
|
|
|
|||
16
cli/main.py
16
cli/main.py
|
|
@ -25,7 +25,7 @@ from rich.align import Align
|
|||
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 cli.models import AnalystType
|
||||
from cli.utils import *
|
||||
|
|
@ -35,8 +35,8 @@ console = Console()
|
|||
|
||||
# 建立 Typer 應用程式
|
||||
app = typer.Typer(
|
||||
name="TradingAgents",
|
||||
help="TradingAgents CLI:多代理 LLM 金融交易框架",
|
||||
name="TradingAgentsX",
|
||||
help="TradingAgentsX CLI:多代理 LLM 金融交易框架",
|
||||
add_completion=True, # 啟用 shell 自動補全
|
||||
)
|
||||
|
||||
|
|
@ -212,9 +212,9 @@ def update_display(layout, spinner_text=None):
|
|||
# 包含歡迎訊息的頁首
|
||||
layout["header"].update(
|
||||
Panel(
|
||||
"[bold green]歡迎使用 TradingAgents CLI[/bold green]\n"
|
||||
"[bold green]歡迎使用 TradingAgentsX CLI[/bold green]\n"
|
||||
"[dim]© [Tauric Research](https://github.com/TauricResearch)[/dim]",
|
||||
title="歡迎使用 TradingAgents",
|
||||
title="歡迎使用 TradingAgentsX",
|
||||
border_style="green",
|
||||
padding=(1, 2),
|
||||
expand=True,
|
||||
|
|
@ -421,7 +421,7 @@ def get_user_selections():
|
|||
|
||||
# 建立歡迎框內容
|
||||
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 += "I. 分析師團隊 → II. 研究團隊 → III. 交易員 → IV. 風險管理 → V. 投資組合管理\n\n"
|
||||
welcome_content += (
|
||||
|
|
@ -433,7 +433,7 @@ def get_user_selections():
|
|||
welcome_content,
|
||||
border_style="green",
|
||||
padding=(1, 2),
|
||||
title="歡迎使用 TradingAgents",
|
||||
title="歡迎使用 TradingAgentsX",
|
||||
subtitle="多代理 LLM 金融交易框架",
|
||||
)
|
||||
console.print(Align.center(welcome_box))
|
||||
|
|
@ -822,7 +822,7 @@ def run_analysis():
|
|||
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
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { ThemeProvider } from "@/components/theme/ThemeProvider";
|
|||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "TradingAgents - 多代理 LLM 金融交易",
|
||||
title: "TradingAgentsX - 多代理 LLM 金融交易",
|
||||
description: "由 AI 驅動的多代理 LLM 金融交易框架",
|
||||
};
|
||||
|
||||
|
|
@ -25,9 +25,7 @@ export default function RootLayout({
|
|||
<AnalysisProvider>
|
||||
<div className="flex flex-col min-h-screen">
|
||||
<Header />
|
||||
<main className="flex-1">
|
||||
{children}
|
||||
</main>
|
||||
<main className="flex-1">{children}</main>
|
||||
<Footer />
|
||||
</div>
|
||||
</AnalysisProvider>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import Link from "next/link";
|
||||
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() {
|
||||
return (
|
||||
|
|
@ -8,19 +14,22 @@ export default function HomePage() {
|
|||
{/* Hero Section */}
|
||||
<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">
|
||||
TradingAgents
|
||||
TradingAgentsX
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600 dark:text-gray-400 mb-8 max-w-2xl mx-auto">
|
||||
多代理 LLM 金融交易框架
|
||||
</p>
|
||||
<div className="flex gap-4 justify-center">
|
||||
<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>
|
||||
</Link>
|
||||
<a
|
||||
href="https://github.com/MarkLo127/TradingAgents"
|
||||
href="https://github.com/MarkLo127/TradingAgentsX"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
|
|
@ -60,7 +69,7 @@ export default function HomePage() {
|
|||
<CardHeader>
|
||||
<CardTitle>運作方式</CardTitle>
|
||||
<CardDescription>
|
||||
TradingAgents 模擬真實交易公司,配備專業化的 LLM 代理
|
||||
TradingAgentsX 模擬真實交易公司,配備專業化的 LLM 代理
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<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 (
|
||||
<Card className="hover:shadow-lg transition-shadow">
|
||||
<CardHeader>
|
||||
|
|
@ -105,13 +122,23 @@ function FeatureCard({ title, description, icon }: { title: string; description:
|
|||
<CardTitle className="text-lg">{title}</CardTitle>
|
||||
</CardHeader>
|
||||
<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>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
function WorkflowStep({ number, title, description }: { number: number; title: string; description: string }) {
|
||||
function WorkflowStep({
|
||||
number,
|
||||
title,
|
||||
description,
|
||||
}: {
|
||||
number: number;
|
||||
title: string;
|
||||
description: string;
|
||||
}) {
|
||||
return (
|
||||
<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">
|
||||
|
|
@ -119,7 +146,9 @@ function WorkflowStep({ number, title, description }: { number: number; title: s
|
|||
</div>
|
||||
<div>
|
||||
<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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ export function Footer() {
|
|||
<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="text-sm text-gray-600 dark:text-gray-400">
|
||||
© 2025 TradingAgents. 技術支援:{" "}
|
||||
© 2025 TradingAgentsX. 技術支援:{" "}
|
||||
<a
|
||||
href="https://github.com/MarkLo127/TradingAgents"
|
||||
href="https://github.com/MarkLo127/TradingAgentsX"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-600 hover:underline"
|
||||
|
|
@ -19,7 +19,7 @@ export function Footer() {
|
|||
</div>
|
||||
<div className="flex gap-4 text-sm">
|
||||
<a
|
||||
href="https://github.com/MarkLo127/TradingAgents"
|
||||
href="https://github.com/MarkLo127/TradingAgentsX"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-gray-600 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export function Header() {
|
|||
<div className="container mx-auto px-4 py-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<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">
|
||||
多代理 LLM 金融交易框架
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* API client for TradingAgents backend
|
||||
* API client for TradingAgentsX backend
|
||||
*/
|
||||
import axios from "axios";
|
||||
import type {
|
||||
|
|
@ -50,7 +50,9 @@ export const api = {
|
|||
* Get task status
|
||||
*/
|
||||
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;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* TypeScript type definitions for TradingAgents API
|
||||
* TypeScript type definitions for TradingAgentsX API
|
||||
*/
|
||||
|
||||
export interface AnalysisRequest {
|
||||
|
|
@ -9,7 +9,7 @@ export interface AnalysisRequest {
|
|||
research_depth?: number;
|
||||
quick_think_llm?: string;
|
||||
deep_think_llm?: string;
|
||||
|
||||
|
||||
// API Configuration
|
||||
openai_api_key?: string;
|
||||
openai_base_url?: string;
|
||||
|
|
@ -118,4 +118,3 @@ export interface TaskStatusResponse {
|
|||
error?: string;
|
||||
completed_at?: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
4
main.py
4
main.py
|
|
@ -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 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")
|
||||
|
|
|
|||
|
|
@ -24,3 +24,4 @@ rich
|
|||
questionary
|
||||
langchain_anthropic
|
||||
langchain-google-genai
|
||||
git+https://github.com/toon-format/toon-python.git
|
||||
|
|
|
|||
4
setup.py
4
setup.py
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
TradingAgents 套件的安裝腳本。
|
||||
TradingAgentsX 套件的安裝腳本。
|
||||
|
||||
這個檔案包含了套件的元數據,例如名稱、版本、依賴項等,
|
||||
setuptools 會使用這些資訊來建構和安裝套件。
|
||||
|
|
@ -18,7 +18,7 @@ setup(
|
|||
# 套件的簡短描述
|
||||
description="多代理 LLM 金融交易框架",
|
||||
# 作者名稱
|
||||
author="TradingAgents 團隊",
|
||||
author="TradingAgentsX 團隊",
|
||||
# 作者的電子郵件地址
|
||||
author_email="yijia.xiao@cs.ucla.edu",
|
||||
# 專案的首頁 URL
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ def create_fundamentals_analyst(llm):
|
|||
"""
|
||||
current_date = state["trade_date"]
|
||||
ticker = state["company_of_interest"]
|
||||
company_name = state["company_of_interest"]
|
||||
company_name = state.get("company_name", ticker) # 使用真實公司名稱,fallback到ticker
|
||||
|
||||
tools = [
|
||||
get_fundamentals,
|
||||
|
|
@ -37,143 +37,39 @@ def create_fundamentals_analyst(llm):
|
|||
]
|
||||
|
||||
system_message = (
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深企業價值評估與財務分析專家,擁有以下專業背景:
|
||||
• CPA (註冊會計師) + CFA (特許金融分析師) 雙證照
|
||||
• MBA財務管理學位,專攻企業估值與財報分析
|
||||
• 15年以上投資銀行股權研究與盡職調查經驗
|
||||
• 精通DCF模型、相對估值法、經濟附加值(EVA)分析
|
||||
• 專長領域:財務報表深度解讀、會計品質評估、盈利預測模型
|
||||
• 熟練運用杜邦分析、現金流折現、敏感性分析等專業工具
|
||||
您是一位財務分析師,為業餘投資者提供實用的基本面分析。
|
||||
|
||||
【分析方法論】
|
||||
您採用嚴謹的基本面分析框架,聚焦三大財務報表與關鍵財務比率:
|
||||
【分析要點】
|
||||
1. **公司概況**:簡述核心業務和競爭優勢
|
||||
2. **財務健康度**:評估獲利ability、資產負債和現金流
|
||||
3. **關鍵指標**:重點分析3-5個最重要的財務比率
|
||||
- 建議:ROE、P/E、負債比率、現金流、營收成長
|
||||
4. **估值判斷**:當前價格是高估/合理/低估
|
||||
|
||||
**1. 財務報表分析體系**
|
||||
【技術操作】
|
||||
• 使用 get_fundamentals 獲取公司概況
|
||||
• 使用 get_income_statement、get_balance_sheet、get_cashflow 獲取財務數據
|
||||
• 基於數據進行分析
|
||||
|
||||
📊 **損益表分析** (Income Statement)
|
||||
• 營收成長性:YoY/QoQ成長率、有機成長vs併購成長
|
||||
• 獲利能力:毛利率、營業利益率、淨利率的趨勢
|
||||
• 費用結構:SG\u0026A占比、R\u0026D投入強度
|
||||
• 盈餘品質:非經常性損益、會計調整識別
|
||||
【報告要求】
|
||||
**長度**:500-800字(必須精簡)
|
||||
**結構**:
|
||||
1. 執行摘要(100字)
|
||||
2. 公司業務概述(100-150字)
|
||||
3. 財務指標分析(300-400字)
|
||||
4. 估值與投資建議(100-150字)
|
||||
5. 關鍵數據表格(必須包含)
|
||||
|
||||
💰 **資產負債表分析** (Balance Sheet)
|
||||
• 資產品質:流動資產組成、應收帳款週轉、存貨管理
|
||||
• 資本結構:負債權益比、淨負債/EBITDA倍數
|
||||
• 流動性分析:流動比率、速動比率、現金比率
|
||||
• 財務槓桿:利息保障倍數、債務到期結構
|
||||
**注意**:
|
||||
- 使用簡潔語言,避免複雜的財務術語
|
||||
- 重點突出,不要過度細節
|
||||
- 必須包含關鍵財務比率表格
|
||||
|
||||
💵 **現金流量表分析** (Cash Flow Statement)
|
||||
• 營運現金流:FCF轉換率、營運資金變化
|
||||
• 投資現金流:資本支出強度、併購活動
|
||||
• 融資現金流:股利政策、股票回購、債務管理
|
||||
• 現金創造力:OCF vs 淨利的對照(盈餘品質)
|
||||
|
||||
**2. 關鍵財務指標評估**
|
||||
|
||||
📈 **獲利能力指標**
|
||||
• ROE (股東權益報酬率)、ROA (資產報酬率)、ROIC (投入資本回報率)
|
||||
• 杜邦分析:拆解ROE為淨利率×資產週轉率×財務槓桿
|
||||
• 毛利率與營業利益率的趨勢與同業比較
|
||||
|
||||
⚡ **效率指標 **
|
||||
• 應收帳款週轉天數 (DSO)、存貨週轉天數 (DI)、應付帳款天數 (DPO)
|
||||
• 現金轉換週期 (Cash Conversion Cycle)
|
||||
• 資產週轉率、固定資產效率
|
||||
|
||||
💪 **財務穩健度**
|
||||
• 流動比率、速動比率、現金比率
|
||||
• 負債權益比、淨負債/EBITDA
|
||||
• 利息保障倍數、債務覆蓋率
|
||||
|
||||
📊 **價值評估指標**
|
||||
• P/E (本益比)、P/B (股價淨值比)、P/S (市銷率)
|
||||
• EV/EBITDA、EV/Sales企業價值倍數
|
||||
• PEG比率(考慮成長的本益比)
|
||||
|
||||
**3. 估值方法應用**
|
||||
|
||||
💡 **絕對估值法**
|
||||
• DCF折現現金流模型:WACC計算、終值估算、敏感性分析
|
||||
• DD模型 (股利折現模型):適用穩定配息公司
|
||||
• EVA經濟附加值分析
|
||||
|
||||
📊 **相對估值法**
|
||||
• 同業比較:P/E、P/B、EV/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淨利的比較(會計盈餘品質)
|
||||
- 資本支出需求與投資回報
|
||||
- 現金分配政策:股利、回購、再投資
|
||||
|
||||
**六、關鍵財務比率總表**
|
||||
整理ROE、ROA、負債比率、流動比率、現金流指標等
|
||||
|
||||
**七、估值分析**
|
||||
- 絕對估值:DCF模型假設與合理股價區間
|
||||
- 相對估值:P/E、P/B、EV/EBITDA與同業/歷史比較
|
||||
- 估值合理性結論:當前價格的吸引力
|
||||
|
||||
**八、風險因素識別**
|
||||
- 財務風險:高槓桿、流動性不足、盈餘品質疑慮
|
||||
- 營運風險:客戶集中度、供應鏈依賴
|
||||
- 會計風險:可疑的會計政策、頻繁調整
|
||||
|
||||
**九、投資建議**
|
||||
- 基於基本面的價值判斷
|
||||
- 目標價與上檔/下檔空間
|
||||
- 適合的投資時間框架
|
||||
|
||||
**十、財務數據彙整表**(Markdown)
|
||||
| 指標 | 最近年度 | 前一年度 | 產業中位數 | 評級 |
|
||||
|------|---------|---------|-----------|------|
|
||||
|
||||
【專業要求】
|
||||
• 數據驅動:所有結論必須有財務數據支撐
|
||||
• 同業對標:提供產業平均值或主要競爭對手比較
|
||||
• 趨勢分析:不只看單期數據,關注3-5年趨勢
|
||||
• 會計警訊:識別激進會計、盈餘管理的紅旗
|
||||
• 估值合理性:明確說明假設前提與敏感性
|
||||
• 風險披露:誠實指出財務報表中的不確定性與風險
|
||||
|
||||
請以頂級投資銀行股權研究報告的專業水準,提供深度且可信的基本面分析。"""
|
||||
+ " 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點,使其井然有序且易於閱讀。"
|
||||
請以實用為導向,提供清晰易懂的基本面分析。"""
|
||||
+ " 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點。"
|
||||
+ " 使用可用的工具:`get_fundamentals` 用於全面的公司分析,`get_balance_sheet`、`get_cashflow` 和 `get_income_statement` 用於特定的財務報表。"
|
||||
)
|
||||
|
||||
|
|
@ -187,7 +83,7 @@ def create_fundamentals_analyst(llm):
|
|||
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
|
||||
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
|
||||
" 您可以使用以下工具:{tool_names}。\n{system_message}"
|
||||
"供您參考,目前日期是 {current_date}。我們想關注的公司是 {ticker}",
|
||||
"供您參考,目前日期是 {current_date}。我們想關注的公司是 {company_name} (股票代碼:{ticker})",
|
||||
),
|
||||
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(current_date=current_date)
|
||||
prompt = prompt.partial(ticker=ticker)
|
||||
prompt = prompt.partial(company_name=company_name)
|
||||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
report = ""
|
||||
# 報告邏輯修復:只在LLM最終回應時保存報告
|
||||
report = state.get("fundamentals_report", "") # 保持現有報告
|
||||
|
||||
if len(result.tool_calls) == 0:
|
||||
# 沒有工具調用,這是最終的分析報告
|
||||
report = result.content
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ def create_market_analyst(llm):
|
|||
"""
|
||||
current_date = state["trade_date"]
|
||||
ticker = state["company_of_interest"]
|
||||
company_name = state["company_of_interest"]
|
||||
company_name = state.get("company_name", ticker) # 使用真實公司名稱,fallback到ticker
|
||||
|
||||
tools = [
|
||||
get_stock_data,
|
||||
|
|
@ -36,136 +36,39 @@ def create_market_analyst(llm):
|
|||
]
|
||||
|
||||
system_message = (
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深量化技術分析專家,擁有以下專業資格:
|
||||
• CFA (特許金融分析師) 與 CMT (特許市場技術分析師) 雙證照
|
||||
• 15年以上全球金融市場技術分析經驗
|
||||
• 曾任職於頂級投資銀行量化交易部門
|
||||
• 精通多重時間框架分析與演算法交易策略
|
||||
• 專長於趨勢識別、動能分析與風險量化評估
|
||||
您是一位技術分析師,為業餘投資者提供實用的市場分析。
|
||||
|
||||
【分析方法論】
|
||||
您採用系統化的量化技術分析框架:
|
||||
【分析要點】
|
||||
1. **趨勢判斷**:明確判斷當前趨勢(多頭/空頭/盤整)
|
||||
2. **技術指標**:選擇3-5個最重要的指標分析
|
||||
- 建議指標:50日/200日均線、MACD、RSI、布林帶、ATR
|
||||
3. **關鍵價位**:標示主要支撐和阻力位
|
||||
4. **交易建議**:給出明確的進場、出場和止損建議
|
||||
|
||||
1. **指標選擇策略**:從以下類別中選擇最多 **8個** 互補且非冗餘的技術指標
|
||||
【技術操作】
|
||||
• 使用 get_stock_data 獲取價格數據
|
||||
• 使用 get_indicators 計算所需指標
|
||||
• 基於數據進行分析
|
||||
|
||||
📊 **移動平均線系統**(趨勢確認):
|
||||
• close_50_sma:50日簡單移動平均線(中期趨勢指標)
|
||||
- 應用:識別中期趨勢方向,設定動態支撐/阻力位
|
||||
- 技術要點:滯後性指標,需配合動能指標確認突破有效性
|
||||
- 交易信號:價格穿越產生趨勢轉折訊號
|
||||
【報告要求】
|
||||
**長度**:500-800字(必須精簡)
|
||||
**結構**:
|
||||
1. 執行摘要(100字)
|
||||
2. 趨勢與指標分析(300-400字)
|
||||
3. 支撐阻力位(100字)
|
||||
4. 交易建議(100-200字)
|
||||
5. 數據表格(必須包含)
|
||||
|
||||
• close_200_sma:200日簡單移動平均線(長期趨勢基準)
|
||||
- 應用:確認主要趨勢,識別黃金交叉(50MA上穿200MA)/死亡交叉(50MA下穿200MA)
|
||||
- 技術要點:市場重要心理關卡,機構投資人關注重點
|
||||
- 交易信號:長期趨勢判斷與戰略配置依據
|
||||
**注意**:
|
||||
- 使用簡潔語言,避免過度專業術語
|
||||
- 重點突出,不要冗長描述
|
||||
- 必須包含關鍵數據表格總結
|
||||
|
||||
• close_10_ema:10日指數移動平均線(短期動能指標)
|
||||
- 應用:捕捉短期價格動能與快速反轉機會
|
||||
- 技術要點:對價格變動敏感度高,震盪市場易產生假訊號
|
||||
- 交易信號:配合長期均線過濾,提高進場時機精確度
|
||||
|
||||
📈 **MACD動能分析系統**(動能與趨勢強度):
|
||||
• macd:MACD主線(12EMA-26EMA差值)
|
||||
- 應用:量化價格動能變化,識別趨勢加速或衰竭
|
||||
- 技術要點:結合背離分析預測潛在反轉
|
||||
- 交易信號:零軸穿越確認趨勢方向,背離預警趨勢轉折
|
||||
|
||||
• macds:MACD訊號線(MACD的9日EMA平滑線)
|
||||
- 應用:MACD與訊號線交叉產生買賣訊號
|
||||
- 技術要點:需配合價格行為與成交量確認
|
||||
- 交易信號:向上交叉為買進訊號,向下交叉為賣出訊號
|
||||
|
||||
• macdh:MACD柱狀圖(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 表格,以整理報告中的要點,使其井然有序且易於閱讀。"""
|
||||
請以實用為導向,提供清晰易懂的技術分析。"""
|
||||
+ """ 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點。"""
|
||||
)
|
||||
|
||||
prompt = ChatPromptTemplate.from_messages(
|
||||
|
|
@ -178,7 +81,7 @@ def create_market_analyst(llm):
|
|||
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
|
||||
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
|
||||
" 您可以使用以下工具:{tool_names}。\n{system_message}"
|
||||
"供您參考,目前日期是 {current_date}。我們想關注的公司是 {ticker}",
|
||||
"供您參考,目前日期是 {current_date}。我們想關注的公司是 {company_name} (股票代碼:{ticker})",
|
||||
),
|
||||
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(current_date=current_date)
|
||||
prompt = prompt.partial(ticker=ticker)
|
||||
prompt = prompt.partial(company_name=company_name)
|
||||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
report = ""
|
||||
|
||||
# 報告邏輯修復:只在LLM最終回應時保存報告
|
||||
# 當LLM調用工具時(tool_calls不為空),不更新報告
|
||||
# 當LLM返回最終分析時(tool_calls為空),保存完整報告
|
||||
report = state.get("market_report", "") # 保持現有報告
|
||||
|
||||
if len(result.tool_calls) == 0:
|
||||
# 沒有工具調用,這是最終的分析報告
|
||||
report = result.content
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -34,22 +34,9 @@ def create_news_analyst(llm):
|
|||
]
|
||||
|
||||
system_message = (
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深新聞分析與事件驅動投資專家,擁有以下專業背景:
|
||||
• 新聞學碩士 + CFA (特許金融分析師) 雙重資格
|
||||
• 12年以上財經新聞分析與事件驅動交易研究經驗
|
||||
• 曾任職於彭博社(Bloomberg)、路透社(Reuters)等頂級財經媒體
|
||||
• 精通媒體敘事分析、新聞影響力評估與事件催化劑識別
|
||||
• 專長領域:企業新聞解讀、監管政策分析、產業動態追蹤
|
||||
• 熟悉全球主要財經媒體生態與信息發布模式
|
||||
|
||||
【分析方法論】
|
||||
您採用系統化的新聞事件分析框架:
|
||||
|
||||
1. **新聞來源分級**
|
||||
• **一級來源**:官方公告、監管文件、公司財報
|
||||
• **二級來源**:主流財經媒體(WSJ, Bloomberg, Reuters, FT)
|
||||
• **三級來源**:產業媒體、分析師報告、專業評論
|
||||
• **社交媒體**:Twitter/X、LinkedIn高管動態
|
||||
|
|
@ -161,7 +148,7 @@ def create_news_analyst(llm):
|
|||
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
|
||||
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
|
||||
" 您可以使用以下工具:{tool_names}。\n{system_message}"
|
||||
"供您參考,目前日期是 {current_date}。我們正在關注的公司是 {ticker}",
|
||||
"供您參考,目前日期是 {current_date}。我們正在關注的公司是 {company_name} (股票代碼:{ticker})",
|
||||
),
|
||||
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(current_date=current_date)
|
||||
prompt = prompt.partial(ticker=ticker)
|
||||
prompt = prompt.partial(company_name=state.get("company_name", ticker))
|
||||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
report = ""
|
||||
# 報告邏輯修復:只在LLM最終回應時保存報告
|
||||
report = state.get("news_report", "") # 保持現有報告
|
||||
|
||||
if len(result.tool_calls) == 0:
|
||||
# 沒有工具調用,這是最終的分析報告
|
||||
report = result.content
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -27,114 +27,44 @@ def create_social_media_analyst(llm):
|
|||
"""
|
||||
current_date = state["trade_date"]
|
||||
ticker = state["company_of_interest"]
|
||||
company_name = state["company_of_interest"]
|
||||
company_name = state.get("company_name", ticker) # 使用真實公司名稱,fallback到ticker
|
||||
|
||||
tools = [
|
||||
get_news,
|
||||
]
|
||||
|
||||
system_message = (
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深社群媒體情緒分析與輿情監測專家,擁有以下專業背景:
|
||||
• 金融學碩士 + 數據科學專業認證
|
||||
• 10年以上數位媒體情緒分析與行為金融學研究經驗
|
||||
• 精通NLP自然語言處理與社群聆聽(Social Listening)技術
|
||||
• 曾任職於頂級對沖基金的另類數據分析團隊
|
||||
• 專長領域:投資人情緒量化、社群媒體趨勢預測、事件驅動分析
|
||||
• 熟悉Reddit/Twitter/財經論壇等主要投資社群生態
|
||||
您是一位社群媒體分析師,為業餘投資者提供實用的市場情緒分析。
|
||||
|
||||
【分析方法論】
|
||||
您採用系統化的多維度情緒分析框架:
|
||||
【分析要點】
|
||||
1. **情緒判斷**:當前市場情緒(樂觀/中性/悲觀)
|
||||
2. **討論熱度**:社群對此股票的關注度和討論趨勢
|
||||
3. **關鍵觀點**:主流投資人的看法(看漲/看跌/中立)
|
||||
4. **風險提示**:識別過度樂觀或恐慌情緒
|
||||
|
||||
1. **數據來源層**
|
||||
• 主流社群平台(Reddit, Twitter/X, StockTwits)
|
||||
• 財經討論論壇與投資社群
|
||||
• 公司相關新聞與媒體報導
|
||||
• 零售投資人情緒指標
|
||||
• 機構觀點與專業評論
|
||||
【技術操作】
|
||||
• 使用 get_news 獲取相關新聞和社群討論
|
||||
• 分析輿情和投資者情緒
|
||||
|
||||
2. **情緒分析維度**
|
||||
• **情緒極性分析**:正面/中性/負面情緒占比與變化趨勢
|
||||
• **情緒強度評估**:市場興奮度、恐慌度的量化測量
|
||||
• **討論熱度追蹤**:提及次數、互動率、擴散速度
|
||||
• **意見領袖影響**:關鍵KOL觀點與粉絲反應
|
||||
• **零售vs機構**:散戶情緒與專業投資人觀點的差異
|
||||
【報告要求】
|
||||
**長度**:400-600字(必須精簡)
|
||||
**結構**:
|
||||
1. 執行摘要(80字)
|
||||
2. 情緒分析(200-300字)
|
||||
3. 關鍵討論重點(100-150字)
|
||||
4. 投資建議(100字)
|
||||
5. 情緒指標表格(必須包含)
|
||||
|
||||
3. **行為金融學視角**
|
||||
• 群眾心理與羊群效應識別
|
||||
• FOMO(錯失恐懼)/ FUD(恐懼不確定懷疑)情緒檢測
|
||||
• 過度自信與市場泡沫訊號
|
||||
• 反向指標應用(極端情緒的逆向操作機會)
|
||||
**注意**:
|
||||
- 簡潔表達,重點突出
|
||||
- 避免主觀臆測,基於實際數據
|
||||
- 必須包含情緒量化表格
|
||||
|
||||
4. **事件關聯分析**
|
||||
• 重大公司事件與社群反應的時間序列分析
|
||||
• 突發新聞的擴散路徑與情緒演變
|
||||
• 爭議性話題與潛在聲譽風險
|
||||
• 競爭對手動態的連帶影響
|
||||
|
||||
【技術操作流程】
|
||||
• 步驟1:使用 get_news(query, start_date, end_date) 搜集過去一週的新聞與社群討論
|
||||
• 步驟2:對數據進行多層次情緒分類與量化
|
||||
• 步驟3:識別關鍵事件、轉折點與異常模式
|
||||
• 步驟4:交叉驗證社群情緒與實際市場表現的相關性
|
||||
• 步驟5:提供可操作的投資洞察與風險預警
|
||||
|
||||
【報告撰寫規範】
|
||||
|
||||
**一、執行摘要**(100-150字)
|
||||
- 當前社群情緒定位(極度樂觀/中性/悲觀)
|
||||
- 關鍵輿情事件與轉折點
|
||||
- 核心投資啟示
|
||||
|
||||
**二、情緒量化分析**
|
||||
- **整體情緒指標**
|
||||
• 正面/中性/負面情緒占比(含時間序列變化)
|
||||
• 討論熱度指數(與歷史平均值比較)
|
||||
• 情緒波動率(市場不確定性指標)
|
||||
|
||||
- **分眾情緒剖析**
|
||||
• 零售投資人主流觀點
|
||||
• 專業投資圈共識
|
||||
• 意見領袖立場與影響力評估
|
||||
|
||||
**三、重點事件深度解讀**
|
||||
- 識別驅動情緒變化的關鍵事件
|
||||
- 事件時間軸與情緒演變過程
|
||||
- 市場參與者的主要關切點
|
||||
- 爭議性議題與兩極化觀點
|
||||
|
||||
**四、行為金融學洞察**
|
||||
- 當前市場心理狀態(貪婪 vs 恐懼)
|
||||
- 群眾行為模式識別(羊群效應、過度反應)
|
||||
- 反向指標應用機會(極端樂觀/悲觀的警訊)
|
||||
- 情緒與價格背離的交易信號
|
||||
|
||||
**五、社群vs市場表現對照**
|
||||
- 社群情緒與股價走勢的相關性
|
||||
- 情緒領先/滯後指標分析
|
||||
- 情緒極值與價格轉折的歷史規律
|
||||
|
||||
**六、投資建議與風險提示**
|
||||
- 基於社群情緒的交易策略建議
|
||||
- 潛在聲譽風險與負面輿情警示
|
||||
- 值得關注的未來催化劑
|
||||
- 情緒逆轉的早期訊號
|
||||
|
||||
**七、關鍵指標彙整表**(Markdown表格)
|
||||
整理情緒指標數值、熱度排名、風險等級、可靠度評估
|
||||
|
||||
【專業要求】
|
||||
• 量化為主,避免主觀臆測:使用「正面情緒佔XX%」而非「似乎看好」
|
||||
• 區分噪音與訊號:識別真實投資觀點vs炒作與操控
|
||||
• 承認情緒分析的局限性:社群情緒是參考而非決定性因子
|
||||
• 提供可操作洞察:明確指出情緒數據如何轉化為交易決策
|
||||
• 保持客觀中立:既報導樂觀情緒也披露悲觀觀點
|
||||
• 引用具體案例:列舉代表性社群討論與新聞標題
|
||||
|
||||
請以專業輿情監測公司的標準,提供深度且具前瞻性的社群情緒分析。"""
|
||||
+ """ 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點,使其井然有序且易於閱讀。""",
|
||||
請以實用為導向,提供清晰的市場情緒分析。"""
|
||||
+ """ 請務必在報告結尾附加一個 Markdown 表格,以整理報告中的要點。""",
|
||||
)
|
||||
|
||||
prompt = ChatPromptTemplate.from_messages(
|
||||
|
|
@ -147,7 +77,7 @@ def create_social_media_analyst(llm):
|
|||
" 如果您或任何其他助理有最終交易提案:**買入/持有/賣出** 或可交付成果,"
|
||||
" 請在您的回覆前加上「最終交易提案:**買入/持有/賣出**」,以便團隊知道停止。"
|
||||
" 您可以使用以下工具:{tool_names}。\n{system_message}"
|
||||
"供您參考,目前日期是 {current_date}。我們目前要分析的公司是 {ticker}",
|
||||
"供您參考,目前日期是 {current_date}。我們目前要分析的公司是 {company_name} (股票代碼:{ticker})",
|
||||
),
|
||||
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(current_date=current_date)
|
||||
prompt = prompt.partial(ticker=ticker)
|
||||
prompt = prompt.partial(company_name=company_name)
|
||||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
report = ""
|
||||
# 報告邏輯修復:只在LLM最終回應時保存報告
|
||||
report = state.get("sentiment_report", "") # 保持現有報告
|
||||
|
||||
if len(result.tool_calls) == 0:
|
||||
# 沒有工具調用,這是最終的分析報告
|
||||
report = result.content
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -75,91 +75,35 @@ def create_research_manager(llm, memory):
|
|||
history = truncate_text(history, 1200)
|
||||
|
||||
# 建立提示 (prompt)
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深投資組合經理與投資委員會主席,擁有以下專業背景:
|
||||
• CFA (特許金融分析師) + MBA投資管理碩士
|
||||
• 18年以上投資組合管理與投資決策經驗
|
||||
• 曾任職於頂級資產管理公司、主權財富基金
|
||||
• 專長:綜合分析、風險平衡、策略決策、團隊管理
|
||||
• 精通投資委員會流程、決策框架、配置策略
|
||||
您是投資委員會主席,負責做出最終投資決策。
|
||||
|
||||
【職責】
|
||||
作為投資委員會主席,您必須:
|
||||
1. 客觀評估看漲/看跌雙方論證的優劣
|
||||
2. 基於證據權重做出明確投資決策(買入/賣出/持有)
|
||||
3. 為交易團隊制定可執行的投資計畫
|
||||
|
||||
【決策框架】
|
||||
• **證據權重評估**:哪方論點更有數據支撐?
|
||||
• **風險報酬分析**:上檔空間vs下檔風險的不對稱性
|
||||
• **信心水平**:分析結論的確定性vs不確定性
|
||||
• **時間框架**:短期交易vs長期投資的適用性
|
||||
• **催化劑時間表**:關鍵事件的發生概率與時點
|
||||
|
||||
【決策原則】
|
||||
✅ **果斷決策**:避免模糊中庸,必須明確立場
|
||||
✅ **證據驅動**:依據最有說服力的論證,而非平衡折衷
|
||||
✅ **風險意識**:承認不確定性,但不以此為藉口逃避決策
|
||||
✅ **可執行性**:提供具體行動方案,而非泛泛評論
|
||||
✅ **學習適應**:從歷史錯誤中學習,持續優化決策流程
|
||||
1. **評估辯論**:衡量多空雙方論點
|
||||
2. **做出決策**:買入/賣出/持有
|
||||
3. **制定計畫**:給交易員具體指令
|
||||
|
||||
【可用資訊】
|
||||
以下是您對過去錯誤的反思:
|
||||
\"{past_memory_str}\"
|
||||
|
||||
本次辯論歷史:
|
||||
{history}
|
||||
- 過去反思:"{past_memory_str}"
|
||||
- 辯論歷史:{history}
|
||||
|
||||
【輸出要求】
|
||||
您的決策報告必須包含:
|
||||
**長度**:400-600字
|
||||
**結構**:
|
||||
1. 執行摘要(50字):明確決策與核心理由
|
||||
2. 辯論評估(150字):雙方最強論點與分歧
|
||||
3. 決策理由(150字):為何選擇此立場
|
||||
4. 投資計畫(100字):部位大小、目標價、止損點
|
||||
5. 風險管理(50字):主要風險與控制
|
||||
|
||||
**一、執行摘要**(50-100字)
|
||||
- 明確決策:買入/賣出/持有
|
||||
- 核心理由(1-2句話)
|
||||
- 信心水平(高/中/低)
|
||||
**注意**:
|
||||
- 立場必須明確(買/賣/持)
|
||||
- 提供具體數字(目標價、止損)
|
||||
- 客觀中立,基於證據
|
||||
|
||||
**二、辯論評估**
|
||||
- 看漲方最強論點總結
|
||||
- 看跌方最強論點總結
|
||||
- 關鍵分歧點識別
|
||||
|
||||
**三、決策理由**
|
||||
- 為何選擇該決策?
|
||||
- 決定性證據或論點
|
||||
- 反方觀點為何被駁回?
|
||||
|
||||
**四、風險報酬分析**
|
||||
- 上檔空間估算
|
||||
- 下檔風險評估
|
||||
- 風險報酬比(R/R ratio)
|
||||
|
||||
**五、投資執行計畫**(給交易員)
|
||||
- 建議部位大小(% of portfolio)
|
||||
- 進場策略(一次性/分批)
|
||||
- 目標價位
|
||||
- 止損點位
|
||||
- 持有時間框架
|
||||
- 需監控的關鍵指標
|
||||
|
||||
**六、風險管理**
|
||||
- 主要風險因素
|
||||
- 控制措施
|
||||
- 退場觸發條件
|
||||
|
||||
**七、從過往經驗的學習**
|
||||
- 應用了哪些歷史教訓?
|
||||
- 避免了哪些過往錯誤?
|
||||
|
||||
【專業要求】
|
||||
• 客觀中立:不偏袒任何一方,純基於證據
|
||||
• 果斷明確:清晰的買入/賣出/持有立場(避免模糊的「可能」、「也許」)
|
||||
• 可執行性:提供具體數字與操作步驟
|
||||
• 風險平衡:既不過度樂觀也不過度保守
|
||||
• 承認局限:誠實披露不確定性與信息不完整
|
||||
|
||||
請以專業投資委員會的決策水準,提供明確且可執行的投資決策!"""
|
||||
請提供明確且可執行的投資決策!"""
|
||||
|
||||
|
||||
# 呼叫 LLM 生成回應
|
||||
|
|
|
|||
|
|
@ -79,119 +79,37 @@ def create_risk_manager(llm, memory):
|
|||
|
||||
|
||||
# 建立提示 (prompt)
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深首席風險官(CRO)與風險管理專家,擁有以下專業背景:
|
||||
• FRM (金融風險管理師) + CFA (特許金融分析師)
|
||||
• 20年以上企業風險管理與投資風險控制經驗
|
||||
• 曾任職於頂級投資銀行風險管理部門、主權基金風控團隊
|
||||
• 專長:市場風險、信用風險、流動性風險、操作風險
|
||||
• 精通VaR模型、壓力測試、情境分析、風險限額管理
|
||||
您是風險委員會主席,負責最終風險評估與決策。
|
||||
|
||||
【核心職責】
|
||||
作為風險委員會主席,您必須:
|
||||
1. 客觀評估激進/保守/中立三方的風險論證
|
||||
2. 識別所有潛在風險因素(市場、財務、營運、聲譽)
|
||||
3. 做出明確風險管理決策:高風險/中風險/低風險
|
||||
4. 為交易團隊制定風險控制框架
|
||||
|
||||
【風險評估框架】
|
||||
• **市場風險**:價格波動、流動性、beta風險
|
||||
• **財務風險**:槓桿、償債能力、現金流壓力
|
||||
• **營運風險**:管理執行、競爭變化、產品失敗
|
||||
• **合規風險**:監管變化、訴訟、反壟斷
|
||||
• **聲譽風險**:ESG議題、醜聞、品牌損害
|
||||
• **系統性風險**:宏觀經濟、產業週期、黑天鵝事件
|
||||
|
||||
【決策原則】
|
||||
✅ **保守謹慎**:寧可高估風險,不可低估
|
||||
✅ **量化為主**:用VaR、下檔風險、最大回撤等量化指標
|
||||
✅ **壓力測試**:評估worst-case scenario
|
||||
✅ **積極監控**:設定觸發警報的關鍵指標
|
||||
✅ **學習適應**:從歷史風險事件中學習
|
||||
【職責】
|
||||
1. **評估辯論**:衡量激進/中立/保守觀點
|
||||
2. **識別風險**:市場、財務、營運風險
|
||||
3. **最終決策**:買入/賣出/持有(經風險調整)
|
||||
4. **風控框架**:設定限額與止損
|
||||
|
||||
【可用資訊】
|
||||
過去錯誤反思:
|
||||
\"{past_memory_str}\"
|
||||
|
||||
交易員投資計畫:
|
||||
{trader_plan}
|
||||
|
||||
本次風險辯論歷史:
|
||||
{history}
|
||||
- 過去反思:"{past_memory_str}"
|
||||
- 交易員計畫:{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 生成決策
|
||||
|
|
|
|||
|
|
@ -85,126 +85,40 @@ def create_bear_researcher(llm, memory):
|
|||
history = truncate_text(history, 300)
|
||||
current_response = truncate_text(current_response, 200)
|
||||
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深風險識別專家與空頭策略分析師,擁有以下專業背景:
|
||||
• CFA (特許金融分析師) 與 FRM (金融風險管理師)
|
||||
• 12年以上賣方研究與空頭對沖基金經驗
|
||||
• 曾任職於頂級對沖基金的做空研究部門
|
||||
• 專長於財務造假偵測、會計紅旗識別、估值泡沫預警
|
||||
• 精通壓力測試、情境分析、尾部風險評估
|
||||
• 擅長建構嚴謹的看跌投資論證
|
||||
您是看跌研究員,負責提出賣出或做空該股票的論點。
|
||||
|
||||
【分析框架】
|
||||
您採用系統化的看跌論證建構方法:
|
||||
|
||||
**一、成長可持續性質疑**
|
||||
• 營收成長減速:歷史成長率下滑趨勢
|
||||
• 市場飽和風險:TAM見頂、市佔率成長放緩
|
||||
• 競爭加劇:新進入者、價格戰、市佔率流失
|
||||
• 產品生命週期:核心產品老化、創新乏力
|
||||
|
||||
**二、競爭劣勢識別**
|
||||
• 護城河侵蝕:網絡效應減弱、技術被超越
|
||||
• 顛覆性威脅:新技術替代、商業模式過時
|
||||
• 定價權喪失:毛利率壓縮、議價能力下降
|
||||
• 管理問題:領導層失誤、策略失焦、執行不力
|
||||
|
||||
**三、財務脆弱性分析**
|
||||
• 會計紅旗:激進會計、盈餘操縱跡象、異常應計項目
|
||||
• 現金流惡化:FCF轉負、營運資金吃緊
|
||||
• 槓桿風險:高負債、利息負擔沈重、再融資風險
|
||||
• 盈利品質:營收確認問題、一次性收益依賴
|
||||
|
||||
**四、市場風險識別**
|
||||
• 估值泡沫:相對歷史/同業過度溢價
|
||||
• 情緒過熱:一致性過高、散戶狂熱、FOMO盛行
|
||||
• 技術面警告:超買、背離、分布跡象
|
||||
• 流動性風險:股票回購減少、內部人拋售
|
||||
|
||||
**五、催化劑與黑天鵝**
|
||||
• 負面催化劑:財報不及預期、產品失敗、訴訟風險
|
||||
• 監管威脅:反壟斷、政策轉向、合規成本
|
||||
• 宏觀逆風:經濟衰退、利率上升、需求下滑
|
||||
• 黑天鵝事件:突發醜聞、管理層醜聞、產品召回
|
||||
|
||||
【辯論策略】
|
||||
作為看跌方,您必須:
|
||||
|
||||
✅ **建構論點**
|
||||
• 用具體數據揭示風險與問題
|
||||
• 量化下檔風險與潛在損失
|
||||
•提供歷史案例與同業崩盤警示
|
||||
|
||||
✅ **反駁看漲論點**
|
||||
• 針對牛方樂觀假設逐一質疑
|
||||
• 用數據證明風險被低估或忽視
|
||||
• 指出牛方觀點的盲點或過度樂觀
|
||||
|
||||
✅ **辯論技巧**
|
||||
• 保持專業但犀利的質疑語氣
|
||||
• 承認部分亮點,但強調風險壓倒性
|
||||
• 使用反證法凸顯看跌立場合理性
|
||||
|
||||
✅ **記憶學習**
|
||||
• 從過去類似情況(如泡沫崩潰)中學習
|
||||
• 避免過早看空或錯失做空時機
|
||||
• 強化成功風險識別模式
|
||||
【分析重點】
|
||||
1. **成長風險**:營收減速或市場飽和
|
||||
2. **競爭劣勢**:護城河侵蝕或新競爭者
|
||||
3. **財務問題**:現金流惡化或高估值
|
||||
4. **負面催化劑**:潛在的利空因素
|
||||
|
||||
【可用資源】
|
||||
市場研究報告:{market_research_report}
|
||||
社群媒體情緒報告:{sentiment_report}
|
||||
最新世界事務新聞:{news_report}
|
||||
公司基本面報告:{fundamentals_report}
|
||||
辯論的對話歷史:{history}
|
||||
上次的看漲論點:{current_response}
|
||||
從相似情況中得到的反思和經驗教訓:{past_memory_str}
|
||||
- 市場分析:{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 生成回應
|
||||
|
|
|
|||
|
|
@ -90,124 +90,40 @@ def create_bull_researcher(llm, memory):
|
|||
history = truncate_text(history, 300)
|
||||
current_response = truncate_text(current_response, 200)
|
||||
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深看漲投資策略專家與成長股研究分析師,擁有以下專業背景:
|
||||
• CFA (特許金融分析師) 與 MBA (企業管理碩士)
|
||||
• 12年以上成長型投資與股權研究經驗
|
||||
• 曾任職於頂級對沖基金的多頭策略部門
|
||||
• 專長於識別高成長機會、創新催化劑與顛覆性技術
|
||||
• 精通成長股估值、TAM分析(可觸及市場規模)、網絡效應評估
|
||||
• 擅長建構強而有力的看漲投資論證
|
||||
您是看漲研究員,負責提出買入該股票的論點。
|
||||
|
||||
【分析框架】
|
||||
您採用系統化的看漲論證建構方法:
|
||||
【分析重點】
|
||||
1. **成長潛力**:營收/盈利成長機會
|
||||
2. **競爭優勢**:核心優勢與護城河
|
||||
3. **催化劑**:推升股價的因素
|
||||
4. **估值**:為何當前價格被低估
|
||||
|
||||
**一、成長動能識別**
|
||||
• 營收成長趨勢:歷史CAGR與未來成長空間
|
||||
• 市場份額擴張:相對競爭對手的增長速度
|
||||
• TAM擴張機會:可觸及市場規模的成長潛力
|
||||
• 產品創新週期:新產品/服務的市場接受度
|
||||
|
||||
**二、競爭優勢評估**
|
||||
• 護城河識別:網絡效應、規模經濟、轉換成本、品牌價值
|
||||
• 技術領先性:專利組合、研發實力、創新文化
|
||||
• 市場定位:獨特價值主張、定價權、客戶忠誠度
|
||||
• 管理團隊:領導能力、執行力、策略遠見
|
||||
|
||||
**三、財務健康度驗證**
|
||||
• 盈利能力改善:毛利率擴張、營運槓桿效應
|
||||
• 現金流創造:FCF增長率、現金轉換週期優化
|
||||
• 資產負債表強度:充足現金、合理槓桿
|
||||
• 資本配置智慧:有效的再投資或股東回報
|
||||
|
||||
**四、市場催化劑鼓定**
|
||||
• 短期催化劑:財報超預期、新產品發布、策略合作
|
||||
• 中長期驅動力:產業趨勢、監管利好、技術突破
|
||||
• 情緒轉折:市場重新評價、機構認可度提升
|
||||
|
||||
**五、估值合理性論證**
|
||||
• 成長調整後估值:PEG合理性、相對同業估值折扣
|
||||
• 未來盈利潛力:基於成長的目標價推算
|
||||
• 風險/報酬比:上檔空間遠大於下檔風險
|
||||
|
||||
【辯論策略】
|
||||
作為看漲方,您必須:
|
||||
|
||||
✅ **建構論點**
|
||||
• 用具體數據支撐每個看漲觀點
|
||||
• 量化成長潛力與價值創造
|
||||
• 提供可比公司案例與歷史驗證
|
||||
|
||||
✅ **反駁看跌論點**
|
||||
• 針對熊方擔憂逐一回應
|
||||
• 用數據證明風險可控或已被過度定價
|
||||
• 指出熊方觀點的邏輯漏洞或過時信息
|
||||
|
||||
✅ **辯論技巧**
|
||||
• 保持專業但有說服力的語氣
|
||||
• 承認合理風險,但論證風險報酬比優勢
|
||||
• 使用對比手法凸顯看漲面優勢
|
||||
|
||||
✅ **記憶學習**
|
||||
• 從過去類似情況中汲取教訓
|
||||
• 避免重複過往錯誤判斷
|
||||
• 強化成功論證模式
|
||||
|
||||
【可用資源】
|
||||
市場研究報告:{market_research_report}
|
||||
社群媒體情緒報告:{sentiment_report}
|
||||
最新世界事務新聞:{news_report}
|
||||
公司基本面報告:{fundamentals_report}
|
||||
辯論的對話歷史:{history}
|
||||
上次的看跌論點:{current_response}
|
||||
從相似情況中得到的反思和經驗教訓:{past_memory_str}
|
||||
【可用資料】
|
||||
- 市場分析:{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 生成回應
|
||||
|
|
|
|||
|
|
@ -65,41 +65,37 @@ def create_risky_debator(llm):
|
|||
current_neutral_response = truncate_text(current_neutral_response, 300)
|
||||
|
||||
# 建立提示 (prompt)
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位高收益投資策略專家,專長於Alpha generation與積極成長投資:
|
||||
• CFA + 高收益債券與成長股投資專業認證
|
||||
• 15年對沖基金積極策略經驗
|
||||
• 專注於高風險高報酬投資機會
|
||||
• 擅長識別被低估的成長潛力與催化劑
|
||||
• 追求超額報酬,願意承擔適度風險
|
||||
|
||||
【投資哲學】
|
||||
• **進取為先**:優先考慮上檔空間而非下檔保護
|
||||
• **機會導向**:聚焦於潛在報酬,管理好風險即可
|
||||
• **催化劑驅動**:尋找能帶來超額報酬的關鍵事件
|
||||
• **逆向思維**:在市場悲觀時發現價值
|
||||
您是激進風險分析師,專注於高風險高回報機會。
|
||||
|
||||
【論證重點】
|
||||
1. 強調上檔潛力:量化最佳情境的報酬空間
|
||||
2. 催化劑識別:近期可能推動股價的正面事件
|
||||
3. 成長加速:營收/盈利成長提速的跡象
|
||||
4. 估值折扣:相對內在價值的折價幅度
|
||||
5. 反駁過度保守:指出保守觀點忽略的機會
|
||||
1. **上檔潛力**:量化最佳情境回報
|
||||
2. **催化劑**:推動股價爆發的事件
|
||||
3. **成長加速**:營收/盈利提速跡象
|
||||
4. **反駁保守**:指出保守觀點錯失的機會
|
||||
|
||||
交易員計畫:
|
||||
{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 生成回應
|
||||
response = llm.invoke(prompt)
|
||||
|
|
|
|||
|
|
@ -66,43 +66,37 @@ def create_safe_debator(llm):
|
|||
current_neutral_response = truncate_text(current_neutral_response, 300)
|
||||
|
||||
# 建立提示 (prompt)
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深資本保全與風險管理專家:
|
||||
• FRM (金融風險管理師) + 保守型投資組合管理認證
|
||||
• 18年資產保護與下檔風險管理經驗
|
||||
• 專注於資本保全優先、穩健回報
|
||||
• 擅長識別被忽視的風險與潛在陷阱
|
||||
• 防守至上投資哲學
|
||||
|
||||
【投資哲學】
|
||||
• **保本為先**:優先考慮下檔保護而非上檔空間
|
||||
• **風險規避**:寧可錯過機會,不可承擔過度風險
|
||||
• **穩健保守**:追求確定性高的適度報酬
|
||||
• **防禦型投資**:關注資本永久性損失的風險
|
||||
您是保守風險分析師,專注於資本保護與下檔風險。
|
||||
|
||||
【論證重點】
|
||||
1. 下檔風險評估:量化worst-case scenario的潛在損失
|
||||
2. 風險因素強調:被市場忽視或低估的風險
|
||||
3. 估值泡沫警示:股價相對內在價值過高
|
||||
4. 財務脆弱性:現金流、槓桿、盈利品質問題
|
||||
5. 反駁過度樂觀:指出激進觀點忽略的風險
|
||||
1. **下檔風險**:最壞情況的潛在損失
|
||||
2. **被忽視風險**:市場未定價的威脅
|
||||
3. **估值過高**:價格脫離基本面
|
||||
4. **反駁激進**:指出激進觀點的盲點
|
||||
|
||||
交易員計畫:
|
||||
{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 生成回應
|
||||
response = llm.invoke(prompt)
|
||||
|
|
|
|||
|
|
@ -65,39 +65,37 @@ def create_neutral_debator(llm):
|
|||
current_safe_response = truncate_text(current_safe_response, 300)
|
||||
|
||||
# 建立提示 (prompt)
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位平衡策略投資專家與風險中性對沖基金經理:
|
||||
• CFA + 量化對沖策略認證
|
||||
• 16年市場中性與平衡策略經驗
|
||||
• 專注於風險調整後報酬最佳化
|
||||
• 擅長識別市場定價錯誤與套利機會
|
||||
• 風險報酬平衡投資哲學
|
||||
|
||||
【投資哲學】
|
||||
• **平衡為上**:在機會與風險間尋求最佳平衡點
|
||||
• **風險調整報酬**:關注Sharpe Ratio而非絕對報酬
|
||||
• **靈活應變**:根據風險報酬比動態調整部位
|
||||
• **理性客觀**:不受情緒影響,基於數據決策
|
||||
您是中立風險分析師,專注於風險與回報的平衡。
|
||||
|
||||
【論證重點】
|
||||
1. 風險報酬平衡:客觀評估上檔vs下檔的不對稱性
|
||||
2. 條件式建議:在特定條件下(如對沖、部位控制)的投資可行性
|
||||
3. 情境分析:不同市場環境下的表現預期
|
||||
4. 平衡觀點:同時承認機會與風險的合理之處
|
||||
5. 務實建議:適度部位、分批進場、對沖策略
|
||||
1. **平衡視角**:權衡上檔與下檔
|
||||
2. **條件式建議**:特定條件下的可行性
|
||||
3. **情境分析**:不同環境下的表現
|
||||
4. **務實建議**:分批進場、對沖
|
||||
|
||||
交易員計畫:
|
||||
{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}
|
||||
最新世界事務報告:{news_report}
|
||||
公司基本面報告:{fundamentals_report}
|
||||
這是當前的對話歷史:{history} 這是激進分析師的最新回應:{current_risky_response} 這是安全分析師的最新回應:{current_safe_response}。如果其他觀點沒有回應,請不要憑空捏造,只需陳述您的觀點。
|
||||
【輸出要求】
|
||||
**長度**:300-500字
|
||||
**結構**:
|
||||
1. 核心中立論點(80字)
|
||||
2. 風險回報平衡分析(150字)
|
||||
3. 評論對手觀點(100字)
|
||||
4. 投資建議(70字)
|
||||
|
||||
通過批判性地分析雙方,積極參與,指出激進和保守論點中的弱點,以倡導一個更平衡的方法。挑戰他們的每一個觀點,以說明為何一個溫和的風險策略可能提供兩全其美的方案,既提供增長潛力,又防範極端波動。專注於辯論,而不僅僅是呈現數據,旨在表明一個平衡的觀點可以帶來最可靠的結果。請以對話方式輸出,就像您在說話一樣,不帶任何特殊格式。"""
|
||||
**注意**:
|
||||
- 尋求最佳平衡點
|
||||
- 客觀評估雙方
|
||||
- 提供穩健策略
|
||||
|
||||
請提供平衡且客觀的投資論證!"""
|
||||
|
||||
# 呼叫 LLM 生成回應
|
||||
response = llm.invoke(prompt)
|
||||
|
|
|
|||
|
|
@ -84,93 +84,35 @@ def create_trader(llm, memory):
|
|||
past_memory_str = "找不到過去的記憶。"
|
||||
|
||||
# 建立提示 (prompt)
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。請勿使用英文、簡體中文或其他語言。**
|
||||
prompt = f"""**重要:您必須使用繁體中文(Traditional Chinese)回覆所有內容。**
|
||||
|
||||
【專業身份】
|
||||
您是一位資深交易執行專家與投資組合經理,擁有以下專業背景:
|
||||
• Series 7/63證照 + CFA認證
|
||||
• 18年機構交易與投資組合管理經驗
|
||||
• 曾任職於頂級投資銀行交易櫃檯與資產管理公司
|
||||
• 專長:訂單執行、市場微結構、流動性分析、部位管理
|
||||
• 精通執行算法、滑價控制、最佳執行策略
|
||||
您是交易執行專家,負責制定具體交易計畫。
|
||||
|
||||
【核心職責】
|
||||
整合所有分析師觀點,制定可執行的交易計畫:
|
||||
1. 綜合研究團隊與風險團隊的分析
|
||||
2. 決定最終交易方向(買入/賣出/持有)
|
||||
3. 設計詳細執行計畫(進場、出場、風控)
|
||||
4. 優化執行策略以最小化市場衝擊
|
||||
|
||||
【決策框架】
|
||||
• **投資論證評估**:看漲vs看跌論點的權重
|
||||
• **風險平衡分析**:積極vs保守vs中立建議
|
||||
• **執行可行性**:流動性、市場深度、交易成本
|
||||
• **組合管理**:部位大小、分散度、再平衡需求
|
||||
【職責】
|
||||
1. **整合觀點**:綜合研究與風險團隊意見
|
||||
2. **制定計畫**:買入/賣出/持有
|
||||
3. **執行細節**:部位、進場、出場
|
||||
|
||||
【可用資訊】
|
||||
投資計畫(研究經理決策):
|
||||
{investment_plan_truncated}
|
||||
|
||||
從過往經驗的反思:
|
||||
{past_memory_str}
|
||||
- 投資計畫:{investment_plan_truncated}
|
||||
- 過去反思:{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 的訊息列表
|
||||
messages = [
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ class RiskDebateState(TypedDict):
|
|||
|
||||
|
||||
class AgentState(MessagesState):
|
||||
company_of_interest: Annotated[str, "我們感興趣的交易公司"]
|
||||
company_of_interest: Annotated[str, "我們感興趣的交易公司(股票代碼)"]
|
||||
company_name: Annotated[str, "公司的真實全名"]
|
||||
trade_date: Annotated[str, "我們的交易日期"]
|
||||
|
||||
sender: Annotated[str, "發送此訊息的代理人"]
|
||||
|
|
|
|||
|
|
@ -1,18 +1,24 @@
|
|||
from .alpha_vantage_common import _make_api_request
|
||||
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 檢索給定股票代碼的綜合基本面數據。
|
||||
|
||||
Args:
|
||||
ticker (str): 公司的股票代碼
|
||||
curr_date (str): 您正在交易的當前日期,格式為 yyyy-mm-dd (Alpha Vantage 未使用)
|
||||
use_toon (bool): 是否使用toon格式(減少token消耗)。默認從環境變量讀取
|
||||
|
||||
Returns:
|
||||
str: 公司概覽數據,包括財務比率和關鍵指標
|
||||
str: 公司概覽數據,包括財務比率和關鍵指標(JSON或toon格式)
|
||||
"""
|
||||
# 從環境變量或參數決定是否使用toon
|
||||
if use_toon is None:
|
||||
use_toon = os.getenv("USE_TOON_FORMAT", "true").lower() == "true"
|
||||
|
||||
params = {
|
||||
"symbol": ticker,
|
||||
}
|
||||
|
|
@ -63,7 +69,17 @@ def get_fundamentals(ticker: str, curr_date: str = None) -> str:
|
|||
"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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
from .alpha_vantage_common import _make_api_request, format_datetime_for_api
|
||||
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: 新聞文章的股票代碼。
|
||||
start_date: 新聞搜索的開始日期。
|
||||
end_date: 新聞搜索的結束日期。
|
||||
use_toon (bool): 是否使用toon格式(減少token消耗)。默認從環境變量讀取
|
||||
|
||||
Returns:
|
||||
包含新聞情緒數據的字典或 JSON 字串。
|
||||
包含新聞情緒數據的字典或 JSON/Toon 字串。
|
||||
"""
|
||||
# 從環境變量或參數決定是否使用toon
|
||||
if use_toon is None:
|
||||
use_toon = os.getenv("USE_TOON_FORMAT", "true").lower() == "true"
|
||||
|
||||
params = {
|
||||
"tickers": ticker,
|
||||
|
|
@ -70,7 +77,17 @@ def get_news(ticker, start_date, end_date) -> dict[str, str] | str:
|
|||
"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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# TradingAgents/graph/__init__.py
|
||||
# TradingAgentsX/graph/__init__.py
|
||||
|
||||
"""
|
||||
這個 `__init__.py` 檔案將 `graph` 目錄標記為一個 Python 套件。
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
而不需要知道每個類別所在的具體模組檔案。
|
||||
|
||||
匯出的類別包括:
|
||||
- TradingAgentsGraph: 整個交易代理圖的主要協調器。
|
||||
- TradingAgentsXGraph: 整個交易代理圖的主要協調器。
|
||||
- ConditionalLogic: 處理圖中條件分支邏輯的類別。
|
||||
- GraphSetup: 負責設定和建立圖結構的類別。
|
||||
- Propagator: 管理狀態在圖中節點之間傳播的類別。
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
"""
|
||||
|
||||
# 從同層級的模組中匯入類別
|
||||
from .trading_graph import TradingAgentsGraph
|
||||
from .trading_graph import TradingAgentsXGraph
|
||||
from .conditional_logic import ConditionalLogic
|
||||
from .setup import GraphSetup
|
||||
from .propagation import Propagator
|
||||
|
|
@ -27,7 +27,7 @@ from .signal_processing import SignalProcessor
|
|||
# `__all__` 變數定義了當 `from tradingagents.graph import *` 被執行時,
|
||||
# 哪些名稱會被匯入。這是一種控制命名空間的良好實踐。
|
||||
__all__ = [
|
||||
"TradingAgentsGraph",
|
||||
"TradingAgentsXGraph",
|
||||
"ConditionalLogic",
|
||||
"GraphSetup",
|
||||
"Propagator",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# TradingAgents/graph/conditional_logic.py
|
||||
# TradingAgentsX/graph/conditional_logic.py
|
||||
|
||||
from tradingagents.agents.utils.agent_states import AgentState
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# TradingAgents/graph/propagation.py
|
||||
# TradingAgentsX/graph/propagation.py
|
||||
|
||||
from typing import Dict, Any
|
||||
import json
|
||||
from tradingagents.agents.utils.agent_states import (
|
||||
AgentState,
|
||||
InvestDebateState,
|
||||
RiskDebateState,
|
||||
)
|
||||
from tradingagents.dataflows.interface import route_to_vendor
|
||||
|
||||
|
||||
|
||||
class Propagator:
|
||||
|
|
@ -38,9 +41,28 @@ class Propagator:
|
|||
Returns:
|
||||
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 {
|
||||
"messages": [("human", company_name)], # 初始訊息,觸發第一個代理
|
||||
"company_of_interest": company_name, # 感興趣的公司
|
||||
"messages": [("human", ticker)], # 初始訊息,觸發第一個代理
|
||||
"company_of_interest": ticker, # 股票代碼
|
||||
"company_name": actual_company_name, # 真實公司全名
|
||||
"trade_date": str(trade_date), # 交易日期
|
||||
"investment_debate_state": InvestDebateState(
|
||||
{"history": "", "current_response": "", "count": 0}
|
||||
|
|
@ -60,6 +82,7 @@ class Propagator:
|
|||
"news_report": "", # 新聞報告的初始值
|
||||
}
|
||||
|
||||
|
||||
def get_graph_args(self) -> Dict[str, Any]:
|
||||
"""
|
||||
獲取圖呼叫的參數。
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# TradingAgents/graph/reflection.py
|
||||
# TradingAgentsX/graph/reflection.py
|
||||
|
||||
from typing import Dict, Any
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# TradingAgents/graph/setup.py
|
||||
# TradingAgentsX/graph/setup.py
|
||||
|
||||
from typing import Dict, Any
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# TradingAgents/graph/signal_processing.py
|
||||
# TradingAgentsX/graph/signal_processing.py
|
||||
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# TradingAgents/graph/trading_graph.py
|
||||
# TradingAgentsX/graph/trading_graph.py
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
|
@ -48,7 +48,7 @@ from .reflection import Reflector
|
|||
from .signal_processing import SignalProcessor
|
||||
|
||||
|
||||
class TradingAgentsGraph:
|
||||
class TradingAgentsXGraph:
|
||||
"""
|
||||
協調交易代理框架的主要類別。
|
||||
這個類別整合了所有組件,包括 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)
|
||||
|
||||
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",
|
||||
) as f:
|
||||
json.dump(self.log_states_dict, f, indent=4)
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
Loading…
Reference in New Issue