Files
nanocode/TradingAgents/docs/architecture-and-modifications.md
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

19 KiB
Raw Permalink Blame History

TradingAgents 技术架构分析及 akshare 集成修改

文档时间: 2026-05-05
项目路径: /home/ubuntu/forgithub/TradingAgents
运行端口: :8500 (Web UI)


一、项目概述

TradingAgents 是一个基于 LLM 的多智能体(Multi-Agent)金融交易分析框架。它模拟真实投资决策中的"研究员→辩论→交易员"流程,由多个分析师角色协作完成对单只股票的深入分析,并输出最终交易决策(买入/卖出/持有)。

核心思想:用 LLM 扮演不同角色的分析师,使用真实市场数据工具,通过辩论机制达成投资共识。


二、技术栈

层次 技术选型
多智能体编排 LangGraph(StateGraph)
LLM 接口 LangChain + DeepSeek / OpenAI
工具系统 LangChain @tool 装饰器
数据源 akshare / yfinance / Alpha Vantage
Web 服务 FastAPI + 自定义 SPA 页面
部署 systemd(tradingagents.service)

三、架构分层

3.1 整体流程

用户输入 (ticker + date)
        │
        ▼
  ┌──────────────────────┐
  │   TradingAgentsGraph │  ← LangGraph StateGraph
  │   (trading_graph.py) │
  └──────┬───────────────┘
         │
         ▼
  ┌───────────────────────────────────────┐
  │         Researcher Team               │
  │  ┌──────────┐ ┌──────────┐           │
  │  │  Market  │ │  News    │  ...      │  ← 并行分析
  │  │ Analyst  │ │ Analyst  │           │
  │  └────┬─────┘ └────┬─────┘           │
  │       │            │                  │
  │       └─────┬──────┘                  │
  │             ▼                         │
  │       Debate Layer (1~N rounds)       │  ← 多轮辩论
  │             │                         │
  │             ▼                         │
  │       Final Decision                  │
  │       (Buy/Sell/Hold)                 │
  └───────────────────────────────────────┘
         │
         ▼
  输出:分析报告 + 交易决策

3.2 节点说明

节点 文件 角色 使用的工具
Market Analyst analysts/market_analyst.py 技术面分析师 get_stock_data, get_indicators (RSI, MACD, 布林带等 19 项指标)
News Analyst analysts/news_analyst.py 宏观新闻分析师 get_news, get_global_news
Social Media Analyst analysts/social_media_analyst.py 社交媒体分析师 get_news
Fundamentals Analyst analysts/fundamentals_analyst.py 基本面分析师 get_fundamentals, get_balance_sheet, get_cashflow, get_income_statement
Debate Layer trading_graph.py 多智能体辩论 各分析师报告交叉辩论
Final Decision trading_graph.py 最终交易决策 综合所有报告和辩论结果

3.3 数据流

每个 Analyst 节点
  │
  ├─ 构造 system prompt + 数据查询指令
  ├─ 通过 LangChain tool 调用 route_to_vendor()
  ├─ route_to_vendor 按优先级选择数据源
  │   ├─ akshare (默认)
  │   ├─ yfinance (fallback)
  │   └─ alpha_vantage (fallback)
  └─ 返回格式化数据,LLM 生成分析报告

四、核心模块

4.1 Graph 编排层

文件: tradingagents/graph/trading_graph.py

  • 基于 LangGraph StateGraph 构建
  • setup_graph() 按选定的分析师列表动态添加节点
  • 支持配置 max_debate_rounds(默认 1 轮,可多轮辩论)
  • 输出最终状态和交易决策

文件: tradingagents/graph/setup.py

  • 提供 create_complete_graph() 工厂函数
  • 封装完整流程:研究员 → 辩论 → 终判

4.2 工具层

文件: tradingagents/agents/utils/agent_utils.py

  • create_completion() — LLM 调用封装,支持 reasoning_effort 参数
  • ToolKit — 工具集管理,按分析师类型分发工具

工具定义文件(位于 agents/utils/):

文件 包含工具
core_stock_tools.py get_stock_data
technical_indicators_tools.py get_indicators (19 项技术指标)
fundamental_data_tools.py get_fundamentals, get_balance_sheet, get_cashflow, get_income_statement
news_data_tools.py get_news, get_global_news, get_insider_transactions

所有工具统一通过 route_to_vendor(method, *args) 调用,实现数据源透明切换。

4.3 数据源层

入口: tradingagents/dataflows/interface.py

route_to_vendor(method, *args)
  │
  ├─ 读取 config["data_vendors"] 确定主数据源
  ├─ 按 fallback 链依次尝试:
  │   ├─ akshare  (优先级最高)
  │   ├─ yfinance
  │   └─ alpha_vantage
  └─ 返回第一个成功结果

配置系统: tradingagents/dataflows/config.py + tradingagents/default_config.py

  • default_config.py 定义全局默认配置
  • config.py 提供运行时 get_config() / set_config() 接口
  • 可通过 set_config({"data_vendors": {"...": "akshare"}}) 动态切换

4.4 Web 服务层

文件: web_server.py

  • FastAPI 应用,端口 8500
  • POST /api/analyze — 提交分析任务(后台异步执行)
  • GET /api/task/{task_id} — 查询任务状态
  • GET / — 内置 Web 面板(web.html)

五、akshare 集成修改(详细改动点)

5.1 修改动机

原始项目的默认数据源是 yfinance,存在以下问题:

  1. 国内访问不稳定: yfinance 对非美股数据支持有限,频繁触发 Rate Limit
  2. A 股数据质量差: yfinance 的 A 股 OHLCV 数据常常缺失或不准确
  3. 新闻源偏西式: yfinance 的新闻来源主要是英文媒体,对 A 股分析不友好
  4. 无国内数据源: 缺少针对中国市场的本地化数据适配

解决方案: 集成 akshare(国内开源金融数据接口库)作为主数据源,yfinance 降级为 fallback。

5.2 文件变更清单

文件 类型 行数 说明
tradingagents/dataflows/akshare_data.py 新增 563 A股/港股/美股行情、财务数据、技术指标适配
tradingagents/dataflows/akshare_news.py 新增 165 个股新闻(东方财富)、全球新闻(CCTV)适配
tradingagents/dataflows/interface.py 修改 +22 注册 akshare 到 VENDOR_METHODS,调优 fallback 顺序
tradingagents/default_config.py 修改 +14/-8 默认 vendor 改为 akshare
web_server.py 新增 124 FastAPI Web 服务 + 后台任务
web.html 新增 480 前端分析面板

5.3 akshare_data.py 详细设计

5.3.1 市场检测

def _detect_market(symbol: str) -> str:
    """自动识别股票所属市场"""
    # 6位数字 → A股上海/深圳
    # 5位数字 → 港股
    # 字母 → 美股

通过 ticker 格式自动路由到正确的 akshare 接口:

  • 600xxx / 000xxx / 300xxx → A 股(ak.stock_zh_a_hist)
  • 00700 / 09988 → 港股(ak.stock_hk_hist)
  • AAPL / MSFT / TSLA → 美股(ak.stock_us_hist)

5.3.2 实现的接口

接口 签名 akshare 函数 说明
get_stock_data (symbol, start_date, end_date) stock_zh_a_hist / stock_hk_hist / stock_us_hist 三市场统一 OHLCV 数据
get_indicators (symbol, indicator, curr_date, look_back_days) stock_zh_a_hist + 手动计算 19 项技术指标(RSI/MACD/布林带等)
get_fundamentals (ticker, curr_date) stock_individual_info_em 公司概况/市盈率/市净率等
get_balance_sheet (ticker, freq, curr_date) stock_balance_sheet_by_report_em 资产负债表(年报/季报)
get_cashflow (ticker, freq, curr_date) stock_cash_flow_sheet_by_report_em 现金流量表
get_income_statement (ticker, freq, curr_date) stock_profit_sheet_by_report_em 利润表
get_insider_transactions (ticker) — 抛出异常触发 fallback 到 yfinance

5.3.3 技术指标计算实现

采用原始公式重算而非依赖第三方库,确保数据一致性:

rsi     → 100 - (100 / (1 + RS))               [平均涨跌幅比值法]
macd    → EMA(12) - EMA(26), Signal=EMA(9)     [指数加权移动平均]
bb      → MA ± 2*STD                            [布林带]
atr     → TR 的 Wilder 平滑                     [真实波幅]
sma_20  → MA(20)
ema_20  → EMA(20)

共支持 19 项常用技术指标,覆盖趋势类、动量类、波动类、成交量类。

5.3.4 输出格式

所有接口返回统一格式:Pandas DataFrame → Markdown 表格字符串,与 yfinance 适配器输出格式一致,保证 LLM 可正常解析。

| Date       | Open   | High   | Low    | Close  | Volume    |
|------------|--------|--------|--------|--------|-----------|
| 2026-04-25 | 12.50  | 12.80  | 12.30  | 12.65  | 12345678  |

5.3.5 TQDM 噪音抑制

akshare 内部使用 tqdm 显示进度条,在 LLM 工具调用场景中会产生大量噪音输出。通过在 akshare import 之前设置环境变量解决:

os.environ.setdefault('TQDM_DISABLE', '1')
import akshare as ak

5.4 akshare_news.py 详细设计

5.4.1 实现的接口

接口 说明 数据来源
get_news(ticker, start_date, end_date) 个股新闻 ak.stock_news_em(东方财富)
get_global_news(curr_date, look_back_days, limit) 宏观/全球新闻 ak.news_cctv(CCTV 新闻联播)

5.4.2 Ticker 规范化

600362  → 600362   (A股,不变)
000001  → 000001   (A股,不变)
AAPL    → AAPL     (美股,不变)
        → 回退到原 ticker

5.4.3 东方财富新闻接口特点

  • 返回 15 天内个股相关新闻,含标题、发布时间、来源
  • 自动按日期过滤,限制返回最近 50 条
  • 格式化输出为 Markdown 表格,便于 LLM 分析

5.4.4 CCTV 新闻接口特点

  • 获取新闻联播文字稿摘要
  • 适合宏观政策面分析
  • 输出为时间线格式的文本列表

5.5 interface.py 修改详情

5.5.1 VENDOR_METHODS 注册

为以下 9 个方法注册了 akshare 实现:

VENDOR_METHODS = {
    "get_stock_data":          {"akshare": ..., "yfinance": ..., "alpha_vantage": ...},
    "get_indicators":          {"akshare": ..., "yfinance": ...},
    "get_fundamentals":        {"akshare": ..., "yfinance": ..., "alpha_vantage": ...},
    "get_balance_sheet":       {"akshare": ..., "yfinance": ..., "alpha_vantage": ...},
    "get_cashflow":            {"akshare": ..., "yfinance": ..., "alpha_vantage": ...},
    "get_income_statement":    {"akshare": ..., "yfinance": ..., "alpha_vantage": ...},
    "get_news":                {"akshare": ..., "yfinance": ...},
    "get_global_news":         {"akshare": ..., "yfinance": ...},
    "get_insider_transactions": {"akshare": ..., "yfinance": ..., "alpha_vantage": ...},
}

5.5.2 Fallback 顺序优化

get_insider_transactions 的字典键顺序调整为 akshare → yfinance → alpha_vantage:

原始顺序: alpha_vantage → yfinance → [无 akshare]
修改后:   akshare → yfinance → alpha_vantage

原因:如果 alpha_vantage 排在 yfinance 之前,当 akshare 不支持时,会先尝试 alpha_vantage —— 它的 get_api_key() 在无 API key 时会抛出 ValueError(非 AlphaVantageRateLimitError),导致异常直接传播、不会继续尝试 yfinance。

调整后 fallback 路径:

  1. akshare → 抛出 AlphaVantageRateLimitError(触发 fallback)
  2. yfinance → 获取数据(成功)✓

5.5.3 数据源分类优化

将 akshare 明确归入 all_available_vendors,确保它在所有 data_vendors 分类组中可用:

all_available_vendors = ["akshare", "yfinance", "alpha_vantage"]

5.6 default_config.py 修改

# 修改前
"data_vendors": {
    "core_stock_data": {"primary": "yfinance"},
    "technical_indicators": {"primary": "yfinance"},
    "fundamental_data": {"primary": "yfinance"},
    "news_data": {"primary": "yfinance"},
}

# 修改后
"data_vendors": {
    "core_stock_data": {"primary": "akshare"},
    "technical_indicators": {"primary": "akshare"},
    "fundamental_data": {"primary": "akshare"},
    "news_data": {"primary": "akshare"},
}

效果:所有分析请求默认走 akshare,彻底避免 yfinance Rate Limit 问题。

5.7 web_server.py 设计

5.7.1 API 端点

方法 路径 说明
GET / Web 分析面板(web.html)
GET /api/health 健康检查
POST /api/analyze 提交分析任务,返回 task_id
GET /api/task/{task_id} 查询任务状态和结果

5.7.2 异步任务机制

class AnalysisRequest(BaseModel):
    ticker: str              # 股票代码
    date: Optional[str]      # 分析日期,默认今天
    analysts: Optional[list] # 分析师列表,默认 ["market", "news"]
    max_debate_rounds: int   # 辩论轮次,默认 1

分析流程在 BackgroundTasks 中异步执行,通过线程安全的 tasks_store 字典管理任务状态。

5.8 web.html 设计

  • 纯原生 HTML/CSS/JS 单页应用
  • 响应式设计,支持移动端
  • 输入框:股票代码 + 日期 + 分析师选择 + 辩论轮次
  • 实时轮询任务状态(每 3 秒)
  • 结果展示:Markdown 渲染的交易决策和分析报告(使用 marked.js)
  • 适配 DeepSeek 推理过程的 reasoning_content 展示

六、部署架构

                     http://129.211.173.87:8500/
                              │
                     ┌────────┴────────┐
                     │   web_server.py  │
                     │   (FastAPI)      │
                     │   port :8500     │
                     └────────┬────────┘
                              │
                     ┌────────┴────────┐
                     │  TradingAgents  │
                     │  Graph          │
                     │  (LangGraph)    │
                     └──────┬─────────┘
                            │
                ┌───────────┼───────────┐
                ▼           ▼           ▼
          ┌─────────┐ ┌─────────┐ ┌─────────┐
          │ akshare │ │yfinance │ │ alpha   │
          │ (主要)  │ │(备用1)  │ │vantage  │
          └─────────┘ └─────────┘ └─────────┘
  • 进程管理: systemd tradingagents.service
  • LLM 后端: DeepSeek(通过 DEEPSEEK_API_KEY 环境变量)
  • 数据源: akshare(默认,国内数据丰富)+ yfinance(fallback,美股内部交易等场景)

七、修改前后对比

维度 修改前 修改后
默认数据源 yfinance akshare
A 股行情 不稳定,频繁 Rate Limit ✅ 稳定,无限制
A 股财务数据 ❌ 不可用 ✅ 完整(资产负债表/利润表/现金流)
技术指标 依赖 yfinance 返回 ✅ 原始公式重算,19 项指标
个股新闻 英文来源,A 股覆盖差 ✅ 东方财富,中文,时效性强
宏观新闻 英文来源 ✅ CCTV 新闻联播,政策面
港股支持 部分 ✅ 完整
Rate Limit 频繁触发 ✅ 已消除
内部交易 yfinance akshare 自动 fallback 到 yfinance
Web UI ❌ 无 ✅ 新增 FastAPI + Web 面板
任务异步 ❌ 无 ✅ 后台任务 + 状态查询
TQDM 噪音 — ✅ 已抑制

八、项目目录结构

TradingAgents/
├── tradingagents/
│   ├── agents/
│   │   ├── analysts/                   # 四个分析师角色
│   │   │   ├── fundamentals_analyst.py
│   │   │   ├── market_analyst.py
│   │   │   ├── news_analyst.py
│   │   │   └── social_media_analyst.py
│   │   └── utils/                      # 工具定义和 LLM 封装
│   │       ├── agent_utils.py          # LLM 调用 + ToolKit
│   │       ├── core_stock_tools.py     # get_stock_data
│   │       ├── technical_indicators_tools.py  # get_indicators
│   │       ├── fundamental_data_tools.py      # 财务分析工具
│   │       └── news_data_tools.py             # 新闻工具
│   ├── dataflows/                      # 数据源层
│   │   ├── interface.py                # 路由分发 + VENDOR_METHODS
│   │   ├── config.py                   # 运行时配置
│   │   ├── akshare_data.py             # 🆕 akshare 行情+财务适配
│   │   ├── akshare_news.py             # 🆕 akshare 新闻适配
│   │   ├── yfinance_news.py            # yfinance 新闻
│   │   ├── y_finance.py                # yfinance 行情
│   │   └── alpha_vantage*.py           # Alpha Vantage 适配
│   ├── graph/                          # LangGraph 编排
│   │   ├── trading_graph.py            # 主图定义
│   │   └── setup.py                    # 图工厂
│   └── default_config.py               # 默认配置(已改为 akshare)
├── docs/                               # 文档
│   ├── architecture-and-modifications.md  # 🆕 本文档
│   └── ...
├── web_server.py                       # 🆕 FastAPI Web 服务
├── web.html                            # 🆕 前端面板
└── pyproject.toml                      # 依赖管理

九、关键代码路径

功能 起点 链路
用户提交分析 web_server.py:94 POST /api/analyze → run_analysis_task → TradingAgentsGraph.propagate()
获取行情数据 core_stock_tools.py:get_stock_data → route_to_vendor("get_stock_data", ...) → akshare_data.get_stock_data()
获取技术指标 technical_indicators_tools.py:get_indicators → route_to_vendor → akshare_data.get_indicators()
获取财务数据 fundamental_data_tools.py:get_fundamentals → route_to_vendor → akshare_data.get_fundamentals()
获取新闻 news_data_tools.py:get_news → route_to_vendor → akshare_news.get_news()
数据源切换 interface.py:route_to_vendor 按 config → fallback 链尝试