数据源架构设计

📎 引用文件

本文引用的文件 - base.py - registry.py - _http.py - _symbol_utils.py - yahoo_loader.py - local_loader.py - ccxt_loader.py - eastmoney_client.py

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障诊断与监控
  9. 结论
  10. 附录:自定义数据源开发指南

简介

本技术文档面向 Vibe-Trading 的数据源架构,聚焦于数据加载器的抽象层设计、注册机制与统一接口规范;说明 HTTP 请求封装、符号工具函数与通用数据处理组件的实现原理;阐述数据源的插件化架构(动态加载、版本管理与依赖解析);提供自定义数据源的开发指南(接口定义、数据转换与错误处理模式);并总结性能优化策略(连接池管理、请求合并与缓存机制)以及健康检查、监控指标与故障诊断工具的使用。

项目结构

数据源子系统位于 agent/backtest/loaders 目录下,采用“协议 + 注册表 + 具体实现”的分层组织方式: - 抽象协议与通用能力:base.py 定义了 DataLoaderProtocol、重试/预算控制、OHLC 校验、本地缓存等。 - 注册与回退链:registry.py 维护全局注册表、市场级回退链与自动发现机制。 - HTTP 基础设施:_http.py 提供按主机桶的节流、会话复用与 JSON 获取。 - 符号工具:_symbol_utils.py 提供 ETF/LOF 前缀识别等通用符号判断。 - 具体数据源:如 yahoo_loader.py、local_loader.py、ccxt_loader.py 等,各自实现统一 fetch 接口。 - 第三方客户端:如 eastmoney_client.py,封装特定供应商的 HTTP 调用与字段映射。

graph TB subgraph "抽象层" A["DataLoaderProtocol<br/>base.py"] B["重试/预算/缓存<br/>base.py"] C["OHLC 校验<br/>base.py"] end subgraph "注册与路由" D["注册表/回退链<br/>registry.py"] end subgraph "HTTP 基础设施" E["HostThrottle/Session<br/>_http.py"] F["throttled_get / get_json<br/>_http.py"] end subgraph "具体数据源" G["Yahoo 加载器<br/>yahoo_loader.py"] H["本地加载器<br/>local_loader.py"] I["CCXT 加载器<br/>ccxt_loader.py"] end subgraph "供应商客户端" J["东方财富客户端<br/>eastmoney_client.py"] end K["符号工具<br/>_symbol_utils.py"] A --> D B --> D C --> D D --> G D --> H D --> I G --> F H --> F I --> F J --> F K --> G K --> H K --> I

图表来源 - base.py:1-645 - registry.py:1-249 - _http.py:1-180 - _symbol_utils.py:1-21 - yahoo_loader.py:1-200 - local_loader.py:1-200 - ccxt_loader.py:1-200 - eastmoney_client.py:1-200

章节来源 - base.py:1-645 - registry.py:1-249 - _http.py:1-180 - _symbol_utils.py:1-21

核心组件

章节来源 - base.py:27-119 - base.py:163-236 - base.py:243-439 - registry.py:23-155 - registry.py:158-249 - _http.py:46-152 - _symbol_utils.py:9-21

架构总览

下图展示了从上层调用到具体数据源的完整流程,包括注册发现、回退选择、HTTP 节流与数据标准化。

sequenceDiagram participant Caller as "调用方" participant Reg as "注册表<br/>registry.py" participant Loader as "具体加载器<br/>yahoo/local/ccxt" participant HTTP as "HTTP 封装<br/>_http.py" participant Provider as "外部数据源" Caller->>Reg : resolve_loader(market) Reg->>Reg : _ensure_registered() Reg->>Reg : 遍历 FALLBACK_CHAINS Reg->>Loader : 构造并 is_available() alt 可用 Caller->>Loader : fetch(codes, start, end, interval, fields) Loader->>HTTP : throttled_get/get_json HTTP->>Provider : GET (带节流/会话复用) Provider-->>HTTP : Response HTTP-->>Loader : JSON/文本 Loader-->>Caller : {symbol : DataFrame} else 不可用 Reg->>Reg : 继续下一个候选 Reg-->>Caller : NoAvailableSourceError end

图表来源 - registry.py:71-193 - _http.py:120-152 - yahoo_loader.py:173-200 - local_loader.py:129-200 - ccxt_loader.py:184-200

详细组件分析

抽象层与通用能力(base.py)

flowchart TD Start(["进入 fetch"]) --> CheckCache["检查本地缓存<br/>loader_cache_get"] CheckCache --> |命中| ReturnCache["返回缓存 DataFrame"] CheckCache --> |未命中| DoFetch["调用底层 fetch()"] DoFetch --> Validate["validate_ohlc / validate_date_range"] Validate --> CacheWrite{"是否可缓存"} CacheWrite --> |是| PutCache["写入 parquet + 元数据"] CacheWrite --> |否| ReturnResult["返回结果"] PutCache --> ReturnResult

图表来源 - base.py:343-439 - base.py:31-119

章节来源 - base.py:27-119 - base.py:163-236 - base.py:243-439

注册与回退机制(registry.py)

classDiagram class Registry { +LOADER_REGISTRY : dict +VALID_SOURCES : set +FALLBACK_CHAINS : dict +register(cls) +resolve_loader(market) +get_loader_cls_with_fallback(source) } class DataLoaderProtocol { +name : str +markets : set +requires_auth : bool +is_available() bool +fetch(codes, start_date, end_date, interval, fields) dict } Registry --> DataLoaderProtocol : "管理/选择"

图表来源 - registry.py:23-155 - registry.py:158-249 - base.py:618-645

章节来源 - registry.py:23-155 - registry.py:158-249

HTTP 请求封装(_http.py)

flowchart TD Call["throttled_get(url, host_key, min_interval)"] --> Wait["HostThrottle.wait(bucket, interval)"] Wait --> Session["获取/创建 Session"] Session --> Request["session.get(url, params, headers, timeout)"] Request --> Response["返回 Response"]

图表来源 - _http.py:46-152

章节来源 - _http.py:1-180

符号工具(_symbol_utils.py)

章节来源 - _symbol_utils.py:1-21

Yahoo 数据源(yahoo_loader.py)

章节来源 - yahoo_loader.py:1-200

本地数据源(local_loader.py)

章节来源 - local_loader.py:1-200

CCXT 数据源(ccxt_loader.py)

章节来源 - ccxt_loader.py:1-200

东方财富客户端(eastmoney_client.py)

章节来源 - eastmoney_client.py:1-200

依赖关系分析

graph LR Base["base.py"] --> Reg["registry.py"] Base --> Http["_http.py"] Reg --> Yahoo["yahoo_loader.py"] Reg --> Local["local_loader.py"] Reg --> Ccxt["ccxt_loader.py"] Http --> East["eastmoney_client.py"] Yahoo --> Http Local --> Http Ccxt --> Base

图表来源 - base.py:1-645 - registry.py:1-249 - _http.py:1-180 - yahoo_loader.py:1-200 - local_loader.py:1-200 - ccxt_loader.py:1-200 - eastmoney_client.py:1-200

章节来源 - registry.py:71-115 - ccxt_loader.py:184-200

性能考虑

[本节为通用性能建议,不直接分析具体文件]

故障诊断与监控

章节来源 - registry.py:158-249 - base.py:163-236 - base.py:343-439

结论

Vibe-Trading 的数据源架构通过清晰的协议抽象、健壮的注册与回退机制、统一的 HTTP 封装与通用的数据处理能力,实现了高内聚、低耦合的可插拔数据源体系。其设计兼顾了易用性与鲁棒性:既支持免费公共源快速接入,也兼容付费与本地数据;通过节流、重试、缓存等手段保障性能与稳定性;并通过严格的数据校验与完善的日志体系支撑运维与排障。

[本节为总结性内容,不直接分析具体文件]

附录:自定义数据源开发指南

章节来源 - base.py:618-645 - registry.py:62-68 - yahoo_loader.py:173-200 - local_loader.py:129-200 - ccxt_loader.py:184-200