From 1b7d8a5fffa68305ca237f0403723c17ac291496 Mon Sep 17 00:00:00 2001 From: GitHub Date: Fri, 28 Aug 2026 20:14:41 +0800 Subject: [PATCH] =?UTF-8?q?docs(client):=20=E8=B5=84=E9=87=91=E6=B5=81?= =?UTF-8?q?=E5=8F=A3=E5=BE=84=E6=A0=87=E6=B3=A8=E2=80=94=E2=80=940x0fb5=20?= =?UTF-8?q?=E9=80=90=E7=AC=94=E4=B8=BA=E8=81=9A=E5=90=88=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E3=80=81=E6=8C=89=E6=88=90=E4=BA=A4=E9=A2=9D=E5=88=86=E6=A1=A3?= =?UTF-8?q?=EF=BC=8C=E4=B8=8E=E4=B8=9C=E8=B4=A2=E4=B8=BB=E5=8A=9B=E5=87=80?= =?UTF-8?q?=E9=A2=9D=E4=B8=8D=E5=8F=AF=E6=AF=94=EF=BC=88issue=20#55?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++-- docs/api_reference.md | 9 +++++++++ examples/08_fund_flow/fund_flow.py | 3 +++ examples/08_fund_flow/history_fund_flow.py | 5 +++++ src/easy_tdx/client.py | 23 +++++++++++++++++++++- src/easy_tdx/models/stats.py | 13 ++++++++++-- src/easy_tdx/web/routers/market.py | 10 ++++++++-- 7 files changed, 62 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 76419fb..45cb554 100644 --- a/README.md +++ b/README.md @@ -1452,6 +1452,8 @@ with TdxClient.from_best_host() as c: stat = c.get_market_stat() ``` +> **资金流口径注意**(Issue #55):`get_fund_flow` / `get_history_fund_flow` 按 0x0fb5 逐笔接口的"单笔成交额"分档,而该接口返回的记录是交易所真实逐笔**聚合**后的(实测 000001.SZ 单日约 17:1),分档看的也不是挂单额。结果:高价股小单档可不足成交额 1%、主力档常占 95%+,`main_net_inflow` 实质更接近"当日主动买卖总失衡"。东财/同花顺的"主力净流入"基于 L2 逐笔委托、按挂单额分档——两套口径**不可比**(实证同规则选股信号重合度仅约 14%),勿混用于同一张表或同一个因子。 + `AsyncTdxClient` 提供对应的 `async def` 方法,接口一一对应。 ### SecurityQuote 字段说明 @@ -1814,8 +1816,8 @@ with MacClient.from_best_host() as client: | `get_history_minute_time_data(market, code, date)` | 历史分时 | | `get_transaction_data(market, code, ...)` | 当日逐笔成交 | | `get_history_transaction_data(...)` | 历史逐笔成交 | -| `get_fund_flow(market, code)` | 当日资金流向 | -| `get_history_fund_flow(market, code, ...)` | 历史资金流向 | +| `get_fund_flow(market, code)` | 当日资金流向(口径注意见上文) | +| `get_history_fund_flow(market, code, ...)` | 历史资金流向(口径注意见上文) | | `get_xdxr_info(market, code)` | 除权除息历史 | | `get_finance_info(market, code)` | 最新财务数据 | | `get_company_info_category(market, code)` | 公司信息目录 | diff --git a/docs/api_reference.md b/docs/api_reference.md index 412f478..e92c00c 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -333,6 +333,7 @@ c.get_fund_flow(market: Market, code: str) -> pd.DataFrame ``` 获取个股当日资金流向(基于 L1 逐笔数据统计)。返回含 `main_net_inflow`(主力净流入)列。 +口径限制见下方 `get_history_fund_flow` 的"口径注意"(两个接口同,Issue #55)。 **资金分级**: | 级别 | 单笔成交额 | @@ -353,6 +354,14 @@ c.get_history_fund_flow(market: Market, code: str, 无资金流专用指令,Issue #52)。当日 bar 盘中取当日实时逐笔。返回列含 `main_net_inflow`(主力净流入,单位元)。 +**口径注意**(Issue #55,两个接口同):分档基于 0x0fb5 逐笔接口返回的"单笔 +成交额",而该接口的记录是交易所真实逐笔**聚合**后的(实测 000001.SZ 单日 +约 17:1),分档看的也不是挂单额。高价股单笔普遍被聚合推过 100 万/20 万阈值, +小单档可不足成交额 1%、主力档常占 95%+——`main_net_inflow` 实质更接近 +"当日主动买卖总失衡"(另有约 2–4% 方向未定的成交被排除)。东财/同花顺的 +"主力净流入"基于 L2 逐笔委托、按挂单额分档、四档净额严格归零——两套口径 +**不可比**(实证同规则选股信号重合度仅约 14%),勿混用于同一张表或同一个因子。 + --- ## 文件下载 diff --git a/examples/08_fund_flow/fund_flow.py b/examples/08_fund_flow/fund_flow.py index 88a9a1c..407ed27 100644 --- a/examples/08_fund_flow/fund_flow.py +++ b/examples/08_fund_flow/fund_flow.py @@ -27,6 +27,9 @@ DataFrame 列说明: - 金额单位为元(本 demo 转换为亿元便于阅读) - 数据实时计算,非交易时段返回全零值 - 基于 L1 逐笔成交数据统计,非交易所官方资金流向数据 + - 口径注意(Issue #55): 0x0fb5 逐笔为聚合记录、按成交额(非挂单额)分档, + 高价股主力档常占 95%+,"主力净流入"更接近主动买卖总失衡,与东财/ + 同花顺同名指标不可比,勿混用于同一张表或同一个因子 """ import pandas as pd diff --git a/examples/08_fund_flow/history_fund_flow.py b/examples/08_fund_flow/history_fund_flow.py index 32407fa..d352a7c 100644 --- a/examples/08_fund_flow/history_fund_flow.py +++ b/examples/08_fund_flow/history_fund_flow.py @@ -23,6 +23,11 @@ DataFrame 列说明: 中单: 4 ~ 20 万元 小单: <= 4 万元 +口径注意(Issue #55): 分档基于 0x0fb5 逐笔接口的"单笔成交额",而该接口 +返回的是聚合后的记录(实测约 17 笔并 1 笔)、并非挂单额——高价股小单档 +可不足成交额 1%、主力档常占 95%+,main_net_inflow 更接近"主动买卖总 +失衡",与东财/同花顺"主力净流入"不可比,勿混用于同一张表或同一个因子。 + 数据特点: - start 为偏移量,0=最近交易日,count 为请求数量 - 金额单位为元 diff --git a/src/easy_tdx/client.py b/src/easy_tdx/client.py index 1bf7022..bbd36e5 100644 --- a/src/easy_tdx/client.py +++ b/src/easy_tdx/client.py @@ -893,6 +893,14 @@ class TdxClient: """获取个股当日资金流向分布(基于 L1 逐笔数据统计)。 返回列含 ``main_net_inflow``(主力净流入,单位元)。 + + 口径限制(Issue #55):分档基于 0x0fb5 逐笔接口返回的"单笔成交额", + 而该接口的记录是交易所真实逐笔**聚合**后的(实测 000001.SZ 单日 + 约 17:1),且分档看的是成交额、不是挂单额。高价股单笔普遍被聚合 + 推过 100 万/20 万阈值,小单档可不足成交额 1%、主力档常占 95%+—— + ``main_net_inflow`` 实质更接近"当日主动买卖总失衡",与东财/同花顺 + 基于 L2 逐笔委托挂单额的"主力净流入"**不可比**,勿混用于同一张 + 表或同一个因子。 """ records = self._collect_transaction_records( lambda start, page_size: self._execute( @@ -952,6 +960,14 @@ class TdxClient: 此前直接返回空 DataFrame,用户拿不到数据;现复用 K 线故障转移的同源逻辑。 注意:真·无历史数据(如新股)所有服务器都返回空,此时换台仍为空,直接 返回空 DataFrame 而非 raise——避免把"该股票本就没数据"误报为故障。 + + 口径限制(Issue #55):分档基于 0x0fb5 逐笔接口返回的"单笔成交额", + 而该接口的记录是交易所真实逐笔**聚合**后的(实测 000001.SZ 单日 + 约 17:1),且分档看的是成交额、不是挂单额。高价股单笔普遍被聚合 + 推过 100 万/20 万阈值,小单档可不足成交额 1%、主力档常占 95%+—— + ``main_net_inflow`` 实质更接近"当日主动买卖总失衡",与东财/同花顺 + 基于 L2 逐笔委托挂单额的"主力净流入"**不可比**,勿混用于同一张 + 表或同一个因子(实证两口径选股信号重合度仅约 14%)。 """ results = self._fetch_fund_flow_records(market, code, start, count) # 空数据故障转移:与 get_security_bars / get_index_bars 同源逻辑。 @@ -1562,9 +1578,11 @@ class AsyncTdxClient(AsyncHeartbeatMixin): return all_recs async def get_fund_flow(self, market: Market, code: str) -> pd.DataFrame: - """获取个股当日资金流向分布(基于 L1 逐笔数据统计)。 + """获取个股当日资金流向分布(基于 L1 逐笔数据统计,async)。 返回列含 ``main_net_inflow``(主力净流入,单位元)。 + 口径限制同同步版(Issue #55):0x0fb5 逐笔为聚合记录、按成交额而非 + 挂单额分档,值更接近"主动买卖总失衡",与东财/同花顺不可比。 """ records = await self._collect_transaction_records( lambda start, page_size: self._execute( @@ -1614,6 +1632,9 @@ class AsyncTdxClient(AsyncHeartbeatMixin): 实现:"日 K 线取日期 + 逐笔成交重算资金流";当日 bar 盘中走当日实时 逐笔接口。返回列含 ``main_net_inflow``(主力净流入,单位元)。 + 口径限制同同步版(Issue #55):0x0fb5 逐笔为聚合记录、按成交额而非 + 挂单额分档,值更接近"主动买卖总失衡",与东财/同花顺不可比。 + 空数据故障转移(v1.20.5,Issue #41):当前 host 无 K 线数据时, 按延迟顺序逐台实测找首台返回有效数据的服务器。 """ diff --git a/src/easy_tdx/models/stats.py b/src/easy_tdx/models/stats.py index 9dbb9af..c538e14 100644 --- a/src/easy_tdx/models/stats.py +++ b/src/easy_tdx/models/stats.py @@ -21,7 +21,12 @@ class MarketStat: @dataclass class FundFlow: - """个股资金流向统计(基于 Tick 数据加权计算)。""" + """个股资金流向统计(基于逐笔成交重算)。 + + 口径(Issue #55):按 0x0fb5 逐笔接口的"单笔成交额"分档——该接口 + 返回的是聚合记录(非交易所真实逐笔,也非挂单额),故 ``main_net_inflow`` + 更接近"主动买卖总失衡",与东财/同花顺的"主力净流入"不可比。 + """ # 流入项 (Buy) super_in: float # 超大单流入 (>100万) @@ -50,7 +55,11 @@ class FundFlow: @dataclass class HistoricalFundFlow: - """历史日线资金流向条目。""" + """历史日线资金流向条目。 + + 口径同 ``FundFlow``(Issue #55):按聚合后单笔成交额分档,与东财/ + 同花顺"主力净流入"不可比。 + """ year: int month: int diff --git a/src/easy_tdx/web/routers/market.py b/src/easy_tdx/web/routers/market.py index ef16663..1ec8572 100644 --- a/src/easy_tdx/web/routers/market.py +++ b/src/easy_tdx/web/routers/market.py @@ -82,7 +82,10 @@ async def fund_flow( code: str = Query(..., min_length=6, max_length=6, description="6位股票代码"), client: Any = Depends(get_client), ) -> DataFrameResponse: - """获取个股当日资金流向。""" + """获取个股当日资金流向。 + + 口径注意:按聚合后单笔成交额分档,与东财/同花顺"主力净流入"不可比(Issue #55)。 + """ df = await client.get_fund_flow(market_from_str(market), code) return _df_response(df) @@ -95,7 +98,10 @@ async def history_fund_flow( count: int = Query(100, ge=1, le=800), client: Any = Depends(get_client), ) -> DataFrameResponse: - """获取个股历史日线资金流向。""" + """获取个股历史日线资金流向。 + + 口径注意:按聚合后单笔成交额分档,与东财/同花顺"主力净流入"不可比(Issue #55)。 + """ df = await client.get_history_fund_flow(market_from_str(market), code, start, count) return _df_response(df)