TradingAgents-CN 股票代码格式验证与标准化:A股、美股、港股三市场前端校验与后端快速失败实现
2026/9/17 11:36:47 网站建设 项目流程

TradingAgents-CN 股票代码格式验证与标准化:A股、美股、港股三市场前端校验与后端快速失败实现

【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN

本指南完整梳理 TradingAgents-CN 项目中股票代码验证体系的落地实现,覆盖单股分析页面前端的三市场(A股、美股、港股)格式校验、自动市场识别与代码标准化,以及分析任务启动前的后端预获取验证与快速失败机制。读者将掌握stockValidator.tsstock_validator.py的核心校验规则、港股代码格式化陷阱的修复方案,以及如何将验证结果接入分析任务状态机,避免无效请求浪费 LLM 与数据源资源。

背景:为什么需要两层股票代码验证

TradingAgents-CN 是基于多智能体 LLM 的中文金融交易框架,用户可在单股分析页面输入任意股票代码发起多智能体深度分析。此前系统存在两个突出问题:

  1. 前端无校验:输入框对任意文本放行,123456750xxxx这类非法代码会直接被提交,用户直到分析失败才看到错误。
  2. 后端不验证即分析:用户反馈输入港股00700(腾讯控股)后,后端未识别股票不存在或格式错误,而是继续执行分析,浪费时间和资源;且港股代码格式化逻辑有误(0070000700.HK而非正确的0700.HK)。

解决方案采用前端格式校验 + 后端数据预获取验证的双层架构:前端负责格式、市场识别与标准化(用户体验层),后端负责"代码是否存在、数据是否可获取"的快速失败(资源保护层)。相关设计与修复记录见 docs/integration/data-sources/stock_code_validation.md 与 docs/integration/data-sources/stock_code_validation_backend.md。

支持的市场代码格式规则

系统支持 A股、美股、港股三种市场的代码格式校验与自动识别,规则如下。

A股:6位数字,前缀白名单

前缀板块示例
60xxxx上海主板600519 贵州茅台
68xxxx科创板688981 中芯国际
00xxxx深圳主板000001 平安银行
30xxxx创业板300750 宁德时代
43xxxx/83xxxx/87xxxx北交所
  • ✅ 通过:000001(平安银行)、600519(贵州茅台)、000858(五粮液)、300750(宁德时代)
  • ✗ 失败:00001(仅5位)、1234567(超过6位)、50xxxx(前缀不在白名单)

美股:1-5个大写字母,可选单点号

  • 大小写不敏感,自动转为大写(aaplAAPL
  • 支持带点号的类别股代码,如BRK.B(伯克希尔B股)
  • ✅ 通过:AAPLMSFTGOOGLTSLABRK.B
  • ✗ 失败:ABCDEF(超过5个字母)、123(纯数字)、A.B.C(多个点号)

港股:1-5位数字,自动补齐前导0

  • 自动将不足5位的代码补齐前导0至5位(70000700
  • ✅ 通过:00700(腾讯控股)、09988(阿里巴巴)、01810(小米集团)、03690(美团),以及不带前导0的7009988
  • ✗ 失败:123456(超过5位)、0(无效代码)

前端实现:单股分析页面的实时校验

核心工具函数 stockValidator.ts

前端校验逻辑全部收敛在 frontend/src/utils/stockValidator.ts,返回统一的StockValidationResult结构(validmarketmessagenormalizedCode),便于组件层与后续扩展复用。

A股校验:先剥离非数字字符,再用^\d{6}$校验位数,最后检查前两位前缀是否在白名单['60', '68', '00', '30', '43', '83', '87']内:

export function validateAStock(code: string): StockValidationResult { const cleanCode = code.trim().replace(/[^0-9]/g, '') if (!/^\d{6}$/.test(cleanCode)) { return { valid: false, message: 'A股代码必须是6位数字' } } const prefix = cleanCode.substring(0, 2) const validPrefixes = ['60', '68', '00', '30', '43', '83', '87'] if (!validPrefixes.includes(prefix)) { return { valid: false, message: 'A股代码前缀不正确(支持:60/68/00/30/43/83/87开头)' } } return { valid: true, market: 'A股', normalizedCode: cleanCode } }

美股校验:正则^[A-Z]{1,5}(\.[A-Z])?$同时约束字母数量(1-5)与点号数量(最多1个、点号后仅1个字母),并额外防御"全是点号"的空代码场景:

export function validateUSStock(code: string): StockValidationResult { const cleanCode = code.trim().toUpperCase().replace(/[^A-Z.]/g, '') if (!/^[A-Z]{1,5}(\.[A-Z])?$/.test(cleanCode)) { return { valid: false, message: '美股代码格式不正确(1-5个字母,如:AAPL、BRK.B)' } } if (cleanCode.replace(/\./g, '').length === 0) { return { valid: false, message: '美股代码不能为空' } } return { valid: true, market: '美股', normalizedCode: cleanCode } }

港股校验:位数限制^\d{1,5}$,通过后用padStart(5, '0')补齐前导0,实现代码标准化:

export function validateHKStock(code: string): StockValidationResult { const cleanCode = code.trim().replace(/[^0-9]/g, '') if (!/^\d{1,5}$/.test(cleanCode)) { return { valid: false, message: '港股代码必须是1-5位数字' } } const normalizedCode = cleanCode.padStart(5, '0') return { valid: true, market: '港股', normalizedCode: normalizedCode } }

自动识别入口validateStockCode(code, marketHint?):若调用方提供了marketHint(当前选中的市场),则按该市场强校验;否则按规则自动识别——纯数字且6位 → A股,纯数字且1-5位 → 港股,含字母 → 美股,其余返回"无法识别的股票代码格式"。工具模块还提供了getStockCodeFormatHelpgetStockCodeExamplesformatStockCode等辅助函数,用于输入框提示语、示例展示与显示格式化。

Vue 组件集成 SingleAnalysis.vue

frontend/src/views/Analysis/SingleAnalysis.vue 中完成了三处接线(文件内行号可定位,如导入见L718):

  1. 响应式状态L816附近):stockCodeErrorstockCodeHelp两个ref<string>分别承载错误信息与帮助提示。
  2. 输入与失焦事件@input时清空错误并展示当前市场的格式帮助;@blur触发validateStockCodeInput()执行真实校验。
  3. 市场切换重新验证onMarketChange中若已有输入代码,立即按新市场重新验证,保证代码与市场类型始终匹配。

validateStockCodeInput的完整逻辑如下(见 SingleAnalysis.vueL853附近):

const validateStockCodeInput = () => { const code = analysisForm.stockCode.trim() if (!code) { stockCodeError.value = '' stockCodeHelp.value = '' return } const validation = validateStockCode(code, analysisForm.market) if (!validation.valid) { stockCodeError.value = validation.message || '股票代码格式不正确' stockCodeHelp.value = '' } else { stockCodeError.value = '' stockCodeHelp.value = `✓ ${validation.market}代码格式正确` // 自动更新市场类型 if (validation.market && validation.market !== analysisForm.market) { analysisForm.market = validation.market ElMessage.success(`已自动识别为${validation.market}`) } // 标准化代码 if (validation.normalizedCode) { analysisForm.stockCode = validation.normalizedCode } } }

值得一提的细节:校验通过后若识别出的市场与用户当前选择不一致,组件会自动切换市场选择器并弹出已自动识别为X市场的成功提示,同时用normalizedCode回写输入框(如aaplAAPL70000700),实现了"输入即标准化"。

输入框与提示样式

输入框使用 Element Plus 的el-input,带TrendCharts前缀图标、clearable可清空、失焦校验与错误态样式绑定;下方错误/成功提示区域分别用WarningFilled(红色#f56c6c)与InfoFilled(绿色#67c23a)图标渲染。市场选择器el-select的三个el-option在标签旁附灰色小字说明格式(A股:6位数字;美股:1-5个字母;港股:1-5位数字)。SCSS 中通过:deep()覆写el-input__innerfont-weight: 600text-transform: uppercase,并在.is-error时高亮边框为红色。完整样式见 frontend/src/views/Analysis/SingleAnalysis.vue。

后端实现:分析开始前的快速失败验证

仅有前端格式校验并不足够——格式合法的代码仍可能指向不存在的股票。为此后端在分析任务真正启动前,通过 tradingagents/utils/stock_validator.py 完成"代码是否存在 + 数据能否获取"的预获取验证。

数据准备器与结果对象

模块核心是StockDataPreparer类,其prepare_stock_data(stock_code, market_type="auto", period_days=30, analysis_date=None)按三步执行:

  1. _validate_format:基本格式验证(见下文);
  2. _detect_market_typemarket_type="auto"时按正则自动判定市场(6位数字 → A股;\d{4,5}.HK或纯4-5位数字 → 港股;1-5位字母 → 美股);
  3. _prepare_data_by_market:按市场分发到_prepare_china_stock_data/_prepare_hk_stock_data/_prepare_us_stock_data

验证结果统一封装为StockDataPreparationResultis_validstock_codemarket_typestock_nameerror_messagesuggestionhas_historical_datahas_basic_infodata_period_dayscache_status),并提供to_dict()便于日志与状态持久化。为保持向后兼容,模块同时导出StockValidatorget_stock_validatorvalidate_stock_exists等别名,并针对 FastAPI 异步上下文提供prepare_stock_data_async(避免事件循环冲突,通过asyncio.to_thread或异步内部方法执行)。

格式验证规则(后端视角)

# A股:必须是6位数字 + 前缀白名单 if not re.match(r'^\d{6}$', stock_code): return error("A股代码格式错误,应为6位数字") prefix = stock_code[:2] valid_prefixes = ['60', '68', '00', '30', '43', '83', '87'] if prefix not in valid_prefixes: return error("A股代码前缀不正确") # 港股:4-5位数字.HK 或 纯4-5位数字 hk_format = re.match(r'^\d{4,5}\.HK$', stock_code.upper()) digit_format = re.match(r'^\d{4,5}$', stock_code) if not (hk_format or digit_format): return error("港股代码格式错误") # 美股:1-5位字母 if not re.match(r'^[A-Z]{1,5}$', stock_code.upper()): return error("美股代码格式错误,应为1-5位字母")

与前端略有差异:后端港股要求4-5位数字(前端为1-5位并自动补齐),因为后端面对的是补齐后的标准代码;同时_validate_format还会拦截空代码与超过10字符的超长输入。

港股代码格式化修复:00700 → 0700.HK

这是整个修复中最关键的 Bug。旧逻辑f"{stock_code.zfill(4)}.HK"00700直接输出00700.HK(错误,腾讯港股标准代码为0700.HK)。新逻辑先移除前导0,再补齐到4位

clean_code = stock_code.lstrip('0') or '0' # 如果全是0,保留一个0 formatted_code = f"{clean_code.zfill(4)}.HK"
输入处理步骤输出
70070007000700.HK
007000070070007000700.HK
9988998899889988.HK
0998809988998899889988.HK
1810181018101810.HK
0181001810181018101810.HK

数据预获取验证:三层证据链

格式通过后,各市场按"基本信息 → 股票名称 → 历史数据"顺序验证代码真实存在:

  • A股get_china_stock_info_unified获取基本信息,解析"股票名称:"字段,若名称为"未知"或以股票{code}开头则判定不存在;随后get_china_stock_data_unified拉取历史数据,要求长度 > 50 且包含价格/成交量等关键字段。值得注意的是,A股分支还会先检查 MongoDB 缓存中的数据是否完整、是否为最新交易日,不完整时自动触发同步_trigger_data_sync_async按数据库配置的数据源优先级依次尝试 tushare / akshare,同步历史数据、财务数据与实时行情),见 tradingagents/utils/stock_validator.py。
  • 港股:先标准化为0700.HK格式,再get_hk_stock_info_unified获取信息并借助_extract_hk_stock_name从字典字段、"公司名称:"、Yahoo Finance 日志格式、公司关键词等多来源解析股票名称;若命中网络限制特征(如 "Too Many Requests"、"Rate limited"、超时),返回专门的网络限制建议(等待5-10分钟重试、检查网络等),与"代码不存在"区分处理。
  • 美股:直接通过OptimizedUSDataProvider(或兼容旧路径get_us_stock_data_cached)获取历史数据来验证存在性,数据有效即视为验证通过(美股通常不单独拉取基本信息)。

接入分析任务:快速失败

验证入口接入 app/services/simple_analysis_service.py 的execute_analysis_background方法(相关调用见L808L832-L872):后台任务启动时调用prepare_stock_data_async,若validation_result.is_valid为假,则同时更新内存任务状态与 MongoDB 任务状态为AnalysisStatus.FAILED(progress=0),携带error_messagesuggestion,并立即返回——不消耗任何 LLM 调用与后续分析资源

validation_result = await prepare_stock_data_async( stock_code=request.stock_code, market_type=market_type, period_days=30, analysis_date=analysis_date, ) if not validation_result.is_valid: error_msg = f"❌ 股票代码验证失败: {validation_result.error_message}" logger.error(error_msg) logger.error(f"💡 建议: {validation_result.suggestion}") await self.memory_manager.update_task_status( task_id=task_id, status=AnalysisStatus.FAILED, progress=0, error_message=validation_result.error_message, ) await self._update_task_status( task_id, AnalysisStatus.FAILED, 0, error_message=validation_result.error_message, ) return

验证通过后,日志会记录股票名称、市场类型、历史数据与基本信息的有无,且验证过程中获取的基本信息与历史数据会缓存在 Redis,供后续分析阶段直接复用,避免重复拉取。

错误信息结构

验证失败返回结构化错误,包含市场类型、错误信息与可操作建议:

{ "is_valid": false, "stock_code": "000999", "market_type": "A股", "error_message": "股票代码 000999 不存在或信息无效", "suggestion": "请检查股票代码是否正确,或确认该股票是否已上市" }

港股示例:"error_message": "港股代码 0700.HK 不存在或信息无效",建议给出0700.HK格式参考;美股示例建议列出AAPLMSFT等正确格式。

端到端验证流程

前端与后端配合后的完整用户旅程:输入时显示格式提示 → 失焦即时验证 → 提交时再次验证(SingleAnalysis.vue 提交逻辑中同样调用validateStockCode,格式错误则阻止提交)→ 后端预获取验证兜底 → 验证通过后使用标准化代码发起分析。

测试用例一览

前端格式校验

市场输入预期标准化后说明
A股000001/600519000001/600519平安银行 / 贵州茅台
A股00001/1234567/500001-5位 / 超6位 / 前缀错误
美股aapl/MSFT/brk.bAAPL/MSFT/BRK.B大小写归一、点号支持
美股ABCDEF/123-超5字母 / 纯数字
港股700/00700/998800700/00700/09988前导0补齐
港股123456-超过5位

后端存在性验证

市场输入预期
A股000001/600519✅ 通过(存在)
A股000999/999999/00001❌ 失败(不存在或格式错误)
港股700/007000700.HK9988/099889988.HK✅ 通过
港股99999(→99999.HK❌ 失败(不存在)
美股AAPL/MSFT/GOOGL✅ 通过
美股ABCDE/ZZZZZ❌ 失败(不存在)

另外,scripts/stock_code_validator.py 提供了一套"内容后置修正"思路:针对 LLM 输出中可能出现的代码混淆(如将002027错写为002021/002026/002028),用错误映射表在分析结果内容中做替换修正,可作为验证体系的补充环节。

性能与健壮性设计

  • 数据缓存:验证过程中获取的基本信息与历史数据会写入 Redis 缓存,分析阶段直接复用,避免重复请求数据源(见 tradingagents/utils/stock_validator.py 中cache_status的记录链路)。
  • 超时控制StockDataPreparer内置self.timeout_seconds = 15,15 秒内无法获取数据即判定验证失败,防止单只股票阻塞整个任务队列。
  • 异步友好prepare_stock_data_async针对 FastAPI 事件循环设计;同步上下文则通过asyncio.to_thread包装(如文档中execute_analysis_background的调用方式),同步包装器_trigger_data_sync_sync还会检测运行中的事件循环并创建新 loop,规避 "attached to a different loop" 错误。
  • A股数据自动同步:数据库数据缺失或过期时自动按配置的数据源优先级触发同步,兼顾数据新鲜度与验证成功率。

总结

修复前后对比:修复前输入00700会直接进入分析、中途才发现数据获取失败,浪费 LLM Token 与数据源配额;修复后,前端即时拦截格式错误并自动标准化(0070000700aaplAAPL),后端在分析启动前完成"格式 → 存在性 → 数据可用性"三级校验,失败即快速终止任务并返回结构化错误与建议。

该设计的核心收益可归纳为:提前验证(分析开始前拦截无效代码)、快速失败(无效请求零成本返回)、清晰提示(错误信息附带修复建议)、数据复用(验证期缓存供分析期使用)、格式标准化(港股前导0、美股大写自动修正)。从源码结构看,后续可扩展的方向包括:股票代码白名单/黑名单、批量代码验证、验证结果缓存(避免重复验证同一股票)、以及新加坡、日本等更多市场的规则接入——工具函数与数据准备器的分层设计已为这些扩展预留了清晰接口。

修复前: 00700 → 开始分析(无验证) → 中途失败 → 浪费资源 ❌ 修复后: 00700 → 格式验证✓ → 标准化 0700.HK → 获取信息✓ → 获取数据✓ → 验证通过开始分析 ✅

【免费下载链接】TradingAgents-CN基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询