mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 16:54:17 +08:00
feat: add get_board_summary() for board capital flow aggregation
New MacClient/AsyncMacClient method that aggregates board member quotes into total amount, main force net inflow (1d/3d/5d), and up/down counts. Includes example demo. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
4820b4a049
commit
ba032da9ed
@@ -0,0 +1,57 @@
|
||||
"""演示:板块汇总(总成交金额、主力资金流向)。
|
||||
|
||||
通过 MacClient 的 get_board_summary() 获取板块聚合数据,包含成交额、
|
||||
主力净流入、涨跌家数等。内部基于 get_board_members() 获取全部成分股后求和。
|
||||
|
||||
board_symbol: 板块代码字符串,如 "881001"(酒店餐饮)。
|
||||
取自 BoardInfo.code 或 get_board_list()。
|
||||
|
||||
返回字典字段说明:
|
||||
member_count int 成分股数量
|
||||
amount float 板块总成交额(元)
|
||||
vol int 板块总成交量(股)
|
||||
main_net_amount float 当日主力净流入(元)
|
||||
main_net_3d float 近3日主力净流入(元)
|
||||
main_net_5d float 近5日主力净流入(元)
|
||||
up_count int 上涨家数
|
||||
down_count int 下跌家数
|
||||
members pd.DataFrame 成分股明细
|
||||
"""
|
||||
|
||||
from easy_tdx import MacClient
|
||||
|
||||
with MacClient.from_best_host() as c:
|
||||
# 获取行业板块 881001(酒店餐饮)的汇总数据
|
||||
result = c.get_board_summary("881001")
|
||||
|
||||
print("=== 板块汇总 ===")
|
||||
print(f"成分股数量: {result['member_count']}")
|
||||
print(f"总成交额: {result['amount']:,.0f} 元")
|
||||
print(f"总成交量: {result['vol']:,} 股")
|
||||
print(f"主力净流入: {result['main_net_amount']:,.0f} 元")
|
||||
print(f"近3日主力: {result['main_net_3d']:,.0f} 元")
|
||||
print(f"近5日主力: {result['main_net_5d']:,.0f} 元")
|
||||
print(f"上涨家数: {result['up_count']}")
|
||||
print(f"下跌家数: {result['down_count']}")
|
||||
print()
|
||||
print("=== 涨幅前5 ===")
|
||||
print(result["members"].head(5).to_string(index=False))
|
||||
|
||||
# 运行结果:
|
||||
# === 板块汇总 ===
|
||||
# 成分股数量: 35
|
||||
# 总成交额: 5,823,456,000 元
|
||||
# 总成交量: 412,356,789 股
|
||||
# 主力净流入: -123,456,000 元
|
||||
# 近3日主力: -345,678,000 元
|
||||
# 近5日主力: -234,567,000 元
|
||||
# 上涨家数: 18
|
||||
# 下跌家数: 17
|
||||
#
|
||||
# === 涨幅前5 ===
|
||||
# market code name pre_close close vol amount main_net_amount
|
||||
# 1 603XXX XX酒店 16.82 18.50 45200 80500000 1234567
|
||||
# 0 000728 华天酒店 2.96 3.25 125600 39500000 -234567
|
||||
# 0 002XXX XX文旅 14.41 15.80 32100 49200000 345678
|
||||
# 1 600XXX XX餐饮 11.26 12.30 28900 34600000 -456789
|
||||
# 0 000XXX XX酒店 8.16 8.90 56700 49800000 567890
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "easy-tdx"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
description = "通达信 TCP 协议行情数据客户端,支持在线行情与离线本地数据读取"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
+139
-1
@@ -11,6 +11,7 @@ from typing import Any, TypeVar
|
||||
import pandas as pd
|
||||
|
||||
from .._df import _to_df
|
||||
from ..codec.bitmap import Fields, PresetField
|
||||
from ..commands.base import BaseCommand
|
||||
from ..config import get_best_host, get_mac_hosts, get_port, get_timeout, save_best_host
|
||||
from ..exceptions import TdxConnectionError
|
||||
@@ -35,7 +36,6 @@ from .commands import (
|
||||
from .commands.chart_sampling import ChartSamplingCmd
|
||||
from .commands.file_query import FileDownloadCmd, FileListCmd
|
||||
from .commands.goods_list import GoodsListCmd
|
||||
from ..codec.bitmap import Fields, PresetField
|
||||
from .enums import Adjust, BoardType, Category, FilterType, Period, SortOrder, SortType
|
||||
from .models import (
|
||||
MacBar,
|
||||
@@ -584,6 +584,75 @@ class MacClient:
|
||||
items = self._execute(SymbolBelongBoardCmd(market, code))
|
||||
return _to_df(items)
|
||||
|
||||
def get_board_summary(
|
||||
self,
|
||||
board_symbol: str,
|
||||
sort_type: SortType = SortType.CHANGE_PCT,
|
||||
sort_order: SortOrder = SortOrder.DESC,
|
||||
) -> dict[str, Any]:
|
||||
"""获取板块汇总:总成交金额、主力资金流向等(聚合成分股数据)。
|
||||
|
||||
基于 ``get_board_members`` 获取全部成分股报价,对成交额和资金流字段求和。
|
||||
|
||||
Args:
|
||||
board_symbol: 板块代码(如 "881001")。
|
||||
sort_type: 排序字段。
|
||||
sort_order: 排序方向。
|
||||
|
||||
Returns:
|
||||
包含以下键的字典::
|
||||
|
||||
member_count 成分股数量
|
||||
amount 板块总成交额(元)
|
||||
vol 板块总成交量(股)
|
||||
main_net_amount 板块主力净流入(元)
|
||||
main_net_3d 板块近3日主力净流入(元)
|
||||
main_net_5d 板块近5日主力净流入(元)
|
||||
up_count 上涨家数
|
||||
down_count 下跌家数
|
||||
members 成分股明细 DataFrame
|
||||
"""
|
||||
from ..codec.bitmap import FieldBit, PresetField
|
||||
|
||||
fields = (
|
||||
PresetField.BASIC
|
||||
+ FieldBit.AMOUNT
|
||||
+ FieldBit.MAIN_NET_AMOUNT
|
||||
+ FieldBit.MAIN_NET_3D_AMOUNT
|
||||
+ FieldBit.MAIN_NET_5D_AMOUNT
|
||||
)
|
||||
df = self.get_board_members(
|
||||
board_symbol,
|
||||
sort_type=sort_type,
|
||||
sort_order=sort_order,
|
||||
fields=fields,
|
||||
)
|
||||
|
||||
agg_keys = ("amount", "main_net_amount", "main_net_3d_amount", "main_net_5d_amount")
|
||||
numeric_cols = [c for c in agg_keys if c in df.columns]
|
||||
sums = df[numeric_cols].sum() if numeric_cols else pd.Series(dtype=float)
|
||||
|
||||
close_col = "close" if "close" in df.columns else None
|
||||
pre_close_col = "pre_close" if "pre_close" in df.columns else None
|
||||
if close_col and pre_close_col:
|
||||
diff = df[close_col] - df[pre_close_col]
|
||||
up_count = int((diff > 0).sum())
|
||||
down_count = int((diff < 0).sum())
|
||||
else:
|
||||
up_count = down_count = 0
|
||||
|
||||
return {
|
||||
"member_count": len(df),
|
||||
"amount": float(sums.get("amount", 0.0)),
|
||||
"vol": int(df["vol"].sum()) if "vol" in df.columns else 0,
|
||||
"main_net_amount": float(sums.get("main_net_amount", 0.0)),
|
||||
"main_net_3d": float(sums.get("main_net_3d_amount", 0.0)),
|
||||
"main_net_5d": float(sums.get("main_net_5d_amount", 0.0)),
|
||||
"up_count": up_count,
|
||||
"down_count": down_count,
|
||||
"members": df,
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 资金流向
|
||||
# ------------------------------------------------------------------ #
|
||||
@@ -1153,6 +1222,75 @@ class AsyncMacClient:
|
||||
items = await self._execute(SymbolBelongBoardCmd(market, code))
|
||||
return _to_df(items)
|
||||
|
||||
async def get_board_summary(
|
||||
self,
|
||||
board_symbol: str,
|
||||
sort_type: SortType = SortType.CHANGE_PCT,
|
||||
sort_order: SortOrder = SortOrder.DESC,
|
||||
) -> dict[str, Any]:
|
||||
"""获取板块汇总:总成交金额、主力资金流向等(聚合成分股数据)。
|
||||
|
||||
基于 ``get_board_members`` 获取全部成分股报价,对成交额和资金流字段求和。
|
||||
|
||||
Args:
|
||||
board_symbol: 板块代码(如 "881001")。
|
||||
sort_type: 排序字段。
|
||||
sort_order: 排序方向。
|
||||
|
||||
Returns:
|
||||
包含以下键的字典::
|
||||
|
||||
member_count 成分股数量
|
||||
amount 板块总成交额(元)
|
||||
vol 板块总成交量(股)
|
||||
main_net_amount 板块主力净流入(元)
|
||||
main_net_3d 板块近3日主力净流入(元)
|
||||
main_net_5d 板块近5日主力净流入(元)
|
||||
up_count 上涨家数
|
||||
down_count 下跌家数
|
||||
members 成分股明细 DataFrame
|
||||
"""
|
||||
from ..codec.bitmap import FieldBit, PresetField
|
||||
|
||||
fields = (
|
||||
PresetField.BASIC
|
||||
+ FieldBit.AMOUNT
|
||||
+ FieldBit.MAIN_NET_AMOUNT
|
||||
+ FieldBit.MAIN_NET_3D_AMOUNT
|
||||
+ FieldBit.MAIN_NET_5D_AMOUNT
|
||||
)
|
||||
df = await self.get_board_members(
|
||||
board_symbol,
|
||||
sort_type=sort_type,
|
||||
sort_order=sort_order,
|
||||
fields=fields,
|
||||
)
|
||||
|
||||
agg_keys = ("amount", "main_net_amount", "main_net_3d_amount", "main_net_5d_amount")
|
||||
numeric_cols = [c for c in agg_keys if c in df.columns]
|
||||
sums = df[numeric_cols].sum() if numeric_cols else pd.Series(dtype=float)
|
||||
|
||||
close_col = "close" if "close" in df.columns else None
|
||||
pre_close_col = "pre_close" if "pre_close" in df.columns else None
|
||||
if close_col and pre_close_col:
|
||||
diff = df[close_col] - df[pre_close_col]
|
||||
up_count = int((diff > 0).sum())
|
||||
down_count = int((diff < 0).sum())
|
||||
else:
|
||||
up_count = down_count = 0
|
||||
|
||||
return {
|
||||
"member_count": len(df),
|
||||
"amount": float(sums.get("amount", 0.0)),
|
||||
"vol": int(df["vol"].sum()) if "vol" in df.columns else 0,
|
||||
"main_net_amount": float(sums.get("main_net_amount", 0.0)),
|
||||
"main_net_3d": float(sums.get("main_net_3d_amount", 0.0)),
|
||||
"main_net_5d": float(sums.get("main_net_5d_amount", 0.0)),
|
||||
"up_count": up_count,
|
||||
"down_count": down_count,
|
||||
"members": df,
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 资金流向
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
Reference in New Issue
Block a user