Metadata-Version: 2.4
Name: pywestockdata
Version: 0.1.0
Summary: Python SDK & CLI for Tencent Finance public APIs (A股/港股/美股)
Requires-Python: >=3.10
Requires-Dist: click>=8.0
Requires-Dist: primp>=0.10
Requires-Dist: rich>=13.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# pywestockdata

Python SDK & CLI for Tencent / East Money public finance APIs.

A 股（含北交所）实时行情、K 线、分时、搜索、财务、资金流、股东、分红、融资融券等数据一站获取。港股 / 美股仅行情与搜索类接口支持（详见下文「代码规则」）。

---

## 安装

```bash
# 可编辑安装（含 CLI 命令 westock）
pip install -e .

# 开发模式（含测试依赖）
pip install -e ".[dev]"
```

安装后即可直接使用 CLI：

```bash
westock quote sh600000 sz000001
```

---

## 性能

> 以下为设计目标 / 参考量级，实际耗时取决于网络环境与并发数，请以本地实测为准。

| 功能 | 并发策略 | 目标耗时 |
|------|---------|---------|
| 全量行情（沪 + 深 + 北，约 5000+ 股） | 4 workers, 100 codes/batch | <500ms |
| 分时 K 线 | 4 workers | <500ms |
| 日 / 周 / 月 / 分钟 K 线、财务、搜索 | 单次请求 | <200ms |

---

## Python API

所有函数均为**同步**实现，返回 `dict` / `list[dict]` / `list[list]`，不抛网络异常（失败返回 `[]` 或 `{}` 并记录 `warning` 日志）。

```python
import pywestockdata as ws

# —— 实时行情 ——
quotes = ws.fetch_quotes_batch(["sh600000", "sz000001"], workers=4)
quotes = ws.fetch_quotes_batch(ws.fetch_all_stock_codes())   # 全市场

# —— K 线（day/week/month/5min/15min/30min/60min）——
day_bars = ws.fetch_kline("sh600000", period="day", count=30, adjust="qfq")
min_bars = ws.fetch_kline("sh600000", period="5min", count=48)   # 返回 [[date, open, close, high, low, volume], ...]

# —— 分时 ——
minute = ws.fetch_minute_data("sh600519")          # {"summary": {...}, "data": [...]}
raw = ws.fetch_minute_batch(["sh600000", "sz000001"])  # {code: 原始文本}

# —— 搜索 / 热门 ——
results = ws.search_stock("中国平安")     # [{'code': 'sh601318', 'name': '中国平安', 'market': 'sh'}, ...]
hot = ws.fetch_hot_search()

# —— 资金流 / 板块 ——
flow = ws.fetch_fund_flow("sh600519")
boards = ws.fetch_board_list()
board_stocks = ws.fetch_board_stocks("BK0493", limit=20)

# —— 公司基本面（A 股）——
profile = ws.fetch_profile("sh600519")
finance = ws.fetch_finance("sh600519")      # {"income": [...], "balance": [...], "cashflow": [...]}
holders = ws.fetch_shareholder("sh600519")
dividends = ws.fetch_dividend("sh600519")

# —— 交易类（A 股）——
blocks = ws.fetch_block_trades("sh600519", limit=10)
margin = ws.fetch_margin("sh600519")
buyback = ws.fetch_buyback("sh600519", limit=10)
suspended = ws.fetch_suspensions()

# —— 全市场列表 ——
all_codes = ws.fetch_all_stock_codes()            # 沪 + 深 + 北
all_codes_sh = ws.fetch_all_stock_codes("sh")     # 指定市场: sh / sz / bj / all
all_info = ws.fetch_all_stock_info()              # 含基础字段
```

### 函数一览

| 函数 | 说明 | 支持市场 |
|------|------|---------|
| `fetch_quotes_batch(codes, workers=4)` | 批量实时行情（含五档盘口 `bid1_price`/`bid1_volume`...`ask5_price`/`ask5_volume`） | 沪 / 深 / 北 / 港 / 美 |
| `fetch_kline(code, period, count, adjust)` | 日 / 周 / 月 / 分钟 K 线 | 行情接口全部；分钟仅 A 股 |
| `fetch_minute_batch(codes, workers)` | 批量分时原始数据 | A 股 |
| `fetch_minute_data(code)` | 单股分时（已解析） | A 股 |
| `search_stock(keyword)` | 股票搜索 | 全部 |
| `fetch_hot_search()` | 热门股票榜 | A 股 |
| `fetch_fund_flow(code)` | 资金流向 | A 股 |
| `fetch_board_list()` | 行业板块列表 | A 股 |
| `fetch_board_stocks(board_code, limit)` | 板块成分股 | A 股 |
| `fetch_finance(code)` | 利润表 / 资产负债表 / 现金流量表 | A 股 |
| `fetch_profile(code)` | 公司概况（市值 / PE / PB 等） | A 股 |
| `fetch_shareholder(code)` | 十大股东 | A 股 |
| `fetch_dividend(code)` | 分红历史 | A 股 |
| `fetch_block_trades(code, limit)` | 大宗交易 | A 股 |
| `fetch_margin(code)` | 融资融券 | A 股 |
| `fetch_buyback(code, limit)` | 回购（† 暂不可用） | A 股 |
| `fetch_suspensions()` | 停牌列表（† 暂不可用） | A 股 |
| `fetch_all_stock_codes(market)` | 全市场代码列表 | 沪 / 深 / 北 |
| `fetch_all_stock_info()` | 全市场基础信息 | 沪 / 深（East Money） |

> † 回购 / 停牌因东方财富上游「特色数据」接口报表名变更暂不可用，见下「已知问题」。

> 港 / 美股代码虽可被 `_normalize_code` 识别，但财务、资金流、股东、分红、融资融券等基于东方财富的接口**仅支持沪深 A 股**，传入其余市场会返回空结果并记录警告日志。

---

## CLI 命令

共 22 个命令，所有命令均支持 `--json` 输出 JSON。

```bash
# ── 实时行情 ──
westock quote sh600000 sz000001 sh600519          # 多代码实时行情
westock quote-all                                 # 全量行情（沪+深+北）
westock quote-all -w 5                            # 指定并发线程数

# ── K 线 / 分时 ──
westock kline sh600000 -f day -c 30               # 日 K 线（-f: day/week/month/5/15/30/60）
westock kline sh600000 -f 5                       # 5 分钟 K 线
westock kline sh600000 -a hfq                     # 后复权（默认 qfq 前复权）
westock minute sh600000                           # 当日分时
westock intraday sh600000                         # minute 的别名

# ── 搜索 / 热门 ──
westock search 贵州茅台                           # 股票搜索
westock hot                                       # 热门股票榜

# ── 资金流 / 板块 ──
westock fund-flow sh600519                        # 资金流向
westock money-flow sh600519                       # fund-flow 的别名
westock board                                     # 行业板块列表
westock board-stocks BK0493 -l 30                 # 板块成分股（-l/--limit 数量）

# ── 公司基本面（A 股）──
westock finance sh600519                          # 三大财务报表
westock profile sh600519                          # 公司概况
westock shareholder sh600519                      # 十大股东
westock dividend sh600519                         # 分红历史
westock exdiv sh600519                            # dividend 的别名

# ── 交易类（A 股）──
westock block-trade sh600519                      # 大宗交易（-l/--limit 数量）
westock block-trade                               # 全市场大宗交易
westock margin sh600519                           # 融资融券（-l 数量）
westock buyback sh600519                          # 回购（-l 数量）
westock buyback                                   # 全市场回购

# ── 其他 ──
westock suspension                                # 停牌列表
westock reserve sh600519                          # 最早财报披露日期
westock market-overview                           # 主要指数概览（上证/深成/创业板/沪深300等）
```

### 命令速查表

| 命令 | 参数 | 关键选项 |
|------|------|---------|
| `quote` | `CODES...` | `--json` |
| `quote-all` | — | `-w/--workers`, `--json` |
| `kline` | `CODE` | `-f/--freq`, `-c/--count`, `-a/--adjust`, `--json` |
| `minute` / `intraday` | `CODE` | `--json` |
| `search` | `KEYWORD` | `--json` |
| `hot` | — | `--json` |
| `fund-flow` / `money-flow` | `CODE` | `--json` |
| `board` | — | `-l/--limit`, `--json` |
| `board-stocks` | `BOARD_CODE` | `-l/--limit`, `--json` |
| `finance` | `CODE` | `--json` |
| `profile` | `CODE` | `--json` |
| `shareholder` | `CODE` | `--json` |
| `dividend` / `exdiv` | `CODE` | `--json` |
| `block-trade` | `[CODE]` | `-l/--limit`, `--json` |
| `margin` | `CODE` | `-l/--limit`, `--json` |
| `buyback` | `[CODE]` | `-l/--limit`, `--json` |
| `suspension` | — | `--json` |
| `reserve` | `CODE` | `--json` |
| `market-overview` | — | `--json` |

---

## 代码规则

- 上海: `sh600000` (6 开头)
- 深圳: `sz000001` (0/3 开头)
- 北京: `bj830799` (8 开头)
- 港股: `hk00700`（仅行情 / 搜索类接口）
- 美股: `usAAPL`（仅行情 / 搜索类接口）

> 实时行情、K 线、搜索基于腾讯公开接口；财务 / 资金流 / 股东 / 分红 / 融资融券等基于东方财富，仅支持沪深 A 股，对港股 / 美股 / 北交所会返回空结果。

---

## 数据源

| 数据类别 | 接口 |
|---------|------|
| 实时行情 | Tencent `qt.gtimg.cn` |
| 日 / 周 / 月 K 线 | Tencent `proxy.finance.qq.com` |
| 分钟 K 线 | Tencent `web.ifzq.gtimg.cn/appstock/app/kline/mkline` |
| 分时数据 | Tencent `web.ifzq.gtimg.cn/appstock/app/minute/query` |
| 搜索 | Tencent `smartbox.gtimg.cn` |
| 热门 / 资金流 / 板块 / 全量列表 | East Money `push2.eastmoney.com` |
| 财务 / 股东 / 分红 / 大宗 / 融资融券 | East Money `datacenter-web.eastmoney.com` |
| 回购 / 停牌 | ⚠️ 暂不可用（东财「特色数据」报表名已变更，待修复，见下） |
| 公司概况 | East Money `push2.eastmoney.com/api/qt/stock/get` |

所有接口均为公开 HTTP GET，无需鉴权。

> **已知问题（已核对，暂搁置）**
> - `fetch_buyback` / `westock buyback`（股票回购）与 `fetch_suspensions` / `westock suspension`（停牌）：所依赖的东方财富「特色数据」`datacenter-web` 报表名（`RPT_SHARE_BUYBACK_DET`、`RPT_DATA_SUSPENSION` 等）现已返回 `9501 报表配置不存在`（经实测核对，财务类报表 `RPT_DMSK_FN_*` 仍正常）。这两个命令已保留兜底（返回空或提示），不会崩溃，待后续定位到有效接口后修复。
> - 实时行情 `amount`（成交额）腾讯原始单位为**万元**，已 `×1e4`；`total_market_cap` / `circ_market_cap` 原始单位为**亿元**，已 `×1e8`。`pe_ratio`、`turnover_rate`、`change_pct` 等字段为原始数值，无需换算。

---

## 开发

```bash
# 运行测试（已 mock 网络请求，无需联网）
pytest tests/ -q

# 代码规范
ruff check src tests
```

项目结构：

```
pywestockdata/
├── src/pywestockdata/
│   ├── api.py      # 全部数据获取函数（同步）
│   ├── cli.py      # click 命令行（22 个命令）
│   └── __init__.py # 公共导出
├── tests/          # pytest 测试（mock 网络层）
└── scripts/
```

---

## License

MIT
