Skip to content

docs(futu): 对照主流用法修正探索文档 - #14

Merged
HRLoveFun merged 2 commits into
mainfrom
worktree-futu-mainstream-comparison
Sep 11, 2026
Merged

HRLoveFun merged 2 commits into
mainfrom
worktree-futu-mainstream-comparison

Conversation

@HRLoveFun

Copy link
Copy Markdown
Owner

目的

回应对 #9(已合并的 futu 探索文档)的追问:"市面上 futu-api 主流方式是什么,当前设想的使用方式有哪些和主流方式不一致?" 对照官方文档、FutunnOpen/py-futu-api、社区 OpenD 生产部署实践,补一份差异分析;顺带校验发现 reorg B1/B2 已落地,把文档里"假设的 provider seam"改成"对照已落地的真实代码"。

无代码改动,无新增 ADR。

新增 §6 Part F——主流用法 vs 本文档设想

# 设想 主流 后果
1 按次 open/subscribe/unsubscribe/close 长连接 + push 回调,订阅一次持续消费推送 契合 Flask 无状态模型,但频繁 subscribe/unsubscribe 撞 60s 最短持有限制,且拿不到推送模型的"常新"优势——是有意简化,不是疏漏
2 没说清楚谁持有 OpenD 连接 一个长驻单例网关进程独占管理连接和订阅状态 OptionLab 用 gunicorn --workers 2(prefork)——若每个 worker 各自连 OpenD,会争抢同一账户共享的 1000 条订阅配额和最高行情权限,是竞态问题,不只是限流问题
3 未提及 futu SDK 内部线程不能跨 fork() 存活 连接必须在 worker fork 之后惰性创建,不能在 import 时建,否则 worker 2..N 拿到的是死连接
4 归因 US 行情失败为"盘后" 根因是未购买付费 Nasdaq Basic 行情卡,任何时段都会超时 已在 §1.4/§3.3 原地更正(依据 py-futu-api issue #25)
5 get_market_snapshot 做免订阅批量查询 美股场景下这是多年未修的已知问题,不是等等就会好 不要指望它自愈;预算买卡或把 futu 限定在 HK/CN
6 只做行情,不做交易 多数教程/社区项目行情+交易两条腿都占 有意收窄范围,明说以免被当成疏漏

顺带发现并修正

business_line_reorg.md 的 B1(provider seam)/B2(canonical 表)已合并落地——data_pipeline/providers/base.pyMarketDataProvider/OptionChainSnapshot/OptionLeg 已是真代码,不再是本文档原先的假设草图。但校验发现:services/options/{chain,preload,builder}.pycore/decision/candidate.py 仍在用 legacy shim 的 dict-of-DataFrames 路径get_provider(...).option_chain() 目前零调用方。据此改写了 §3.1/§4.2/§5 F1–F3:给 futu 加 provider 只是必要条件,把这几个消费者迁移到 canonical 类型才是 ADR 0011 真正要求的、绕不开的必做项,不是顺手清理。

检查

  • python scripts/doc_guard.py — clean(pre-commit 全绿)
  • 无代码改动,无测试影响

🤖 Generated with Claude Code

HRLoveFun and others added 2 commits September 11, 2026 21:05
回应「市面上 futu-api 主流用法 vs 本文档设想」的追问,做两件事:

1. 新增 §6 Part F——对照官方文档 (openapi.futunn.com)、py-futu-api 仓库、
   社区 OpenD 生产部署实践,列出 6 处设想与主流用法的差异:连接生命周期
   (长连接+推送 vs 本文档的按次订阅/取消订阅)、连接归属(futu 订阅配额
   /行情权限是账户级共享,需要单例网关进程,而非每个 gunicorn worker 各开
   一个连接)、fork 安全(SDK 内部线程不能跨 fork 存活)、部署形态
   (headless docker + 登录 token 持久化 volume 才是主流生产模式)等。

2. 更正一处此前的错误归因:US 现货/实时行情失败的根因是**未购买付费
   Nasdaq Basic 行情卡**,而非"盘后"——has been wrong in §1.4/§3.3, both
   fixed in place(依据 py-futu-api issue #25 的社区共识)。

3. 校验发现 business_line_reorg B1/B2 已落地:`data_pipeline/providers/
   base.py` 的 MarketDataProvider/OptionChainSnapshot/OptionLeg 已是真实
   代码,不再是假设的草图;但 `services/options/*` 仍走 legacy shim 的
   dict-of-DataFrames 路径,尚未迁移到 canonical 类型——§3.1/§4.2/§5 F1-F3
   据此改写,标注 futu provider 落地时的必做迁移项,不再只是"顺手清理"。

无代码改动,无新增 ADR。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CI's `ruff format --check .` formats fenced python code blocks inside
.md files too (repo-wide, no path filter) — the OptionLeg/OptionChainSnapshot
sketch added in the mainstream-comparison pass wasn't run through it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@HRLoveFun
HRLoveFun marked this pull request as ready for review September 11, 2026 13:20
@HRLoveFun
HRLoveFun merged commit c95a6e3 into main Sep 11, 2026
3 checks passed
@HRLoveFun
HRLoveFun deleted the worktree-futu-mainstream-comparison branch September 11, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant