TongDaXin Standard Data eXchange — 通达信行情数据通用协议基础设施
类比 HTTP 世界的
requests库:稳定、标准、可组合,专注协议层,不做应用层业务。
- 当前版本:
1.6.1(已打 tagv1.6.1并发布)· v1.4.3 / v1.5.0 / v1.5.1 / v1.5.2 / v1.5.3 / v1.5.4 为未打 tag 的源码候选 · 最新已发布 GitHub Release:v1.6.1;本包不在 PyPI(Trusted Publisher 与pypi环境已配置,推送版本 tag 后工作流会执行 OIDC 上传)· CHANGELOG · 逐版本发布说明
atst 是通达信(TDX)行情数据的通用底层协议基础设施。它完整覆盖 TDX 的 5 套协议族,提供从原始二进制帧解析到统一查询内核(Client)的全链路数据接入能力。
| 痛点 | atst 的解法 |
|---|---|
| TDX 协议封闭、逆向工程门槛高 | 85 命令账本 + 61 精确解析器 + 三级分派 + YAML 协议规范 |
| 单一数据源不可靠 | 14 个 Provider 注册表 + 216 capability 声明;provider-first:一次请求绑定一个 Provider,跨源只在显式 FallbackPolicy 下发生 |
| 数据来源不可追溯 | 每个结果携带 Provenance(provider/channel/capability/命令),溯源不符即抛,杜绝静默换源 |
| 数据请求被隐式缓存污染 | 执行路径零缓存:每次请求直达绑定 Provider |
| 同步/异步 API 分裂 | 签名镜像双客户端(TdxClient / AsyncTdxClient)+ 奇偶门禁 |
| 协议命令持续演进 | YAML 规范驱动 + codegen 自动生成 + golden_audit 三旗标防漂移 |
| 主站可用性差 | 主站池治理 + 三级路由降级 + 后台测速排序 + 社区候选注入 |
量化交易开发者、金融数据工程师、行情中间件开发者、AI Agent(量化策略 / 选股 / 回测 / 因子计算)。
回测引擎、选股系统、交易终端、Web 可视化平台 —— 专注协议层与数据接入层,向上可组合到任意应用。
- 协议全覆盖:5 套 TDX 协议族、85 命令、61 精确解析器,YAML 规范驱动 + codegen 自动生成,未知命令可探测、可自采集、可验证闭环。
- 数据可追溯、不静默换源:每个结果携带
Provenance(provider/channel/capability/命令),provider-first 不变量保证一次请求绑定一个 Provider,跨源只在显式FallbackPolicy下发生。 - 零缓存、单一执行内核:请求直达绑定 Provider,无聚合降级路由、无隐式缓存层——结果永远最新、来源永远可解释。
- 同步/异步 + 四套服务面:签名镜像双客户端,CLI / HTTP REST / WebSocket / MCP 全部只翻译为同一
Client调用,AI Agent 可直接接入。 - 零硬依赖:所有第三方库均为可选 extra,核心可在纯净环境运行。
- 洁净室原创:规格驱动 + License 隔离 + AST 相似度审计,原创合规。
类比 HTTP 世界的
requests:稳定、标准、可组合,专注协议层,不做应用层业务。
┌─────────────────────────────────────────────────────────────────────┐
│ 服务面(可选部署,只翻译不执行) │
│ CLI 33 子命令 · HTTP REST 12 端点 · WebSocket JSON-RPC · MCP 9 工具 │
├─────────────────────────────────────────────────────────────────────┤
│ Client / AsyncClient(唯一业务入口) │
│ 18 便捷方法(bars/quotes/snapshot/minute/trades/stream/call…) │
│ execute(QuerySpec) · typed(CapabilityQuery) · execute_with_policy │
├─────────────────────────────────────────────────────────────────────┤
│ UnifiedRuntime(唯一执行内核,零缓存) │
│ QueryPlanner.compile → QueryPlan(单 Provider / 单 Channel) │
│ DirectProviderExecutor:DIRECT_BINDINGS 303 条精确绑定 │
│ 流式:StreamSpec/StreamPlanner → StatefulQuoteStream │
├─────────────────────────────────────────────────────────────────────┤
│ catalog/(静态声明与一致性审计,无执行) │
│ capability 目录 + 规划期签名校验(fail-closed) │
│ Provider channel→adapter 绑定表 · Provider 隔离契约/守卫/审计 │
├─────────────────────────────────────────────────────────────────────┤
│ providers/(14 Provider · 216 capability 唯一事实源) │
│ tdx(85 命令) · tencent/sina/eastmoney/baidu/jsl/boc/iwencai(web 多源)│
│ local_vipdoc(reader 本地二进制) · builtin · derived(显式聚合) │
├─────────────────────────────────────────────────────────────────────┤
│ 协议核心层 │
│ commands(85 账本) · registry(三级分派 + 异常收口) · parsers(61 × 5 族) │
│ codec(帧/原语) · transport(池/心跳/测速) · client/(TdxClient 同步异步) │
├─────────────────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ 错误体系(E1-E9 九域) · 可观测性(Prometheus/StatsD/OTLP) │
│ 配置(6 源合并) · 安全(TLS/脱敏) · 输出(DataFrame/Parquet/CSV/DuckDB) │
│ 反馈(遥测/统计) · 工具链(capture/codegen/golden_audit/spec_audit) │
└─────────────────────────────────────────────────────────────────────┘
设计原则:每层可独立使用,零强制上层依赖。底层协议库可用,上层内核可选。
唯一执行路径:请求只能沿 Client → UnifiedRuntime → DirectProviderExecutor → Provider
下行;不存在第二条内核、聚合降级路由或隐式缓存层(由 tests/architecture/ 守卫锁定)。
| 特性 | 说明 |
|---|---|
| 5 套协议族 | 7709 标准 / 7727 扩展市场 / MAC 专属 / F10 资料 / 商品语义 |
| 85 命令账本 · 61 精确解析器 | L1 精确 → L2 通用启发 → L3 原始透传 三级分派;解析器逃逸原生异常统一收口为 ParseError |
| YAML 协议规范 | PROTOCOL_SPEC/ 规范驱动 + codegen 自动生成 + spec_audit 双向漂移检查 |
| 协议探测 | atst probe 0x052D 探测未知命令的二进制帧结构 |
| 特性 | 说明 |
|---|---|
| 同步/异步双 API | TdxClient + AsyncTdxClient(签名镜像、奇偶门禁) |
| 多协议族客户端 | GoodsClient / ExMarketClient / MacClient / F10Client |
| 主站池治理 | DEFAULT_HOST_POOL / POOL_BY_FAMILY / RankingStore + 三级路由降级 + 社区候选注入 |
| 特性 | 说明 |
|---|---|
| HTTP Web 45+ 源类 | 东财/新浪/腾讯/集思录/港股/中行等,httpx / urllib 双栈,31 模块;各家适配器按 Provider 归入 web/<provider>/adapters.py,跨 Provider 的域模块(资金流/龙虎榜/新闻/问财…)留 web/ 包根 |
| 本地 vipdoc 解析 | reader/ 解析通达信本地 .day / .min / 板块 / 财务二进制文件 |
| Provider 注册表 | providers/ 声明 14 Provider × 216 capability × channel,是唯一事实源;catalog/provider_bindings.py 声明 channel→adapter 绑定 |
| 流式订阅 | Client.stream → StatefulQuoteStream(轮询基类 QuoteStream/AsyncQuoteStream;engine 内核:ReconnectPolicy + BackpressureQueue + DeltaMerger + GapFiller + StreamEngine) |
| 特性 | 说明 |
|---|---|
数据出口(atst/output/) |
write() 认 4 种格式:DataFrame / Parquet / CSV / DuckDB;Sink 3 种格式(不含 CSV,CSV 只走 write() 或 to_csv()),全部原子写;读回面对称补齐——from_parquet() 读落盘日线、from_csv() 读回人工加工过的 CSV(全 str,不隐式推断类型) |
| 统一业务入口 | Client / AsyncClient(18 便捷方法 + execute/typed/call 通用面),永不隐式换源、永不缓存 |
| HTTP REST 网关 | 12 端点(capability 白名单 + TaskStore 钳制),只翻译为 Client 调用;另有 2 支只读本地代码表的清单端点(不发外呼) |
| WebSocket JSON-RPC | 长连接实时推送 |
| MCP 工具服务 | 9 工具,AI Agent 可直接调用 |
| 特性 | 说明 |
|---|---|
| 唯一内核 | UnifiedRuntime:QuerySpec → QueryPlan → 绑定执行 → QueryResult,零缓存、无请求合并 |
| 精确绑定执行 | DirectProviderExecutor 按 DIRECT_BINDINGS[(provider, channel, capability)](303 条)直调实现 |
| 规划期 fail-closed | catalog/capability.py::validate_call 用真实方法签名绑定参数,参数错误在 I/O 前抛 |
| 执行身份与溯源 | runtime/identity.py + runtime/provenance.py:结果 provenance 与计划身份不符即抛 |
| 显式跨源编排 | runtime/orchestration.py:仅当调用方给出 FallbackPolicy 时按序尝试,逐次记入 OrchestratedResult |
| 启动三方对账 | runtime/audit.py::audit_runtime:registry / catalog / bindings 不一致即报错 |
| 60+ Typed Query 契约 | 10 领域基类 + 9 Domain Record 族,字段名与内核方法签名一一对应(Client.typed) |
| 批量执行 | Client.quotes_batch() → BatchResult:逐 symbol 三态(ok/missing/failed)、保序、串行直连单一 Provider(无隐藏换源) |
| 流式生命周期 | StreamSpec/StreamPlanner + StatefulQuoteStream(订阅/退订/状态查询) |
| 特性 | 说明 |
|---|---|
| 零硬依赖 | 所有第三方库均为可选 extra |
| 错误分类树 | 九域 code 段(E1–E9)+ 每个异常自带 RetryAdvice;类清单以 atst.errors 现读为准,文档不抄录会过期的数字(docs/errors.md) |
| 可观测性 | zero-dep 指标注册表 + Prometheus/StatsD/OTLP 三导出器 |
| 传输与错误卫生 | TDX 连接可按 security.use_tls 走 TLS(默认关,ssl.create_default_context() 校验主机名);错误上下文按关键字脱敏后才可外发。凭据存储不在本库范围内(ADR-007-010 已删除三级 CredentialStore);HTTP 传输层同样不做 Provider 主机白名单——该守卫从未接入任何生产链路,已在单内核收敛时移除,单源边界由调用方自证,内核侧的跨源约束只有一条:选定的 Provider 不会被悄悄换成别家 |
| 原创合规 | 洁净室工程规范:规格驱动 + License 隔离 + AST 相似度审计 + Golden 数据自采集 |
| 协议族 | 端口 | 覆盖范围 | 命令账本 | 精确解析器 | 通用/透传 |
|---|---|---|---|---|---|
7709 标准(quotation) |
7709 | A 股行情(K 线/实时/证券计数;分时与逐笔在结构化面已下线,见 docs/providers/tdx.md) |
39 | 18 | 是 |
7727 扩展市场(ex_quotation) |
7727 | 港股/美股/期货/外汇/期权 | 17 | 15 | 是 |
MAC 专属(mac_quotation) |
7709 | 板块/指数/概念/财务 | 16 | 16 | 是 |
F10 资料(f10) |
7709 | 公司概况/股东/财务/交易信息 | 2 | 1 | 是 |
商品语义(goods) |
7727 | 商品品种/合约/行情 | 11 | 11 | 是 |
未知命令自动归档至
PROTOCOL_SPEC/UNKNOWN/,工具链支持capture采集 →codegen生成 →spec_audit验证闭环。
| 能力 | atst | mootdx | easy_tdx | easyquotation |
|---|---|---|---|---|
| TDX 协议覆盖 | 85 命令 / 61 精确解析器 / 5 协议族 | ~20 命令 | ~15 命令 | ❌(HTTP only) |
| 三级分派 | L1 精确 → L2 启发 → L3 透传 | 仅 L1 | 仅 L1 | ❌ |
| 同步 + 异步 | ✅ 双客户端 | ❌(仅同步) | ❌(仅同步) | ❌ |
| HTTP Web 多源 | 45+ 源 / 14 Provider 注册表 | ❌ | ❌ | ✅(单一源) |
| 本地 vipdoc 解析 | ✅ 多格式 | ❌ | ❌ | ❌ |
| 流式订阅 | ✅ engine 内核 | ❌ | ❌ | ❌ |
| 主站池治理 | ✅ 多主站 + 测速 + 社区注入 | 基础 | 基础 | ❌ |
| 统一业务入口 | ✅ Client 18 方法 + 通用 execute/typed |
❌ | ❌ | ✅(仅行情) |
| HTTP/WS/MCP 服务 | ✅ 三模式 | ❌ | ❌ | ❌ |
| 溯源与 provider-first | ✅ Provenance 强制 + 显式 FallbackPolicy | ❌ | ❌ | ❌ |
| 可观测性 | ✅ Prometheus/StatsD/OTLP | ❌ | ❌ | ❌ |
| YAML 协议规范 | ✅ + codegen + spec_audit | ❌ | ❌ | ❌ |
| 零硬依赖 | ✅ 所有 extra 可选 | 有硬依赖 | 有硬依赖 | 有硬依赖 |
pip install "atst[all]" # ← 尚不可用:本包目前不在 PyPI 上(见下)
pip install -e ".[dev]" # 开发体验(pytest/ruff/mypy/pytest-asyncio/hatchling)装包的实际口径(实测):
https://pypi.org/pypi/atst/json返回{"message": "Not Found"}——PyPI 上没有atst这个名字,所以pip install atst与上面第一行的 extras 安装今天都装不到东西。可用的安装路径只有两条:git clone https://github.com/coeasy/atst.git && cd atst pip install ".[all]" # 从源码 pip install "atst[all] @ file:///绝对路径/atst-<版本>-py3-none-any.whl" # 从构建产物 python -m build # 产物在 dist/;make build 走同一套 canonical 校验extras 的名字(
dataframe/parquet/duckdb/web/metrics/server/tools/all)是仓内pyproject.toml声明的那一套,从源码或 wheel 装时同样可用;本节只在真正上架 PyPI 后才需要改写。
[project.optional-dependencies].dev已声明,本地与 CI 使用同一 门禁口径(覆盖率阈值只在pyproject.toml [tool.coverage.report] fail_under写一次, Makefile/CI 不再各传--cov-fail-under),不再有「装了依赖却跑不出--cov」的漂移。
| Extra | 依赖 | 功能 |
|---|---|---|
dataframe |
pandas | DataFrame 输出 |
parquet |
pyarrow | Parquet 写出(to_parquet / Sink("parquet")) |
duckdb |
duckdb | DuckDB 写出(to_duckdb / Sink("duckdb")) |
web |
httpx | HTTP Web 行情源 |
metrics |
prometheus-client | Prometheus 导出 |
server |
fastapi, uvicorn, websockets | HTTP REST 网关 + WebSocket RPC |
tools |
tzdata (win32 only), zstandard | capture 工具链(时区 + zstd 编码) |
dev |
pytest/pytest-cov/pytest-asyncio/ruff/mypy/hatchling | 开发体验 |
all |
以上非 dev 项的并集 | 完整功能 |
MCP 工具服务不需要 extra:
atst/integration/mcp/是纯标准库的 JSON-RPC over stdio,全仓对pydantic/mcp两个包没有运行期依赖。
本仓的发布由 .github/workflows/wheels.yml 自动化:推送一个 vX.Y.Z 标签即触发,CI 会
构建 canonical wheel + sdist、校验字节级可复现性、生成 SHA256SUMS.txt 与
RELEASE-METADATA.json,创建草稿 GitHub Release 并附带产物,最后在草稿通过后自动发布。
这就是"GitHub 发布之后自动构建安装包"的入口——你只需要在 GitHub 上发布一个 vX.Y.Z 标签,
其余由流水线完成。
流水线刻意以标签推送为唯一发布触发器(CI 契约
test_release_identity_uses_tag_push...强制),以保证版本身份永远来自标签 +atst/_version.py单一事实源,避免重复构建与 版本漂移。release:事件触发器被同一契约排除,因此不要改成on: release。
- 改版本号:编辑
atst/_version.py的__version__(单一事实源;pyproject.toml通过[tool.hatch.version]动态读取,不要写死静态version=)。 - 补版本文档:在
CHANGELOG.md加## [X.Y.Z] - YYYY-MM-DD小节,并在docs/releases/目录下新增以版本号命名的发布说明(已有范例见docs/releases/v1.0.0.md)。这两处是硬门禁:build-dist的身份步会断言docs/releases/v<version>.md存在、且CHANGELOG.md含## [<version>]标题,缺一即以SystemExit让流水线直接变红。 - 提交并打标签:
git add -A && git commit -m "release: vX.Y.Z" git tag vX.Y.Z && git push origin vX.Y.Z
- 流水线自动:构建 → 复现性校验 → 草稿 Release + 产物 → 发布。
- PyPI 发布是显式 opt-in:仅当仓库变量
PUBLIC_RELEASE=true时,publish-pypi才用 OIDC trusted publishing 上传(重复版本会被scripts/check_pypi_release.py校验并安全跳过)。默认不发布到 PyPI。首次启用前, 还需在 PyPI 创建 pending Trusted Publisher;准确字段与 GitHub 环境配置见docs/release-publishing.md。 - Docker 镜像同理,需
PUBLIC_RELEASE=true且PUBLISH_DOCKER=true。
- PyPI 发布是显式 opt-in:仅当仓库变量
流水线依赖 GitHub Actions 实际调度 runner。私有仓库的 Actions 消耗账号付费分钟——当免费
额度用尽、没有有效付款方式、或 spending limit 不足时,job 根本不会启动:每个 job 会在几秒内
failure,步骤数为 0、runner 名为空,页面提示
The job was not started because recent account payments have failed or your spending limit needs to be increased.。
这与仓库代码无关(本地 make gates 全绿也照样如此)。
处理方式(任一):把仓库设为 public(公开仓库的 Actions 分钟免费);或到
Settings → Billing and plans 补付款方式并提高 Actions spending limit;额度重置后重推 vX.Y.Z
标签即可重新触发。runner 镜像迁移预告(ubuntu-latest will migrate to Ubuntu 26 ...)只是提示,不是失败原因。
python scripts/build_package.py --smoke # PEP 517 隔离构建 + 校验 + 临时 venv 冒烟安装
python scripts/build_package.py --verify-only --dist-out dist # 只校验已有产物校验要求恰好 1 个 wheel + 1 个 sdist,二者携带完整运行时源码闭包与 py.typed,
并通过 twine check。
| 维度 | 支持范围 |
|---|---|
| Python | 3.10+(使用了 X | Y 类型语法与 zoneinfo) |
| 操作系统 | Windows 10/11 · macOS 12+ · Linux(主流发行版) |
| CI 矩阵 | Ubuntu 3.10/3.11/3.12/3.13/3.14 + Windows 3.11/3.12 |
| 网络 | TCP 7709/7727(TDX 主站)+ HTTPS(Web 源) |
| 存储 | 文件系统(~/.atst/ 配置/主站排名/反馈)+ Parquet/DuckDB |
from atst.client import TdxClient
client = TdxClient()
bars = client.bars("sh600519", period="day", count=80) # K 线
quotes = client.quotes(["sh600519", "sz000001"]) # 实时行情
count = client.security_count(market=1) # 1=上海, 0=深圳import asyncio
from atst.client import AsyncTdxClient
async def main():
client = AsyncTdxClient()
bars, quotes = await asyncio.gather(
client.bars("sh600519", period="day", count=80),
client.quotes(["sh600519", "sz000001"]),
)
print(len(bars), len(quotes))
asyncio.run(main())from atst import Client, FallbackPolicy, QuerySpec
from atst.typed_query import FundHoldingsQuery
client = Client()
# 1) 便捷方法:每个结果自带 provenance,零缓存、不静默换源
bars = client.bars("sh600519", period="day", count=80)
print(len(bars.data), bars.meta.provider, bars.meta.channel)
quotes = client.quotes(["sh600519", "sz000001"])
# 2) 通用面:任何 capability 走同一入口,参数在规划期按真实签名校验
spec = QuerySpec.build("bars", symbols="sh600519", period="day", count=30)
result = client.execute(spec)
# 3) 类型化糖衣:冻结 dataclass 契约 → 内核 → 强类型 Domain Record
typed = client.typed(FundHoldingsQuery(code="000001"))
print(typed.capability, len(typed.data))
# 4) 批量:逐 symbol 三态(ok/missing/failed),保序
batch = client.quotes_batch(["sh600519", "sz000001"])
# 5) 跨源只在显式策略下发生(默认永不发生)
orchestrated = client.quotes(["sh600519"], policy=FallbackPolicy(providers=("tdx", "tencent")))
client.close()import asyncio
from atst import AsyncClient
async def main():
async with AsyncClient() as client:
bars, quotes = await asyncio.gather(
client.bars("sh600519", period="day", count=80),
client.quotes(["sh600519", "sz000001"]),
)
print(len(bars.data), len(quotes.data))
asyncio.run(main())
TdxClient/AsyncTdxClient(atst.client)是协议层客户端,可脱离内核单独使用; 服务面(CLI/HTTP/WS/MCP)全部只翻译为Client调用,不自行选源、不缓存。
atst bars sh600519 --period day --count 80 # K 线
atst quotes sh600519 sz000001 # 实时行情
atst server-test # 主站测速
atst serve --bind 0.0.0.0 --port 8000 # HTTP 服务
atst probe 0x052D # 协议探测
atst feedback stats # 使用统计
# 主站池巡检
atst hosts audit --family quotation # 仅 7709 标准族
atst hosts audit # 全 5 族并发巡检
atst hosts --hosts-file extra_hosts.json audit # 注入社区贡献主站候选
atst hosts audit --report /tmp/audit.json --markdown /tmp/audit.mdatst/
├── client/ # api.py —— Client / AsyncClient 唯一业务入口(18 便捷方法 + execute/typed/call)
│ # core/sync/async_/factory —— TdxClient 传输层与共享纯协议 SSOT
├── runtime/ # 唯一执行内核:kernel(零缓存)/executor(303 绑定)/orchestration(显式跨源)
│ # /audit(启动三方对账)/identity/provenance(溯源守卫)
├── catalog/ # 静态声明与一致性审计:capability(目录+规划期签名校验)/provider_bindings
│ # /provider_contract/provider_guard/*_audit —— 无执行、无选源
├── providers/ # 14 Provider × 216 capability × channel 注册表(唯一事实源)
├── query.py # QuerySpec/QueryPlan/QueryPlanner + 指纹
├── result.py # QueryResult + ResultMeta + Provenance
├── batch.py # BatchResult/BatchItem 三态批量契约
├── typed_query.py # 60+ CapabilityQuery 冻结契约 + TypedQueryResult
├── stream_contract.py # StreamSpec/StreamPlanner 流式契约
├── errors.py # 错误分类树(E1-E9 九域)+ RetryAdvice
├── diagnostics.py # 结果侧数据瑕疵的唯一发射口(WarningCode + 收集器,strict 的判据来源)
├── error_envelope.py
├── protocol/ # commands(85 账本)/registry(三级分派+异常收口)/parsers(61 × 5 族)
├── codec/ # framing(帧)/primitive(原语 + count_guard + zlib strict)
├── transport/ # base(RLock 租约)/async_/pool(4 槽)/ratelimit/speedtest/hosts/sniff
├── client/ # core.py(同步/异步共享纯协议 SSOT) + sync/async_/factory + 5 族客户端
├── web/ # 45+ HTTP 源类(惰性导入)+ 域 Mixin 会话 + 共享分页器
│ # tencent/sina/eastmoney/baidu/jsl/boc 六包按 Provider 承载 adapters.py
├── reader/ # vipdoc 本地文件解析(day/min/板块/财务)
├── profile/ # 数据规格探测(帧/文件双探测器 + presets)
├── domain/ # symbol(单一事实源)/models/finance 记录/adjust/calendar
├── streaming/ # QuoteStream/AsyncQuoteStream(轮询+diff)/push + engine 内核
├── output/ # DataFrame/Parquet/CSV/DuckDB 原子写
├── sink/ # LocalDaySink:写回 vipdoc .day 二进制
├── charset/ # 字符集自动探测(GBK/GB18030/Big5/UTF-8)
├── config/ # 6 源合并 + 严格校验 + env 归一
├── integration/ # runtime_http(12 端点)/runtime_ws/runtime_ws_server/mcp(9 工具)/serialization
├── observability/ # 指标注册表 + Prometheus/StatsD/OTLP 导出器 + start_exporter
├── feedback/ # 错误/用量上报 + 遥测 + 使用统计
├── tools/ # capture/spec_audit/codegen/golden_audit/golden_expand/check_originality
├── trade/ # 交易协议模拟器(实验性可选模块:SimTransport 纯内存模拟,不接入内核)
├── __main__.py # python -m atst 入口(与 atst 控制台脚本等价)
├── universe/ # 标的清单(按类别取全部标的:代码表/新浪节点/tdx 段表三级降级)
└── cli/ # CLI 入口(33 子命令;数据命令全部经 Client,6 个传输/诊断命令除外,见 runtime_commands.py)
默认永不跨源(provider-first 不变量):
QuerySpec(capability, provider=None|显式)
→ QueryPlanner:provider 为 None 时按注册表偏好选唯一 Provider;多 channel 冲突则要求显式指定
→ QueryPlan(单 provider, 单 channel) → DirectProviderExecutor → 该 Provider 的实现
→ QueryResult(meta.provenance 记录实际来源;与计划身份不符 → 抛错)
- Provider 不可用/失败:只抛出该 Provider 的错误,不自动换源——没有"多级降级 + 熔断 + 合成数据"这一类兜底路由。
- 需要跨源时由调用方显式声明顺序:
client.quotes(symbols, policy=FallbackPolicy(providers=("tdx","tencent")))→ProviderOrchestrator按序尝试,返回OrchestratedResult(逐步记录成败与最终来源)。 - 时效性:
currentness(CurrentnessMode)声明口径,deadline_ms只是执行预算;options袋里只有atst.query.EXECUTED_OPTIONS列出的键会被执行面读取,其余键——包括atst.query.REJECTED_OPTIONS里的策略键(过期容忍、部分放行)——一律当场拒绝: 每次请求都回源,不存在可容忍的过期副本,partial 也始终是结果事实。
主站池由 DEFAULT_HOST_POOL / POOL_BY_FAMILY 定义,运行时通过 RankingStore
(~/.atst/server_ranking.json)落盘延迟样本并驱动三级路由降级。巡检工具:
# 通过 CLI(推荐)
atst hosts audit --family quotation --timeout 3 --workers 20 --samples 3
# 或调用脚本(支持 --report / --markdown / --strict / --no-save-ranking)
python scripts/audit_hosts.py --family all --report audit.json
# 外部候选注入(社区贡献主站入口)
cat > extra_hosts.json <<'JSON'
{
"quotation": [
{"host": "218.75.126.9", "port": 7709, "name": "custom-1"}
],
"ex_quotation": [
{"host": "180.153.180.86", "port": 7727, "name": "custom-2"}
]
}
JSON
atst hosts --hosts-file extra_hosts.json audit输出:每族 healthy/degraded/offline 三态 + JSON/Markdown 报告;候选延迟样本写
~/.atst/server_ranking.json(可 --no-save-ranking 关闭)。CI 中已配置
周三 09:00 UTC 定期巡检(host-audit job,非硬门禁)。
pytest tests/ # 全量测试(离线,无网络)
make gates # 12 步确定性门禁:lint+format→mypy→全量→bridges→golden→spec→对抗→可达性→originality→benchmark→interface-probe→docs
python -m atst.tools.golden_audit --gate # Golden L1 真实样本门禁(530 payload)
python -m pytest tests/adversarial -q # 对抗矩阵(9 payload × 85 命令,逃逸=0)
python scripts/audit_reachability.py --strict # 可达性门禁(孤儿=0)
python scripts/contract_audit.py --ci # Typed 契约↔注册表↔Domain Record 五段对账 + 内核编译审计(注册能力缺声明形状即 ERROR 阻断;Domain Record 待映射项按 PENDING 报告)
python -m pytest --cov=atst # 覆盖率门禁(阈值单源:pyproject fail_under=77)- CI:12 jobs;测试矩阵 Ubuntu 3.10–3.14 加 Windows 3.11/3.12;周一 08:00 UTC 全量确定性门禁,
周三 09:00 UTC 定期
host-audit - 架构守卫:
tests/architecture/(唯一内核、零缓存、无聚合降级路由、根级命名空间白名单、 已删层不可复活)+tests/provider_isolation/(Provider 隔离与溯源) - Ruff:
ruff check与ruff format --check均 0 错(dev 依赖钉版ruff==0.15.2) - mypy:
mypy atst/0 错(含--warn-unused-ignores) - Pre-commit hooks:
ruff check --fix+ruff format --check
GitHub 最新已发布版本是 v1.6.1(2026-10-30);v1.4.3–v1.5.4 为未打 tag 的源码候选。当前内核为单执行路径、零缓存、provider-first:
85 命令 / 61 精确解析器 / 5 协议族 / 14 Provider / 216 capability / 303 条精确绑定。
| 里程碑 | 状态 |
|---|---|
| 协议层:命令账本 + 解析器 + YAML 规范 + codegen 闭环 | ✅ |
| 单内核收敛:零缓存直调、无隐式跨源 | ✅ |
| Typed Capability 契约 + Domain Record 归一 | ✅ |
| 流式订阅:StreamSpec / StreamPlanner + StatefulQuoteStream | ✅ |
| 服务面:CLI / HTTP REST / WebSocket / MCP | ✅ |
| 文档-代码一致性门禁 | ✅ |
| 方向 | 说明 |
|---|---|
| 发布硬化 | 按 CI 环境数字重钉覆盖率阈值;PyPI 上架为显式 opt-in(仓库变量 PUBLIC_RELEASE=true) |
| 流式增量执行 | 流式数据增量合并 + 补数完整性保证 |
| 协议探测扩展 | 更多未知命令的自动采集 → codegen → spec_audit 闭环 |
| 多市场深化 | 港股/美股/期货/外汇/期权覆盖的字段级实测补齐 |
| 可达性收口 | 孤儿=0,每条豁免记录都被门禁盯着(死记录/过期记录/重复条目即红) |
| 对外面增强 | 扩充 MCP 工具与 HTTP 端点,覆盖高频使用场景 |
| 文档 | 内容 |
|---|---|
| docs/ARCHITECTURE.md | 现行架构(分层/内核/契约/服务面,与代码同轮钉死) |
| docs/api/interfaces.md | 项目接口文档(全部公开接口面汇总) |
| docs/quickstart.md | 快速入门 |
| docs/api/README.md | API 索引(内核/协议/传输/服务面/基础设施) |
| docs/configuration.md | 配置段、合并层与环境变量归一 |
| docs/cookbook/ | 场景示例(批量 K 线/显式跨源/离线 vipdoc/流式/Sinks/自定义命令/单内核) |
| docs/migration/ | 从 mootdx/easy_tdx/easyquotation 迁移 |
| docs/providers/ | 逐 Provider 能力与口径 |
| docs/tdx_status.md | TDX 全接口连通性矩阵(真机逐项实测口径) |
| docs/FAQ.md | 常见问题 |
| docs/troubleshooting.md | 排障指南 |
| docs/errors.md | 错误体系与 RetryAdvice 使用指南 |
| PROTOCOL_SPEC/ | 协议命令 YAML 规范 + codegen/spec_audit 闭环 |
| CHANGELOG.md | 版本变更记录(含 native 弃用时间线 v1.5.0/v1.6.0) |
| docs/releases/ | 逐版本发布说明(v1.0.0 → v1.6.1) |
欢迎贡献代码、文档、协议规范、主站候选、测试数据。请阅读:
MIT License - 详见 LICENSE