Aekor

Aekor
专注于用户阅读体验的响应式博客主题
  1. 首页
  2. TradingAgents-CN
  3. 正文

TradingAgents-CN 项目优化:多数据源架构完善与实时数据增强(10-28)

2025-10-29 5930点热度 0人点赞 0条评论

一、升级概览

2025 年 10 月 28 日,TradingAgents-CN 完成了一次重要的 系统架构升级。

本次更新通过 25 个提交,围绕 多数据源隔离存储、实时 PE/PB 计算优化、K 线图实时数据支持、实时行情同步状态追踪 等核心能力展开,进一步提升了系统的 数据完整性、实时性和可靠性。

核心改进

  • 多数据源隔离存储架构:解决 Tushare、AKShare、BaoStock 数据互相覆盖和索引冲突问题。
  • 实时 PE/PB 计算优化:引入实时计算、数据库缓存、历史数据三层回退策略。
  • K 线图实时数据支持:日线图可自动融合当天实时行情。
  • 实时行情同步状态追踪:前端展示同步状态、最后同步时间和错误信息。
  • 基本面快照增强:新增动态 PS、市销率、TTM 收入、净利润、净资产、ROE 等指标。
  • 导出文件名统一:所有报告导出文件采用统一命名格式。

二、多数据源隔离存储架构

2.1 问题背景

相关提交:

  • 279937659:实现 多数据源隔离存储设计。
  • 253d60346:修复多数据源同步的 MongoDB 连接和索引冲突问题。
  • 08bbee6eb:修复多数据源同步的数据一致性问题。
  • 86e67b49a:行业列表接口支持数据源优先级。

系统支持 Tushare、AKShare、BaoStock 三个数据源,但此前存在严重的数据覆盖和索引冲突问题。

主要问题

1. 数据互相覆盖

此前 stock_basic_info 使用 code 作为唯一索引。
同一只股票如果分别从 Tushare、AKShare、BaoStock 同步,后同步的数据会覆盖先同步的数据。

这会导致:

  • 不同数据源无法独立保存。
  • 数据源之间互相污染。
  • 无法比较不同数据源的数据差异。

2. 数据源优先级不统一

不同模块可能使用不同数据源,导致查询结果不一致。

例如:

  • 股票详情页使用 Tushare。
  • 筛选页使用 AKShare。
  • 行业列表使用 BaoStock。

用户看到的数据就会出现混乱。

3. MongoDB 索引冲突

多数据源同步时,容易出现类似错误:

E11000 duplicate key error collection: tradingagents.stock_basic_info
index: code_1 dup key: { code: "000001" }

根本原因是 code 唯一索引无法支持同一股票在多个数据源中分别存储。

2.2 解决方案

核心思路是:在同一个集合中,通过 (code, source) 联合唯一索引 实现数据源隔离。

db.stock_basic_info.createIndex(
  { "code": 1, "source": 1 },
  { unique: true }
)

db.stock_basic_info.createIndex({ "code": 1 })
db.stock_basic_info.createIndex({ "source": 1 })

新的数据结构如下:

{
  "code": "000001",
  "source": "tushare",
  "name": "平安银行",
  "industry": "银行",
  "list_date": "19910403"
}

这样,同一只股票可以同时存在多条记录:

  • 000001 + tushare
  • 000001 + akshare
  • 000001 + baostock

彼此不会覆盖。

2.3 索引迁移

新增迁移脚本:

scripts/migrations/migrate_stock_basic_info_add_source_index.py

迁移逻辑包括:

  1. 删除旧的 code_1 唯一索引。
  2. 创建新的 (code, source) 联合唯一索引。
  3. 创建 code 和 source 辅助索引。
  4. 保证旧数据可以平滑迁移。

2.4 数据源优先级查询

系统在未指定数据源时,按优先级自动查询。

默认优先级为:

source_priority = ["tushare", "multi_source", "akshare", "baostock"]

示例逻辑:

if source:
    query = {"code": symbol6, "source": source}
    doc = await db["stock_basic_info"].find_one(query, {"_id": 0})
else:
    source_priority = ["tushare", "multi_source", "akshare", "baostock"]
    doc = None

    for src in source_priority:
        query = {"code": symbol6, "source": src}
        doc = await db["stock_basic_info"].find_one(query, {"_id": 0})
        if doc:
            break

2.5 多数据源同步修复

同步时使用 (code, source) 作为更新条件。

UpdateOne(
    {"code": stock["code"], "source": source},
    {"$set": stock},
    upsert=True
)

2.6 优化效果

  • 同一股票可以保留多个数据源版本。
  • 彻底解决 MongoDB 唯一索引冲突。
  • 支持指定数据源查询,也支持按优先级自动查询。
  • 避免不同数据源互相覆盖。
  • 为后续数据源对比和质量评估打下基础。

三、实时 PE/PB 计算优化

3.1 问题背景

相关提交:

  • f42fc1f61:修复 实时市值和 PE/PB 计算逻辑。
  • 18727ef3c:完善实时 PE/PB 计算的回退策略。
  • 2460f47dc:添加实时 PE/PB 计算与回退策略博文。

此前实时估值指标存在几个问题:

  • 实时股价可能为空。
  • 财务数据可能未同步。
  • 总股本数据可能缺失。
  • 单位转换容易出错。
  • 计算失败后直接返回空值,用户看不到任何数据。

3.2 三层回退策略

新的实时 PE/PB 计算采用 三层回退策略:

  1. 优先使用实时股价计算。
  2. 如果失败,使用数据库缓存值。
  3. 如果仍失败,使用历史数据兜底。
result = {
    "pe": None,
    "pb": None,
    "total_mv": None,
    "data_source": None
}

当实时计算成功时:

result.update({
    "pe": pe,
    "pb": pb,
    "total_mv": total_mv,
    "data_source": "realtime_calculated"
})

如果实时计算失败,则依次尝试:

  • database_cached
  • historical_data

3.3 实时市值计算修复

实时市值计算逻辑:

total_mv = (total_share * current_price) / 10000

其中:

  • total_share 单位为 万股。
  • current_price 单位为 元。
  • total_mv 最终单位为 亿元。

PE 计算:

net_profit_billion = net_profit / 100000000
pe = total_mv / net_profit_billion

PB 计算:

net_assets_billion = net_assets / 100000000
pb = total_mv / net_assets_billion

3.4 优化效果

  • 实时市值计算更准确。
  • PE/PB 单位转换更清晰。
  • 计算失败时不会直接空白,而是自动回退。
  • 每个结果都有明确的数据来源标识。
  • 用户在前端看到的估值指标更稳定。

四、K 线图实时数据支持

4.1 功能背景

相关提交:

  • 389e7ddea:K 线图支持当天实时数据,并修复同步时间时区显示。

此前 K 线图主要依赖历史数据。如果当天历史数据尚未同步,用户在交易时间内无法看到最新 K 线。

这会导致:

  • 盘中 K 线不更新。
  • 收盘后当天数据可能缺失。
  • 用户需要等待历史同步完成。

4.2 实现方案

日线图在返回历史 K 线时,会额外检查 market_quotes 中是否有当天实时行情。

核心逻辑:

if period == "day" and items:
    today_str = now.strftime("%Y%m%d")

    has_today_data = any(
        item.get("time") == today_str
        for item in items
    )

    is_trading_time = (
        dtime(9, 30) <= current_time <= dtime(15, 0)
        and now.weekday() < 5
    )

    should_fetch_realtime = is_trading_time or not has_today_data

如果需要实时数据,则从 market_quotes 构造当天 K 线:

today_kline = {
    "time": today_str,
    "open": float(realtime_quote.get("open", 0)),
    "high": float(realtime_quote.get("high", 0)),
    "low": float(realtime_quote.get("low", 0)),
    "close": float(realtime_quote.get("close", 0)),
    "volume": float(realtime_quote.get("volume", 0)),
    "amount": float(realtime_quote.get("amount", 0))
}

如果历史数据中已经有当天记录,则替换;如果没有,则追加并重新排序。

4.3 优化效果

  • 交易时间内可以显示实时日 K 数据。
  • 收盘后可自动补充当天数据。
  • 无需等待历史数据同步完成。
  • K 线图体验更接近实时行情软件。

五、实时行情同步状态追踪

5.1 功能背景

相关提交:

  • 7fa9fd1af:实时行情同步状态追踪和收盘后缓冲期。
  • 375a4eaca:前端个股详情页显示实时行情同步状态。
  • a7a0f5cba:修复实时行情同步状态 API 路由冲突。

用户需要知道行情数据是否已经同步、什么时候同步、同步是否失败。

因此系统新增 实时行情同步状态追踪。

5.2 后端状态追踪

后端维护以下状态:

self.last_sync_time = None
self.sync_status = "idle"  # idle, syncing, success, error
self.sync_error = None

同步成功后记录:

self.last_sync_time = datetime.now(ZoneInfo("Asia/Shanghai"))
self.sync_status = "success"

同步失败则记录:

self.sync_status = "error"
self.sync_error = str(e)

5.3 收盘后 30 分钟缓冲期

同步时间范围为:

  • 交易时间:9:30 - 15:00
  • 收盘缓冲期:15:00 - 15:30
  • 周末不自动同步
return dtime(9, 30) <= current_time <= dtime(15, 30)

这样可以覆盖收盘后行情数据延迟更新的情况。

5.4 前端状态显示

个股详情页新增同步状态标签,展示:

  • 同步中
  • 已同步
  • 同步失败
  • 空闲
  • 最后同步时间

并且每 30 秒自动刷新一次状态。

5.5 优化效果

  • 用户可以看到实时行情同步状态。
  • 可以看到最后同步时间。
  • 同步失败时更容易定位问题。
  • 收盘后 30 分钟缓冲期提升数据完整性。
  • 前端状态自动刷新,体验更清晰。

六、其他功能优化

6.1 为 stock_basic_info 添加 symbol 字段

相关提交:

  • 7bcc6d08e:为 stock_basic_info 集合添加 symbol 字段。
  • c0a3aadc2:修复迁移脚本并验证 601899 股票信息。

新增字段示例:

{
  "code": "000001",
  "symbol": "sz000001",
  "source": "tushare"
}

其中:

  • code 是 6 位股票代码。
  • symbol 是带市场前缀的完整代码。

这有助于适配不同数据源的代码格式。

6.2 基本面快照接口增强

相关提交:

  • 41f5d7fdd:增强基本面快照接口,添加市销率和财务指标。
  • c68539e63:基本面快照接口使用动态计算 PS。

新增能力包括:

  • 动态计算 PS 市销率。
  • 新增 营业收入 TTM。
  • 新增 净利润 TTM。
  • 新增 净资产。
  • 新增 ROE 净资产收益率。

动态 PS 计算逻辑:

ps = total_mv / revenue_ttm if revenue_ttm else None

6.3 统一导出报告文件名格式

相关提交:

  • 65c88a29f:统一所有页面的导出报告文件名格式。

统一格式:

TradingAgents_报告类型_股票代码_日期时间.pdf

示例:

TradingAgents_分析报告_000001_20251028_143052.pdf
TradingAgents_批量分析_20251028_143052.pdf

6.4 股票名称获取增强

相关提交:

  • b7838214:增强股票名称获取的错误处理和降级逻辑。

股票名称获取采用多层降级:

  1. 从 stock_basic_info 获取。
  2. 从 market_quotes 获取。
  3. 如果都失败,则使用股票代码作为后备。

七、统计数据

7.1 提交统计

指标数量
总提交数25
修改文件数60+
新增代码3500+ 行
删除代码500+ 行
净增代码3000+ 行

7.2 功能分类

分类数量
多数据源架构6 项改进
实时数据8 项增强
PE/PB 计算3 项优化
K 线图1 项新功能
其他优化7 项改进

八、技术亮点

8.1 多数据源隔离存储设计

核心设计:

db.stock_basic_info.createIndex(
  { "code": 1, "source": 1 },
  { unique: true }
)

优势:

  • 同一股票可保留多个数据源版本。
  • 数据不会互相覆盖。
  • 查询时可指定数据源,也可按优先级自动选择。

8.2 实时 PE/PB 三层回退策略

回退顺序:

  1. 实时股价计算,最准确。
  2. 数据库缓存值,作为次优选择。
  3. 历史数据,作为保底方案。

8.3 K 线图实时数据融合

策略:

  • 交易时间内:从 market_quotes 获取实时数据。
  • 收盘后:如果历史数据未同步,则补充当天数据。
  • 非交易日:只展示历史数据。

8.4 同步状态追踪

能力:

  • 记录同步状态。
  • 记录最后同步时间。
  • 支持错误信息展示。
  • 前端自动刷新。
  • 支持收盘后 30 分钟缓冲期。

九、总结

本次更新通过 25 个提交,完成了 多数据源架构 与 实时数据能力 的重要升级。

主要成果包括:

  • 多数据源隔离存储:通过 (code, source) 联合唯一索引,解决数据覆盖和索引冲突。
  • 数据源优先级查询:未指定数据源时,按 Tushare、multi_source、AKShare、BaoStock 的顺序自动查询。
  • 实时 PE/PB 优化:引入实时计算、缓存值、历史数据三层回退策略。
  • K 线图实时数据支持:日线图自动融合当天 market_quotes 实时行情。
  • 实时行情同步状态追踪:前端展示同步状态、最后同步时间和错误信息。
  • 基本面快照增强:新增 PS、营业收入 TTM、净利润 TTM、净资产、ROE 等指标。
  • 导出文件名统一:所有报告导出命名更加规范。
  • 股票名称获取增强:通过多层降级提高显示稳定性。

这些改进显著提升了 TradingAgents-CN 的 数据完整性、实时性、可靠性和用户体验,也为后续更多数据源接入、实时行情增强和基本面分析升级打下了更扎实的基础。

✅ 官方唯一渠道:📦 GitHub 仓库:https://github.com/hsliuping/TradingAgents-CN

Aekor AI-API 中转站,让全球顶尖 AI 大模型“触手可及”!你是否曾为这些烦恼头疼?

🔹 人在国内,却总被海外官网 API 的高延迟、掉线、甚至无法访问困扰?

🔹 想用最强的 GPT、Claude 等模型,却卡在海外信用卡、支付审核等重重阻碍?

🔹 官方 API 太贵?Aekor 为你打通“网络-支付-成本”的任督二脉!

💡 Aekor 核心价值:好用、便宜、快 💡

🚀 高速稳定,告别掉线国内专线加速,API 响应低延迟,告别「转圈圈」的焦虑,开发效率瞬间拉满!

🧠 顶尖模型,随需而调涵盖 GPT 系列、Claude 系列等全球主流大厂模型,一次接入,轻松调用!

🎁 免费白嫖,诚意拉满!

注册即送 20 美元体验额度,够你狠狠测试一轮模型质量与线路稳定性了!

🚪 入口:https://api.aekor.com

⚠️ 温馨提示:API 中转市场虽多但良莠不齐(甚至有些会偷工减料换小模型糊弄事儿)。Aekor 坚持提供正版稳定的服务,但还是建议:先用免费的 20 刀测试是否契合自身需求,满意了再小额充值上车,理性消费不盲目。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: AkShare BaoStock K线图实时数据 market_quotes MongoDB索引 TradingAgents-CN Tushare 多数据源架构 实时PB计算 实时PE计算
最后更新:2026-07-03

Aekor

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

使用AI教程

  • API报错解决方案
  • API 基础知识
  • API Key 获取

分类

  • Blog
  • TradingAgents-CN
  • 使用教程

COPYRIGHT © 2026 Aekor. ALL RIGHTS RESERVED.