From 81459e2102a2a2ddc4df3ef4148c6440ab01109d Mon Sep 17 00:00:00 2001 From: GradientDescent Date: Fri, 11 Sep 2026 22:14:14 +0800 Subject: [PATCH] =?UTF-8?q?docs(futu):=20=E6=A0=B8=E5=AE=9E=E6=9C=9F?= =?UTF-8?q?=E6=9D=83=E6=95=B0=E6=8D=AE=E6=98=AF=E5=90=A6=E5=8C=85=E5=90=AB?= =?UTF-8?q?=20HV=20=E6=97=B6=E9=97=B4=E5=BA=8F=E5=88=97=20(=C2=A72.5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 回应"futuapi期权数据是否包含HV时间序列"的追问,对照官方文档逐一核实: - get_option_expiration_date / get_option_chain / subscribe+get_stock_quote / get_market_snapshot 四个调用(§2.1-2.3 已列全字段)完全没有 HV,全是 快照/静态字段,没有任何序列。 - 富途标准 K 线技术指标(MA/MACD/RSI/BOLL/KDJ/EMA/SAR/WMSR/BIAS/CCI/PSY/ VR/OSC/九转)也不含 HV——HV 不是能挂在任意K线上的通用指标。 - 唯一出现"HV"字样的是财务/财报体系的 get_financials_earnings_price_move 接口,按 code+periodCount 返回每次历史财报日前后若干交易日的 option_iv/option_hv——确实是"带 HV 的时间序列",但是财报事件窗口切片, 不是任意区间连续序列,替代不了 core/signals/hv.py 需要的 ~250 日滚动 窗口;计算口径未公开,跟项目现有 20日/252日 约定是否可比未知;且属于 第四个独立接口面,跟期权链三个调用无关。 结论:§3.6 的判断不变——两个"两者都用"模块的历史价格腿仍然只能走 yfinance。但顺带记录一个真正只有 futu 能做、yfinance 结构性做不到的 能力(跨多次历史财报的 IV/HV 对照,ADR 0004 的 gap),标注为独立探索 方向(新增 Q-g),不并入本次 provider seam 范围。 无代码改动,无新增 ADR。 Co-Authored-By: Claude Sonnet 5 --- docs/plans/futu_provider_integration.md | 75 ++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/docs/plans/futu_provider_integration.md b/docs/plans/futu_provider_integration.md index 634c697..8e3e99e 100644 --- a/docs/plans/futu_provider_integration.md +++ b/docs/plans/futu_provider_integration.md @@ -1,8 +1,8 @@ # Exploration: futu-api as a Second Data Provider **Date**: 2026-09-11, updated 2026-09-11 (Part F + mainstream-vs-plan pass; -§3.6 module-split pass) | **Owner**: repo owner | **Status**: EXPLORATION — -no futu code, no new ADR +§3.6 module-split pass; §2.5 HV-field check) | **Owner**: repo owner | +**Status**: EXPLORATION — no futu code, no new ADR > **Update**: the business-line reorg's batches **B1–B10 have since landed** > (merged to `main`, see `business_line_reorg.md` §0/§10) — `providers/base.py`, @@ -37,6 +37,7 @@ current codebase and the now-landed ADR 0011 canonical schema. | Biggest blocker | **OpenD is a stateful, authenticated, GUI-oriented local daemon.** It breaks ADR 0002's "works out of the box / zero infra" property and cannot be dropped onto a headless VPS without the Linux headless build + a login ceremony + crash supervision. | | Which modules need both stock price *and* option data? | Only **two call sites**, both the same pattern (HV percentile from ~1y of daily closes vs. current option IV, per ADR 0004): the Volatility Analysis tab's "Vol Premium" block and the Strategy Builder's `vol_context`. Everywhere else is cleanly price-only or option-only already — see §3.6. | | Can futu's option data also give us stock price info (e.g. latest price)? | The underlying's `subscribe`+`get_stock_quote` call (already needed to resolve `spot`, §3.3) returns a full current-session quote — last price, today's OHLC, prev close, volume — not just "last price". But it's a **snapshot, not a series**, so it cannot feed the two "both" modules' HV calc; their price leg stays on yfinance regardless. | +| Does futu's option data include an HV time series? | **No** — none of the three option-chain calls (§2.1–§2.3) carry HV, and futu's standard kline indicators (MA/MACD/RSI/BOLL/KDJ/…) don't include it either. The one place "HV" exists at all is a *different*, fundamentals-family endpoint (`get_financials_earnings_price_move`) that returns `option_iv`/`option_hv` only in windows around past earnings dates — not a continuous series, not comparable to this project's HV convention without verification, and not part of the option-chain surface this doc scopes. See §2.5. | --- @@ -172,6 +173,62 @@ contract: | `contractSymbol` | `code` | optional, only if a consumer starts needing it | | `spot` | see §3.3 | **not** from futu for US without a Nasdaq Basic quote card | +### 2.5 Does the option data include an HV time series? No — with one narrow, unrelated exception + +Added 2026-09-11, checked against the official docs because §3.6 leans on "the +price leg of the two 'both' modules must stay on yfinance" — worth confirming +that isn't leaving a futu capability on the table. + +**The three option-chain calls above (§2.1–§2.3) — no HV, no such field at +all.** Every field in `get_option_expiration_date`, `get_option_chain`, +`get_stock_quote` (for a contract or the underlying), and `get_market_snapshot` +is enumerated in §2.1–§2.3 and `archive/futu_integration/field_mapping.md`; +none of them carry historical volatility, and none return a series — every +call in this family is a point-in-time snapshot or static metadata, by +construction. + +**Futu's standard technical-indicator set doesn't have it either.** The +indicators attachable to any kline (MA, MACD, RSI, BOLL, KDJ, EMA, SAR, WMSR, +BIAS, CCI, PSY, VR, OSC, 九转/"nine turns") do not include HV — it isn't a +general "attach to a candlestick series" indicator in futu's system. + +**The one exception lives in a different API family and doesn't help here.** +`get_financials_earnings_price_move`(获取财报日前后价格涨跌幅表现) — a +**fundamentals/earnings** endpoint, not a quote/option-chain one — takes +`code` + `periodCount` (past earnings cycles, default 10, max 50) and returns +one `PricePerformanceRow` per trading day in the window around **each** +historical earnings date, and each row carries both `option_iv` and +`option_hv` (percent). So there genuinely is an "HV time series with options +context" in futu's API surface — but: + +- it's **earnings-window-anchored** (`day_offset` relative to each past + earnings publish date), not a continuous series over an arbitrary + `[start, end]` — it cannot stand in for the rolling ~250-trading-day window + `core/signals/hv.py::hv_percentile` needs; +- `option_hv`'s computation window is **undocumented** — this project's HV is + a specific, stated convention (20-day HV, 252-day percentile lookback, + `docs/constraints.md` §5); futu's number is not known to match, so the two + are not safely comparable without independent verification; +- it is a **fourth** futu API surface beyond the three in §2.1–§2.3 + (expiration dates / static chain / subscribed quotes), with its own + undocumented permissions and rate limits — adopting it would widen the + provider's `import futu` surface, not narrow it. + +**Conclusion: no change to §3.6.** The price leg of the two "both" modules +stays on yfinance/`DataService` regardless; nothing in futu's option-adjacent +APIs is a substitute for a continuous historical series. + +**But it's worth flagging as its own, unrelated opportunity.** `option_iv` + +`option_hv` across *many past earnings events* for one ticker is something +yfinance cannot do at all — ADR 0004 exists precisely because yfinance's +option chain has no history, so there's no way to look at IV/HV around last +quarter's earnings, let alone the last 10. A future "IV/HV behaviour around +earnings" feature would be a genuine futu-only capability, not a yfinance +substitute — but it is a **different project** from "replace the option chain +with futu" (a different endpoint, different fields, different question being +answered) and should be scoped separately if ever pursued, not folded into +this seam. + --- ## 3. Part C — Mapping to the project's data format @@ -369,7 +426,9 @@ where a price series and an option snapshot must both be present at once. time series; a richer point-in-time quote (even with today's OHLC) is still one data point. The price leg of ①② must stay on yfinance regardless of which provider serves the option leg — "futu gives us the latest price too" - does not let these two modules drop their yfinance dependency. + does not let these two modules drop their yfinance dependency. Nor is there + an HV series hiding elsewhere in futu's option-adjacent APIs to fall back + on — confirmed none exists (§2.5). - **One thing to actively avoid**: a future refactor "simplifying" ①/② by reusing the spot/OHLC that a futu `option_chain()` call already fetched, instead of a separate `get_cleaned_daily` call. That would silently swap a @@ -564,6 +623,7 @@ in place. | Q-d | Python/dep drift: base conda is 3.13 + numpy 2.x + yfinance 0.2.66, `requirements.txt` pins 3.12 + numpy 1.26 + yfinance 0.2.61, `.venv` is missing numpy entirely. Resolve **before** adding another dep. | F0 (and independent) | | Q-e | Does the account here hold a Nasdaq Basic quote card (or equivalent HK pack)? Determines whether futu US spot/quotes work **at all**, independent of time of day. Needs the §1.3 smoke test — a card-less account will time out even during market hours. | F1 | | Q-f | §6 below: is a per-request `OpenQuoteContext` (this doc's F2 sketch) acceptable, or does the shared subscription quota / quote-tier force a **singleton gateway process** owning the futu connection? | F2/F3 | +| Q-g | (§2.5) `get_financials_earnings_price_move`'s `option_iv`/`option_hv` across past earnings is a real futu-only capability yfinance cannot replicate (ADR 0004's gap). Worth a **separate** exploration as its own feature, not folded into this provider seam? | out of scope for this doc | --- @@ -612,3 +672,12 @@ in place. (`get_market_snapshot` times out for US symbols without a paid Nasdaq Basic quote card — confirms and corrects §1.4/§3.3's original "off-hours" attribution) +- HV field check (§2.5, 2026-09-11): official docs — + [获取财报日前后价格涨跌幅表现](https://openapi.futunn.com/futu-api-doc/quote/get-financials-earnings-price-move.html) + (`option_iv` / `option_hv` per trading day around each past earnings date — + the one place "HV" appears anywhere in futu's API, and it's a fundamentals + endpoint, not a quote/option-chain one), + [获取指标列表](https://openapi.futunn.com/futu-api-doc/quote/get-indicator-list.html); + 富途牛牛 [技术指标](https://support.futunn.com/topic68) (the standard + kline-indicator set — MA/MACD/RSI/BOLL/KDJ/EMA/SAR/WMSR/BIAS/CCI/PSY/VR/OSC/ + 九转 — confirms HV is not a general-purpose indicator in futu's system)