Files
group_fqcd_jr/docs/12-基金行情数据底座接入开发计划.md

8.9 KiB
Raw Permalink Blame History

基金行情数据底座接入开发计划

版本:v1.0
目标:将外部基金行情能力接入公共 MVC+S 底座,供客服、投顾、风控 Agent 统一只读使用。
当前范围:场内基金模拟交易相关行情;场外运营数据不纳入本计划。

一、建设目标

将外部行情脚本改造成公共底座能力:

东方财富 Adapter
→ FundQuoteService
→ ToolRegistry / ToolExecutor
→ 客服、投顾、风控 Agent

业务组员只调用统一工具,不直接访问东方财富接口、HTTP 客户端、缓存或数据库。

二、明确不做的事情

  • 第一阶段不修改已有数据库表、字段和交易流程;
  • 不把行情快照写入场内交易表;
  • 不实现代客下单、成交确认或持仓修改;
  • 不让 Agent 直接调用外部行情接口;
  • 不在本阶段创建可运行示例 Agent;
  • 不把场外基金运营数据混入本行情服务。

三、现有脚本拆分映射

原 hq.py 能力 新底座位置 处理要求
东方财富 HTTP 调用 app/infrastructure/fund_market_adapter.py 改为异步、超时、重试、响应校验
交易时段判断 FundQuoteService 固定北京时间并可测试注入时钟
基金名称缓存 行情缓存适配器 允许 Redis,不使用进程全局作为唯一缓存
历史净值和收益率合并 app/service/fund_quote_service.py 统一 DTO、Decimal、降级标识
中文字典输出 Controller/Agent 展示层 内部 DTO 使用英文稳定字段
固定南方基金代码 配置或代码白名单 先保留白名单,后续配置中心化

四、阶段计划

F0:基线和契约冻结

目标:确认接入不会破坏现有底座和数据库规则。

任务:

  • 对照 AGENTS.md、00 基线和 02 建表设计;
  • 确认本阶段只新增 Python 模块、工具注册和测试;
  • 定义 FundQuoteQuery、FundQuote、FundQuoteSource DTO;
  • 定义错误分类:外部行情不可用返回可识别的降级结果,不泄露供应商异常;
  • 确认行情工具权限码为 fund:quote:read。

验收:

  • DTO 字段、类型和空值规则确定;
  • 没有数据库迁移;
  • 没有修改既有表和字段;
  • 接口契约可被 Service、ToolExecutor 和测试共同引用。

F1:外部行情 Adapter

目标:把 hq.py 的外部请求改造成底座 Infrastructure 适配器。

新增文件:

app/infrastructure/fund_market_adapter.py
app/core/fund_contracts.py
tests/unit/infrastructure/test_fund_market_adapter.py

任务:

  • 使用 httpx.AsyncClient,禁止同步网络调用阻塞 Worker;
  • 封装名称、实时行情、历史净值、区间收益率四类请求;
  • 统一请求超时、有限重试和指数退避;
  • 校验外部 JSON 结构和基金代码;
  • 将 HTTP、JSON、字段缺失转换为 RecoverableAgentError 或降级结果;
  • 供应商日志只记录接口类别、基金数量和异常类型,不记录完整响应正文;
  • 使用 Decimal 保存净值和收益率;
  • 所有时间统一使用 Asia/Shanghai 语义。

验收:

  • 外部接口成功、超时、HTTP 错误、非法 JSON、字段缺失均有测试;
  • 测试不依赖真实东方财富网络,使用 httpx.MockTransport;
  • Adapter 不导入 Agent、Controller 或数据库 Session。

F2:FundQuoteService

目标:将多个外部接口结果合并成稳定的行情业务结果。

新增文件:

app/service/fund_quote_service.py
tests/unit/service/test_fund_quote_service.py

任务:

  • 实现按基金代码、基金类型、日期和数量查询;
  • 保留场内基金白名单;
  • 合并实时行情和历史净值;
  • 盘中使用实时行情,非盘中使用最新收盘净值;
  • 返回 quote_source、quote_time、is_intraday、degraded;
  • 单个产品失败不得导致全部产品无原因失败;
  • 外部行情不可用时返回结构化降级结果;
  • 不将实时行情解释为成交、委托或持仓结果。

验收:

  • 交易时段和非交易时段测试通过;
  • 基金类型筛选、数量限制、非法日期和未知类型测试通过;
  • 实时失败回退历史、历史失败返回降级结果的测试通过;
  • Service 不直接解析 HTTP 响应细节。

F3:缓存和健康状态

目标:降低外部接口压力,并让组员得到可识别的降级状态。

任务:

  • 基金名称缓存建议 1 天;
  • 收盘净值缓存建议 5-30 分钟;
  • 实时行情缓存建议 30-60 秒;
  • Redis 可用时使用 Redis,不可用时回退无缓存请求或结构化降级;
  • 不将进程级字典作为多 Worker 唯一缓存;
  • 增加行情数据源健康状态,不把供应商故障伪装成正常行情;
  • 记录数据源成功率、延迟、降级次数和最后成功时间。

验收:

  • Redis 正常、Redis 不可用、缓存过期和缓存击穿测试通过;
  • 缓存故障不阻塞主流程;
  • 返回结果能够区分实时、缓存、收盘和降级来源。

F4:注册公共只读工具

目标:让所有业务 Agent 通过统一工具使用行情。

工具契约:

工具名:query_fund_quote
权限码:fund:quote:read
只读:是
允许角色:customer、advisor、operator、risk_operator、admin
超时:5 秒

任务:

  • 定义严格的 Pydantic 输入模型;
  • 在 bootstrap 中注册 ToolDefinition;
  • 由 ToolExecutor 统一检查权限、角色、意图白名单和超时;
  • 结果自动生成工具来源引用和审计记录;
  • AgentDefinition.allowed_tools 只能缩小权限;
  • 业务 Agent 不能绕过工具调用 Adapter。

验收:

  • 正常调用、未授权、未列入意图白名单、参数错误、超时和外部失败均有测试;
  • 工具结果不含供应商原始异常和敏感配置;
  • 来源引用能通过公共合规审查。

F5:配置中心和管理规则

目标:把基金白名单、数据源开关、缓存时间和限流参数逐步纳入配置治理。

第一阶段:

  • 外部接口地址、超时和密钥引用写入 .env 或运行配置;
  • 基金白名单保留在代码常量,避免未经审核扩大产品范围。

后续阶段:

  • 使用 platform_config_item 增加行情配置命名空间;
  • 配置发布、审核、激活、回滚必须经过已有配置中心;
  • 配置变更写审计并通过 Outbox 通知缓存失效;
  • 不通过配置中心扩大 Agent 的工具权限上限。

验收:

  • 配置缺失时失败关闭或使用明确的安全默认值;
  • 密钥只使用 secret_ref,不返回明文;
  • 发布版本可追溯、可回滚。

当前实现:RuntimeConfigService.fund_quote() 读取当前激活版本的 namespace=fund_market、config_key=default;query_fund_quote 工具加载该配置, FundQuoteRuntimeConfig 校验基金白名单和缓存 TTL。配置缺失、类型错误或配置中心异常时使用代码 默认值,不会因配置中心异常导致行情功能整体不可用。

F6:业务组员接入

目标:客服、投顾和风控 Agent 只消费统一行情工具。

组员需要做:

  • 在 AgentDefinition.allowed_tools 声明 query_fund_quote;
  • 在对应意图白名单中声明 fund_quote;
  • 在 handle() 中调用 self.call_tool(...);
  • 对行情缺失、降级和非交易时段给出业务解释;
  • 补充本业务域的权限和边界测试。

组员禁止做:

  • 直接导入 hq.py;
  • 直接调用东方财富 URL;
  • 自己读取行情缓存或解析外部 JSON;
  • 根据行情直接下单或修改交易数据;
  • 把行情数据写入交易表。

F7:是否落行情快照表

判断条件:只有在需要历史回测、监管留痕、行情对账或跨进程长期查询时才进入本阶段。

候选新增表:

fund_quote_snapshot
fund_quote_source_record

前置要求:

  • 先更新 00、02 数据库文档;
  • 证明没有修改任何既有表名和字段定义;
  • 设计唯一键、来源、采集时间、有效时间和幂等策略;
  • 增加 Alembic 迁移、schema fingerprint 和真实 MySQL 验收;
  • 只新增表,不改写场内交易表。

五、建议开发顺序和完成标准

F0 契约冻结
→ F1 Adapter
→ F2 Service
→ F3 缓存/健康
→ F4 公共工具
→ F5 配置治理
→ F6 业务接入
→ F7 可选落库

MVP 完成标准:F0-F4 全部通过;不要求新增数据库表。长期版本再评估 F5-F7。

六、测试命令

python -m pytest tests/unit/infrastructure/test_fund_market_adapter.py tests/unit/service/test_fund_quote_service.py -q -p no:cacheprovider
python -m pytest -q -p no:cacheprovider
python -m ruff check app tests tools alembic
python -m mypy app
python tools/audit_schema.py

任何数据库变更都必须额外执行 schema fingerprint,并在 TODO 中记录基线对比结果。