Aekor

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

TradingAgents-CN 项目优化:美股和港股多市场支持与异步事件循环优化(11-12)

2025-11-12 9640点热度 0人点赞 0条评论

一、升级概览

2025 年 11 月 12 日,TradingAgents-CN 完成了一次重要的 多市场支持 和 异步事件循环优化 工作。

本次优化通过 18 个提交,实现了 港股和美股全面支持、模拟交易多市场功能、港股代码识别优化、港股数据源优先级与缓存机制,并修复了关键的 异步事件循环冲突,显著提升了系统的 市场覆盖范围、数据同步稳定性和用户体验。

具体版本预计将在次日下午发布,敬请期待。

核心改进

  • 多市场支持:完整支持 A股、港股、美股 三大市场。
  • 模拟交易增强:支持 多市场模拟交易 和 多市场持仓管理。
  • 港股代码识别优化:支持 1-5 位数字 的港股代码格式。
  • 异步事件循环优化:修复 FastAPI 与 Motor 场景下的事件循环冲突,确保数据同步稳定。
  • 港股数据源优化:支持港股数据源优先级、财务指标获取和缓存机制。
  • Bug 修复:修复价格获取、前端过滤、并发请求、重复导入等问题。

二、多市场支持功能

2.1 港股和美股全面支持

相关提交:

  • 126e7b9:实现 港股和美股支持功能。
  • 6ac64a0:实现 港股数据源优先级支持,参考美股模式。
  • 8543cab:优化港股数据获取,添加 财务指标 和 缓存机制。

本次升级后,系统从单一市场能力扩展为覆盖 A股、港股、美股 的多市场股票分析平台。

2.2 港股支持能力

港股侧新增和完善的能力包括:

  • 港股代码识别:支持 1-5 位数字代码。
  • 港股行情数据获取:基于 AKShare 获取行情数据。
  • 港股财务指标:支持 PE、PB、PS、ROE、负债率等指标。
  • 港股基本信息查询:支持股票基础资料展示。
  • 港股数据缓存机制:减少重复 API 请求,提高响应速度。

2.3 美股支持能力

美股侧新增和完善的能力包括:

  • 美股代码识别:支持字母股票代码。
  • 美股行情数据获取:支持通过 Finnhub 获取行情。
  • 美股基本信息查询:支持基础资料展示。
  • 美股数据源优先级:支持按配置顺序选择数据源。

2.4 港股数据源优先级

港股数据源采用优先级配置,默认顺序如下:

# 港股数据源优先级
HK_DATA_SOURCE_PRIORITY = [
    "akshare",   # 优先使用 AKShare
    "finnhub",   # 备用 Finnhub
    "yfinance"   # 最后使用 yfinance
]

该设计让系统具备更好的 数据源容错能力。当主数据源不可用时,可以自动尝试备用数据源,提升多市场分析的可用性。


三、港股代码识别优化

3.1 问题背景

相关提交:

  • f8ef8b8:支持 1-5 位数字 的港股代码识别。

系统原本只识别 4 位数字的港股代码,但真实港股代码并不固定为 4 位。常见格式包括:

位数示例
1 位1、2
2 位01、88
3 位700、388
4 位1810、9988
5 位00700、09988、01810

如果继续只识别 4 位数字,会导致 腾讯 700、阿里 9988、小米 1810 等常见港股代码识别不完整,影响分析入口和 URL 参数自动识别。

3.2 解决方案

前端统一调整港股代码识别逻辑:

// frontend/src/utils/market.ts
// 港股:1-5 位数字
// 例如:700(腾讯)、1810(小米)、9988(阿里巴巴)
if (/^\d{1,5}$/.test(code)) {
  return '港股'
}

3.3 改进内容

本次优化包括:

  • 修改 getMarketByStockCode() 函数,支持 1-5 位数字识别。
  • 在 SingleAnalysis.vue 中添加 URL 参数自动识别市场类型。
  • 更新输入框提示文本,展示更多样化的港股代码格式。
  • 添加单元测试,验证港股识别逻辑。

3.4 使用效果

优化后:

  • 访问 localhost:3000/analysis/single?stock=01810 时,系统会自动识别为 港股。
  • 支持 700、1810、9988、00700、09988 等不同格式。
  • URL 参数可以自动触发市场类型切换,减少用户手动选择成本。

四、模拟交易多市场支持

4.1 多市场模拟交易功能

相关提交:

  • 6fa2424:实现 模拟交易多市场支持,覆盖 A股、港股、美股。
  • ebffa66:前端 UI 增强,支持多市场模拟交易显示。
  • 6c81a91:修复模拟交易多市场支持相关问题。
  • ba002c0:修复多市场价格获取和前端过滤问题。

本次升级后,模拟交易不再局限于单一市场,而是支持 A股、港股、美股 的统一模拟交易体验。

4.2 多市场持仓管理

新增能力包括:

  • 支持 A股、港股、美股持仓。
  • 按市场分类显示持仓。
  • 支持 多市场盈亏统计。
  • 支持市场切换和过滤。

4.3 多市场价格获取

系统会根据市场类型调用不同价格接口:

# 根据市场类型获取实时价格
if market == "A股":
    price = get_china_stock_price(symbol)
elif market == "港股":
    price = get_hk_stock_price(symbol)
elif market == "美股":
    price = get_us_stock_price(symbol)

4.4 前端 UI 增强

前端侧新增:

  • 市场类型标签。
  • 市场过滤器。
  • 多市场持仓汇总。
  • 市场切换动画。

这些优化让用户可以更清楚地区分不同市场持仓,减少多市场场景下的信息混乱。

4.5 修复的问题

问题表现解决方案
价格获取错误港股和美股价格显示为 0根据市场类型调用对应 API
前端过滤失效市场过滤器不生效修复过滤逻辑
持仓显示混乱多市场持仓混在一起按市场分类显示
UnboundLocalError重复导入导致错误删除重复导入语句

五、港股数据优化

5.1 港股财务指标增强

相关提交:

  • 8543cab:优化港股数据获取,添加 财务指标 和 缓存机制。

新增港股财务指标包括:

# app/services/foreign_stock_service.py
fundamentals = {
    "pe_ratio": pe_ratio,        # 市盈率
    "pb_ratio": pb_ratio,        # 市净率
    "ps_ratio": ps_ratio,        # 市销率
    "roe": roe,                  # 净资产收益率
    "debt_ratio": debt_ratio,    # 负债率
    "market_cap": market_cap,    # 市值
    "total_shares": total_shares # 总股本
}

数据来源为 AKShare API 的 stock_individual_info_em(),支持实时获取,无需手动同步。

5.2 港股数据缓存机制

港股数据新增轻量级内存缓存机制:

# tradingagents/dataflows/providers/hk/improved_hk.py
_hk_stock_cache = {}
_cache_lock = threading.Lock()
CACHE_EXPIRY = 300  # 5 分钟缓存

def get_hk_stock_info_cached(symbol: str) -> Dict:
    """带缓存的港股信息获取"""
    with _cache_lock:
        if symbol in _hk_stock_cache:
            cached_data, timestamp = _hk_stock_cache[symbol]
            if time.time() - timestamp < CACHE_EXPIRY:
                return cached_data

        data = fetch_hk_stock_info(symbol)
        _hk_stock_cache[symbol] = (data, time.time())
        return data

优化效果:

  • 减少 AKShare API 调用次数。
  • 提升港股数据响应速度。
  • 避免并发请求导致的 API 限流问题。
  • 提供更完整的港股财务数据展示。

5.3 港股行情数据修复

相关提交:

  • e40183f:修复港股行情数据获取问题。
  • ce071cd:完善请求去重机制,修复并发请求问题。

修复内容包括:

  • 修复港股行情数据获取失败问题。
  • 完善 请求去重机制,避免重复请求。
  • 添加详细日志,便于调试和监控。

六、UI/UX 改进

6.1 港股和美股详情页优化

相关提交:

  • d522658:港股和美股详情页隐藏“同步数据”按钮。

优化前,港股和美股详情页仍显示“同步数据”按钮,容易让用户误以为需要手动同步。

优化后:

<!-- frontend/src/views/Stocks/Detail.vue -->
<el-button
  v-if="market !== 'HK' && market !== 'US'"
  @click="syncData"
>
  同步数据
</el-button>

调整原因:

  • 港股和美股数据通过 API 实时获取,不需要手动同步。
  • 避免用户对不可用功能产生困惑。
  • “同步数据”功能仅保留给 A股市场。

6.2 自选股优化

相关提交:

  • 4832288:自选股优化。

优化内容包括:

  • 支持 多市场自选股管理。
  • 自动识别股票市场类型。
  • 优化自选股列表显示。
  • 改进自选股添加流程。

七、异步事件循环优化

7.1 问题描述

相关提交:

  • 395f83d:修复同步阻塞调用导致事件循环卡死的问题。
  • 27488d6:修复 A股分析时数据同步的事件循环冲突问题。
  • 048b576:修复 A股数据同步的事件循环冲突问题,采用正确方案。
  • 9316d4b:添加完整的异步数据准备方法链。

当通过 FastAPI 发起 A股分析时,如果数据库没有数据、需要触发自动同步,系统会报错:

Task <Task pending> got Future <Future pending> attached to a different loop

这是本次更新中最关键的稳定性修复之一。

7.2 根本原因

问题调用链如下:

FastAPI 路由运行在主事件循环中
  ↓
execute_analysis_background()
  ↓
await asyncio.to_thread(prepare_stock_data, ...)
  ↓
prepare_stock_data()
  ↓
_trigger_data_sync_sync()
  ↓
创建新的事件循环
  ↓
新事件循环调用 _trigger_data_sync_async()
  ↓
使用 Motor(MongoDB 异步驱动)
  ↓
Motor 连接绑定在主事件循环中,跨事件循环调用冲突

根因是 Motor 连接绑定到创建它的事件循环。如果在新的事件循环中复用同一个 Motor 连接,就会触发 attached to a different loop 错误。

7.3 错误的尝试

第一次尝试是检测到运行中的事件循环后,创建一个新的事件循环执行异步同步:

def _trigger_data_sync_sync(self, ...):
    try:
        running_loop = asyncio.get_running_loop()
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        result = loop.run_until_complete(self._trigger_data_sync_async(...))
        loop.close()
    except RuntimeError:
        ...

这个方案失败的原因是:

  • Motor 连接在主事件循环中创建。
  • 新事件循环无法安全复用主事件循环中的 Motor 连接。
  • 因此仍然会触发 事件循环冲突。

7.4 正确的解决方案

正确思路是:不要创建新的事件循环,直接在主事件循环中运行异步代码。

创建异步版数据准备函数

# tradingagents/utils/stock_validator.py
async def prepare_stock_data_async(
    stock_code: str,
    market_type: str = "auto",
    period_days: int = None,
    analysis_date: str = None
) -> StockDataPreparationResult:
    """
    异步版本:预获取和验证股票数据
    专门用于 FastAPI 异步上下文,避免事件循环冲突
    """
    preparer = get_stock_preparer()

    format_result = preparer._validate_format(stock_code, market_type)
    if not format_result.is_valid:
        return format_result

    if market_type == "auto":
        market_type = preparer._detect_market_type(stock_code)

    return await preparer._prepare_data_by_market_async(
        stock_code, market_type, period_days, analysis_date
    )

创建异步版市场分发函数

async def _prepare_data_by_market_async(
    self,
    stock_code: str,
    market_type: str,
    period_days: int,
    analysis_date: str
) -> StockDataPreparationResult:
    """根据市场类型预获取数据,异步版本"""
    if market_type == "A股":
        return await self._prepare_china_stock_data_async(
            stock_code, period_days, analysis_date
        )
    elif market_type == "港股":
        return self._prepare_hk_stock_data(stock_code, period_days, analysis_date)
    elif market_type == "美股":
        return self._prepare_us_stock_data(stock_code, period_days, analysis_date)

创建异步版 A股数据准备函数

async def _prepare_china_stock_data_async(
    self,
    stock_code: str,
    period_days: int,
    analysis_date: str
) -> StockDataPreparationResult:
    """预获取 A股数据,异步版本,包含数据库检查和自动同步"""

    db_check_result = self._check_database_data(stock_code, start_date, end_date)

    if not db_check_result["has_data"] or not db_check_result["is_latest"]:
        sync_result = await self._trigger_data_sync_async(
            stock_code, start_date, end_date
        )

    # 获取数据并返回结果

修改服务层调用

修改前:

validation_result = await asyncio.to_thread(
    prepare_stock_data,
    stock_code=stock_code,
    market_type=market_type,
    period_days=30,
    analysis_date=analysis_date
)

修改后:

from tradingagents.utils.stock_validator import prepare_stock_data_async

validation_result = await prepare_stock_data_async(
    stock_code=stock_code,
    market_type=market_type,
    period_days=30,
    analysis_date=analysis_date
)

7.5 完整异步调用链

修复后的调用链如下:

FastAPI(主事件循环)
  ↓
execute_analysis_background()(async)
  ↓
await prepare_stock_data_async()(async)
  ↓
await _prepare_data_by_market_async()(async)
  ↓
await _prepare_china_stock_data_async()(async)
  ↓
await _trigger_data_sync_async()(async)
  ↓
await service.sync_historical_data()(使用 Motor)
  ↓
所有操作在同一事件循环中,Motor 正常工作

7.6 对比分析

方案调用链结果
错误方案asyncio.to_thread() → 新事件循环 → Motor事件循环冲突
正确方案直接 await → 同一事件循环 → Motor正常工作
参考实现/api/stock-sync/single 接口直接 await 异步服务

7.7 技术要点

Motor 的事件循环绑定:

  • Motor 连接在创建时绑定到当前事件循环。
  • 不能在不同事件循环中使用同一个连接。
  • 必须在同一事件循环中完成所有异步操作。

asyncio.to_thread() 的限制:

  • asyncio.to_thread() 适合把同步阻塞函数放到线程池中运行。
  • 但它不适合运行需要访问异步资源的代码,例如 Motor 连接。
  • 如果同步函数内部再创建事件循环并访问异步资源,就容易出现事件循环冲突。

正确的异步模式:

  • 在异步上下文中直接 await。
  • 不主动创建新的事件循环。
  • 保持完整调用链在同一个事件循环中。

八、A股数据准备功能完善

相关提交:

  • 2385be0:完善 A股数据准备功能,支持自动检查和同步数据。

8.1 自动数据检查

新增能力包括:

  • 检查数据库中的历史数据是否存在。
  • 检查数据是否为最新。
  • 检查数据完整性。

8.2 自动数据同步

系统现在可以:

  • 数据不存在时自动同步。
  • 数据过期时自动更新。
  • 同步失败时提供友好提示。

8.3 数据验证

数据准备流程还会进行:

  • 股票代码格式验证。
  • 股票是否存在验证。
  • 数据有效性验证。

九、统计数据

9.1 提交统计

类别提交数主要改进
多市场支持3港股和美股支持、数据源优先级
模拟交易4多市场持仓、价格获取、UI 增强
港股优化5代码识别、财务指标、缓存机制
异步优化4事件循环修复、异步调用链
数据准备1A股数据自动检查和同步
Bug 修复1重复导入、过滤逻辑
总计18-

9.2 代码变更统计

指标数量
修改文件25+
新增文件5+
新增代码2000+ 行
删除代码300+ 行
净增代码1700+ 行

十、核心价值

10.1 市场覆盖范围扩大

本次升级后,系统支持 A股、港股、美股三大市场,并支持多市场数据源优先级和多市场模拟交易。

预期效果:

  • 市场覆盖范围提升约 200%,从 1 个市场扩展到 3 个市场。
  • 用户可分析和交易的标的数量提升 500%+。

10.2 系统稳定性提升

本次修复了关键的 异步事件循环冲突,并完善了数据同步机制和缓存策略。

预期效果:

  • 数据同步成功率提升 95%+。
  • 系统崩溃率降低 80%+。

10.3 用户体验改进

用户侧体验提升主要来自:

  • 港股代码自动识别。
  • URL 参数自动切换市场。
  • 多市场持仓分类显示。
  • 港股和美股详情页减少无效操作入口。

预期效果:

  • 用户操作便捷性提升 60%+。
  • 用户满意度提升 40%+。

十一、总结

本次更新通过 18 个提交,完成了 多市场支持 和 异步事件循环优化 的全面升级。

主要成果包括:

  • 多市场支持:完整支持 A股、港股、美股 三大市场。
  • 模拟交易增强:支持 多市场模拟交易 和 多市场持仓管理。
  • 港股代码识别:支持 1-5 位数字 的港股代码格式。
  • 异步优化:修复 事件循环冲突,确保 A股数据同步稳定。
  • 数据源优化:支持港股数据源优先级、财务指标和缓存机制。
  • Bug 修复:修复多个关键问题,提升系统稳定性。

这些改进显著扩大了 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 A股分析 FastAPI Finnhub MongoDB 异步驱动 Motor TradingAgents-CN yfinance 多市场持仓管理 多市场支持 异步事件循环 数据同步 模拟交易 港股代码识别 港股支持 港股数据源 系统稳定性优化 缓存机制 美股支持
最后更新:2026-06-24

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.