架构设计

AxData 架构设计

本文说明 AxData 的整体架构、模块边界和部署形态。AxData 是本地优先的量化数据底座:个人研究可以在单机目录内完成,团队共享可以通过局域网 API 扩展,云端部署可沿用同一套数据语义。

目标

当前边界:

整体架构

flowchart TD
    Sources["数据源\nTushare / RQData / xtdata / AKShare / OpenBB / 文件"]
    SourceRegistry["Source Provider Registry\n接口 / 字段 / 临时查询路由"]
    CollectorRegistry["Collector Registry\n采集器 / runner entry / 输出契约"]
    Direct["源端直取\n字段契约 / 立即请求 / 默认不入库"]
    Ingest["采集任务\n全量 / 增量 / 修复 / 回放"]
    Raw["raw Parquet\n不可变源快照"]
    Staging["staging Parquet\n字段标准化 / 类型归一 / 去重"]
    Core["core Parquet\n接口口径主数据与行情事实表"]
    Factor["factor Parquet\n因子与特征宽表"]
    DuckDB["DuckDB\n视图 / SQL 查询 / 本地缓存"]
    SDK["Python SDK\n默认本地直读 / 可走远程 API"]
    HTTP["HTTP API\n远程通道 / Web / 跨语言"]
    CLI["CLI\n采集 / 管理 / 调试"]
    Apps["研究与应用\nNotebook / 回测 / Dashboard / 服务"]
    Meta["元数据\nschema / lineage / jobs / quality"]

    Sources --> SourceRegistry
    SourceRegistry --> Direct
    Sources --> Ingest
    CollectorRegistry --> Ingest
    Ingest --> Raw
    Raw --> Staging
    Staging --> Core
    Core --> Factor
    Raw --> Meta
    Staging --> Meta
    Core --> Meta
    Factor --> Meta
    Core --> DuckDB
    Factor --> DuckDB
    DuckDB --> SDK
    DuckDB --> HTTP
    Direct --> SDK
    Direct --> HTTP
    HTTP --> SDK
    SDK --> Apps
    HTTP --> Apps
    CLI --> Ingest
    Meta --> SDK
    Meta --> HTTP

模块边界

插件化边界

AxData 的插件体系以本地优先为前提:插件是用户本地安装、本地启用、本地运行的 Python 扩展包,用户自行选择来源并承担运行风险。AxData 不做中心化插件市场、不做插件审核、不做签名信任体系;checksum 只用于 .axp 文件完整性和打包一致性检查。

插件不只等于数据源。一个插件可以提供 Provider、Collector、DownloaderProfile、工具能力,或这些能力的组合。核心边界如下:

截至 2026-07-04,默认 CollectorRegistry catalog 为 8 个 independent / non-legacy collectors,均由 axdata.collector.tdx 提供。交易所保留为 Source Provider 接口和本地基础数据能力,不再提供默认 CollectorSpec;stock_capital_changes_tdxstock_adj_factor_tdx 保留为源端接口和兼容 DownloaderProfile,不再作为采集器进入采集页。巨潮、腾讯、东方财富和新浪财经仍是 source_request Provider 接口,默认不提供采集器。

数据流

AxData 有两条读数路径。

源端直取路径:

  1. SDK 或 HTTP API 指定 AxData 接口名,例如第一版源端预览接口 stock_codes_tdx
  2. Source Request Gateway 读取接口契约,校验参数和字段。
  3. 适配器请求源端,协议层解析原始响应。
  4. 归一层返回 AxData 字段、中文说明和响应包络。
  5. 默认不写入 rawstagingcorefactor

采集入库路径:

  1. 采集任务读取 Collector Registry,解析 collector_idcollector_plugin_iddataset_idrunner_entry、资源组、输出和质量契约。
  2. Collector Runner 在 AxData 队列和资源池下调用 runner_entry。新采集器可以自带取数逻辑、请求上游、读取本地文件或复用公共库,但不得通过 /v1/request、SDK call、ProviderRegistry route 或旧 DownloaderProfile 链路套接口采集。
  3. Writer 将采集器产出的记录按 raw/staging/core/factor 规则写入 Parquet,并写入批次元数据。兼容的旧 Provider manifest collectors 仍可通过 DownloaderProfile -> Adapter -> Writer 路径执行,但必须标记为 legacy。
  4. staging 层执行字段整理、类型转换、代码标准化、日期规范、基础去重。
  5. core 层按数据集或接口口径形成稳定、面向业务语义的主表和事实表,例如 stock_basic_exchange;新增口径应使用独立表名或接口名表达。
  6. factor 层从 core 层生成因子,记录计算窗口、依赖表、代码版本和数据截止点。
  7. DuckDB 以外部表或视图方式查询 Parquet,为 SDK 的本地直读、HTTP API 服务、Notebook 和回测提供一致语义。

采集与实时数据的边界:

本地优先部署形态

本地版默认是一个目录、一组 Parquet 文件和一个可选的 DuckDB 元数据/缓存文件:

axdata-home/
  data/
    raw/
    staging/
    core/
    factor/
  metadata/
    catalog.duckdb
    manifests/
    quality/
  logs/
  cache/

本地部署原则:

局域网部署形态

局域网版在本地版基础上增加一个常驻 API 服务和共享存储:

云端部署形态

云端版保持同一套表结构和 API 语义,只替换运行组件:

参考系统取舍

系统借鉴点不直接照搬的原因
Tushareapi_name + params + fields 的统一调用模型、清晰的 token 认证、A 股字段命名习惯AxData 不把第三方接口形态作为核心事实模型;额度、积分、权限只属于 source adapter
RQData专业数据源的稳定标的编码、Python/HTTP 双入口、交易日函数和多资产数据模型不采用当天 token 或 CSV 响应作为 AxData 核心协议;返回统一 JSON/Arrow/Parquet
xtdata本地终端桥接、历史补充与实时订阅分离、桌面环境可用不让核心服务依赖 MiniQMT 进程;xtdata 只作为边缘采集源或实时补充源,实时默认不写入 core
AKShare开源、覆盖广、DataFrame 友好、适合交叉校验和低成本补充多数接口依赖公开网页或第三方站点稳定性,不能作为唯一权威源
OpenBB扩展式数据接入、统一入口、多前端形态、凭据集中管理AxData 当前聚焦本地 A 股数据底座,不追求金融全品类聚合平台
Qlib数据层、因子层、研究/回测衔接、点时数据意识不以 Qlib .bin 作为主存储;AxData 使用开放 Parquet,并可向 Qlib 格式导出

源端接口目录、字段先行策略和实时/直取边界按实际需求逐个补充。

参考链接:

架构原则

关键设计决策