## 行业概念板块（Sector / Concept Boards）

工具：`get_sector_info`（`src.tools.sector_tool.SectorInfoTool`）
描述：东财免费免鉴权板块分类，把 A 股归入行业板块（行业板块）与主题概念板块（概念板块）。两种只读视图：
- **membership** —— 给定个股 `code`，列出它所属的行业/概念板块（push2 `slist` 端点，按 secid 寻址）。
- **ranking** —— `mode="ranking"`，把行业板块本身按盘中涨跌幅排名（push2 `clist` 端点，行业板块全集 `fs=m:90+t:2`）。
市场：membership 覆盖 A 股（.SH / .SZ / .BJ）；ranking 为 A 股板块全集。
限速：经共享 `eastmoney` per-host 节流层；东财按源 IP 限流。

<br>

**端点**

| 模式 | 端点 URL |
| ---- | -------- |
| membership | `https://push2.eastmoney.com/api/qt/slist/get` |
| ranking | `https://push2.eastmoney.com/api/qt/clist/get` |

字段选择器：f12=板块/证券代码，f14=名称，f3=涨跌幅，f2=最新价/指数，f104/f105=上涨/下跌成分数（ranking），f140=领涨股（ranking）。

<br>

**输入参数（工具入参）**

名称 | 类型 | 必选 | 描述
---- | ---- | ---- | ----
mode | str | N | `"membership"`（默认，列个股所属板块，需 `code`）或 `"ranking"`（行业板块按当日涨幅排名，忽略 `code`）。
code | str | membership 必选 | A 股 symbol 带后缀，如 `600519.SH` / `000001.SZ` / `430139.BJ`。
limit | int | N | ranking 时返回 top 板块数（1–100，默认 30）；membership 忽略。

<br>

**端点查询参数**

membership（slist）：`secid=<secid>`、`spt=3`、`pi=0`、`pz=100`、`fields=f12,f13,f14,f3,f2`、`fltt=2`、`po=1`。
ranking（clist）：`fs=m:90+t:2`、`fields=f12,f14,f3,f2,f104,f105,f128,f140`、`pn=1`、`pz=<limit>`、`po=1`、`fid=f3`、`fltt=2`。

<br>

**返回字段**

membership（每行一个板块）：

字段 | 类型 | 描述
---- | ---- | ----
board_code | str | 板块代码（f12）
board_name | str | 板块名称（f14）
change_pct | float | 涨跌幅（f3）
price | float | 最新价（f2）

ranking（每行一个行业板块）：

字段 | 类型 | 描述
---- | ---- | ----
board_code / board_name | str | 板块代码 / 名称
change_pct | float | 涨跌幅（f3）
index | float | 板块指数（f2）
up_count / down_count | float | 上涨 / 下跌成分数（f104 / f105）
leader | str | 领涨股（f140；`-` → None）

信封：`{"ok": true, "market": "stock", "source": "eastmoney", "mode": <mode>, "data": {...}}`。`-`/空映射为 None。

<br>

**调用范例**

```python
from src.tools.sector_tool import SectorInfoTool

print(SectorInfoTool().execute(code="600519.SH"))             # membership
print(SectorInfoTool().execute(mode="ranking", limit=20))     # 行业板块涨幅榜
```
