Files
EMWebApi/docs/api_manual.md
T
toor 2ce68b7b5d 新增公司资料/指数/重大事项等 13 个接口, 文档全面对齐
- 新增 fin_mda/fin_equity/fin_company/fin_belong_index/fin_major_events 5 个模块
- 覆盖: 管理层讨论、股本结构、公司介绍、所属行业、指数分类/统计/成分、并购/股权激励/诉讼/关联交易/违规/担保
- _emchoice.fetch_report 支持"数据为空"按空结果处理
- api.py 增加 _simple_endpoint 统一生成纯 stocks 参数接口, 路由达 29 个 /fin 端点
- 冒烟测试扩展至 56 用例, 全部通过
- api_manual/blueprint/SKILLS/待优化 文档与代码路径 100% 对齐
2026-08-15 11:34:11 +08:00

432 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EMWeb API 接口文档
> 东方财富 CHOICE 数据抓取服务 HTTP 接口使用说明。对应目前已实现的功能,随版本更新。
## 基本信息
| 项 | 值 |
|---|---|
| 服务名称 | EMWeb API |
| 版本 | 0.1.0 |
| 默认地址 | `http://127.0.0.1:8765` |
| 数据源 | 东方财富 CHOICE 公开接口(无需登录/cookie) |
| Swagger | `http://127.0.0.1:8765/docs` |
启动:
```bash
uv run python api.py # 监听 0.0.0.0:8765
```
## 通用说明
### 返回结构
所有 `/fin/*` 接口成功时返回统一结构:
```json
{
"success": true,
"count": 10,
"columns": ["SECUCODE", "REPORT_DATE", "..."],
"data": [ { "SECUCODE": "603233.SH", "..." }, "..." ],
"codes_requested": ["603233.SH"],
"years": 3
}
```
| 字段 | 说明 |
|---|---|
| `success` | 是否成功 |
| `count` | 数据行数 |
| `columns` | 数据列名(与上游接口返回一致,不做翻译) |
| `data` | 数据行数组;空值/NaN/NaT/±inf 统一转 `null` |
| 其余字段 | 回显本次请求参数,便于排查 |
### 错误
| HTTP 状态 | 场景 |
|---|---|
| `400` | 参数不合法(如 `stocks` 为空) |
| `404` | 请求成功但无数据(`success: false`,`data: []`) |
| `5xx` | 上游接口异常(超时、返回失败等) |
### 股票代码格式
统一使用 `代码.市场`,如 `603233.SH`(上交所)/ `000001.SZ`(深交所)。多只股票用英文逗号分隔。
---
## 1. GET /health — 健康检查
**参数**:无
**响应**:
```json
{ "status": "ok" }
```
---
## 2. GET /fin/summary — 财务摘要(报告期)
拉取多只股票的财务摘要指标(报告期口径,单季度数据请用 `/fin/quarterly-summary`)。
**参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票列表。两种写法:① 仅代码 `603233.SH`(自动查 ORG_CODE,不稳定);② `代码:ORG_CODE`,如 `603233.SH:10500736`(推荐,最稳) |
| `years` | int | | `10` | 拉取多少年历史(1~20) |
| `date_type_codes` | string | | `1,5,6` | 报告期代码,逗号分隔:`1`=一季报,`5`=中报,`6`=年报 |
| `is_newest` | bool | | `true` | 是否只要最新合并报表 |
**示例**
```bash
curl "http://127.0.0.1:8765/fin/summary?stocks=603233.SH:10500736&years=5&date_type_codes=1,5,6"
```
**说明**
- ORG_CODE 无法从公开接口稳定自动获取,推荐在抓包时记录(如大参林 `603233.SH` → `10500736`)。
- 只传代码时自动查询失败会返回 `400` 并提示改用 `代码:ORG_CODE` 格式。
---
## 3. GET /fin/quarterly-summary — 财务摘要(单季度)
拉取多只股票的季度财务摘要,数据按 `SECUCODE + REPORT_DATE` 去重并倒序排列。
**参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH,600519.SH`。仅需代码,不需要 ORG_CODE |
| `years` | int | | `3` | 未传 `report_dates` 时,拉取最近多少年的季度数据(1~20) |
| `report_dates` | string | | 无 | 可选,逗号分隔的报告期 `YYYY-MM-DD`,如 `2025-03-31,2024-12-31`;传入时精确筛选 |
**示例**
```bash
# 最近 3 年全部季度
curl "http://127.0.0.1:8765/fin/quarterly-summary?stocks=603233.SH&years=3"
# 精确指定报告期
curl "http://127.0.0.1:8765/fin/quarterly-summary?stocks=603233.SH&report_dates=2025-03-31,2024-12-31"
```
---
## 4. GET /fin/main-business — 主营构成(按产品 / 按地区)
拉取多只股票的主营构成,可分别按产品分类或按地区分类。
**参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
| `classify_type` | string | | `产品` | 分类方式:`产品` 或 `地区` |
| `years` | int | | `3` | 拉取最近多少年数据(1~20) |
**示例**
```bash
# 按产品分类(中文参数建议 URL 编码:产品=%E4%BA%A7%E5%93%81)
curl "http://127.0.0.1:8765/fin/main-business?stocks=603233.SH&classify_type=%E4%BA%A7%E5%93%81&years=3"
# 按地区分类(地区=%E5%9C%B0%E5%8C%BA)
curl "http://127.0.0.1:8765/fin/main-business?stocks=603233.SH&classify_type=%E5%9C%B0%E5%8C%BA&years=3"
```
**返回数据常见列**
| 列名 | 说明 |
|---|---|
| `SECUCODE` | 股票代码 |
| `CLASSIFY_TYPE` | 分类方式(产品/地区) |
| `STD_REPORT_NAME` | 分类名(如产品名/地区名,含"合计"行) |
| `ReportDate` | 报告期(`YYYY-MM-DD HH:MM:SS`) |
| `MAIN_BUSINESS_INCOME` | 主营业务收入 |
| `MAIN_BUSINESS_COST` | 主营业务成本 |
| `MAIN_BUSINESS_RPOFIT` | 主营业务利润 |
| `GROSS_RPOFIT_RATIO` | 毛利率(%) |
| `MBI_RATIO` | 占主营业务收入比(%) |
| `MBR_RATIO` | 占主营业务利润比(%) |
| `IS_MAXREPORTDATE` | 是否最新报告期(`1`=是) |
---
## 5. 财务报表(资产负债表 / 利润表 / 现金流量表)
**公共参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
| `years` | int | | `3` | 拉取最近多少年的数据(1~20) |
**示例**
```bash
# 资产负债表
curl "http://127.0.0.1:8765/fin/balance?stocks=603233.SH&years=3"
# 利润表
curl "http://127.0.0.1:8765/fin/income?stocks=603233.SH&years=3"
# 现金流量表
curl "http://127.0.0.1:8765/fin/cashflow?stocks=603233.SH&years=3"
```
**说明**:数据为按报告期的明细科目,列数较多(资产负债表约 160+ 列,利润表约 80+ 列,现金流量表约 140 列),列名与上游接口一致(如 `TOTAL_ASSETS`、`TOTAL_OPERATE_INCOME`、`SALES_SERVICES`)。
---
## 6. 财务分析指标(盈利能力 / 资本结构 / 营运能力 / 成长能力 / 杜邦)
**公共参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
| `years` | int | | `3` | 拉取最近多少年的数据(1~20) |
**示例**
```bash
# 盈利能力与收益质量 (ROE/ROA/毛利率等)
curl "http://127.0.0.1:8765/fin/profitability?stocks=603233.SH&years=3"
# 资本结构与偿债能力 (资产负债率/流动比率等)
curl "http://127.0.0.1:8765/fin/capital-structure?stocks=603233.SH&years=3"
# 营运能力 (周转天数/周转率等)
curl "http://127.0.0.1:8765/fin/operate-ability?stocks=603233.SH&years=3"
# 成长能力 (营收/净利同比等)
curl "http://127.0.0.1:8765/fin/growth?stocks=603233.SH&years=3"
# 杜邦分析 (ROE 拆解)
curl "http://127.0.0.1:8765/fin/dupont?stocks=603233.SH&years=3"
```
**各接口常见列**
| 接口 | 常见列 |
|---|---|
| 盈利能力 | `ROE_AVERAGE`(平均净资产收益率)、`ROE_DILUTED`(摊薄)、`ROA`、`ROIC`、`SALE_GPR`(毛利率)等 |
| 资本结构 | `DEBT_ASSET_RATIO`(资产负债率)、`CURRENT_RATIO`(流动比率)、`SPEED_RATIO`(速动比率)等 |
| 营运能力 | `OPERATE_CYCLE`(营业周期)、`INVENTORY_DAYS`(存货周转天数)、`ACCOUNTS_RECE_DAYS` 等 |
| 成长能力 | `BASICEPS_YOY`、`TOTAL_OPERATEINCOME_YOY`(营收同比)、`PARENT_NETPROFIT_YOY`(净利同比)等 |
| 杜邦 | `ROE`、`NETPROFIT`、`TOTAL_ASSETS`、`EQUITY_MULTIPLIER`(权益乘数)、`NETPROFIT_TOI` 等 |
---
## 7. 分红(明细 / 统计)
**公共参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
| `years` | int | | `5` | 拉取最近多少年的分红数据(1~20) |
**示例**
```bash
# 分红明细 (含方案/股权登记日/除权除息日等)
curl "http://127.0.0.1:8765/fin/dividend-detail?stocks=603233.SH&years=5"
# 分红统计 (按年汇总, 含股息率/分红率等)
curl "http://127.0.0.1:8765/fin/dividend-statics?stocks=603233.SH&years=5"
```
**各接口常见列**
| 接口 | 常见列 |
|---|---|
| 分红明细 | `IMPL_PLAN_PROFILE`(方案)、`ASSIGN_PROGRESS`(进度)、`PRETAX_BONUS_RMB`(每股税前)、`EX_DIVIDEND_DATE`(除权除息日)、`PAY_CASH_DATE` 等 |
| 分红统计 | `AUALACCMDIV_ARD`(每股股利)、`PARENTNETPROFIT`、`GXL`(股息率)、`SUM_AUALACCMDIV_ARD` 等 |
---
## 8. 股东数据(十大流通股东 / 十大股东明细 / 股东户数)
**公共参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
| `years` | int | | `3` | 拉取最近多少年的数据(1~20) |
**示例**
```bash
# 十大流通股东
curl "http://127.0.0.1:8765/fin/free-holders?stocks=603233.SH&years=3"
# 十大股东明细
curl "http://127.0.0.1:8765/fin/holders?stocks=603233.SH&years=3"
# 股东户数
curl "http://127.0.0.1:8765/fin/holder-num?stocks=603233.SH&years=3"
```
**各接口常见列**
| 接口 | 常见列 |
|---|---|
| 十大流通股东 | `HOLDER_NAME`(股东名)、`HOLD_NUM`(持股数)、`HOLD_RATIO`、`FREE_HOLDNUM_RATIO`(占流通股比)、`HOLD_CHANGE` 等 |
| 十大股东明细 | `RANK`(排名)、`HOLDER_NAME`、`HOLD_NUM`、`HOLD_RATIO`、`DIRECTION`(增减持方向)、`NOTICE_DATE` 等 |
| 股东户数 | `HOLDER_TOTAL_NUM`(股东总数)、`HOLDER_TOTAL_NUMCHANGE`(户数增减)、`AVG_TOTAL_SHARES`(户均持股)等 |
---
## 9. 公司资料 / 股本 / 指数
以下接口均只需 `stocks` 参数(无 `years`,返回全量),公司介绍每只 1 行。
**示例**
```bash
# 公司介绍 (基本资料: 注册资本/董事长/行业等)
curl "http://127.0.0.1:8765/fin/company-info?stocks=603233.SH"
# 股本结构 (各报告期末股本变动全量历史)
curl "http://127.0.0.1:8765/fin/equity?stocks=603233.SH"
# 所属行业 (当前生效的行业分类)
curl "http://127.0.0.1:8765/fin/industry?stocks=603233.SH"
# 所属指数分类
curl "http://127.0.0.1:8765/fin/index-classif?stocks=603233.SH"
# 纳入指数统计 (指数/基金数量)
curl "http://127.0.0.1:8765/fin/belong-index?stocks=603233.SH"
# 指数成分权重 (纳入主要指数的权重)
curl "http://127.0.0.1:8765/fin/index-membership?stocks=603233.SH"
```
**各接口常见列**
| 接口 | 常见列 |
|---|---|
| 公司介绍 | `ORG_NAME`(公司全称)、`FOUND_DATE`、`REG_CAPITAL`、`LISTING_DATE`、`CHAIRMAN`、`PRESIDENT`、`INDUSTRYCSRC1` 等 |
| 股本结构 | `END_DATE`、`CHANGE_REASON`(变动原因)、`LIMITED_SHARES`(限售股)、`UNLIMITED_SHARES`、`TOTAL_SHARES` 等 |
| 所属行业 | `INDUSTRY_TYPE`(行业类型)、`INDUSTRY_NAME`、`INDUSTRY_CODE`、`ENTRY_DATE` 等 |
| 指数分类 | `INDEX_CLASSIF_CODE`、`INDEX_CLASSIF` |
| 纳入指数统计 | `INDEX_NUM`(指数数量)、`INDEX_FUND_NUM`、`FUND_NUM`、`FUND_TOTAL_SCALE` 等 |
| 指数成分权重 | `INDEX_NAME_ABBR`(指数名)、`INDEX_CLASSIF`、`WEIGHT`(权重)、`NUM`、`INCLUDE_DATE` 等 |
---
## 10. 管理层讨论与分析(MD&A)
年报/中报的董事会报告索引(含标题与页码),默认拉最近 5 年。
**参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH` |
| `years` | int | | `5` | 拉取最近多少年的报告(1~20) |
**示例**
```bash
curl "http://127.0.0.1:8765/fin/mda?stocks=603233.SH&years=5"
```
**常见列**:`REPORT_DATE`、`REPORT_NAME`(年报/中报)、`NOTICE_DATE`、`TITLE`(标题)、`PAGE`(页码)、`RELINFOCODE`(报告关联编码)。
---
## 11. 重大事项(并购 / 股权激励 / 诉讼 / 关联交易 / 违规 / 担保)
**公共参数**
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
| `years` | int | | `3` | 拉取最近多少年的数据(1~20) |
**示例**
```bash
# 并购事件
curl "http://127.0.0.1:8765/fin/acquisitions?stocks=603233.SH&years=3"
# 股权激励 (部分股票可能无数据, 如无记录返回 404)
curl "http://127.0.0.1:8765/fin/equity-incentive?stocks=603233.SH&years=3"
# 诉讼仲裁
curl "http://127.0.0.1:8765/fin/litigation?stocks=603233.SH&years=3"
# 关联交易
curl "http://127.0.0.1:8765/fin/related-transaction?stocks=603233.SH&years=3"
# 违规处罚
curl "http://127.0.0.1:8765/fin/violation?stocks=603233.SH&years=3"
# 对外担保 (部分股票可能无数据)
curl "http://127.0.0.1:8765/fin/guarantee?stocks=603233.SH&years=3"
```
**各接口常见列**
| 接口 | 常见列 |
|---|---|
| 并购 | `PLAN_PROCESS`(进展)、`NAME_OBJ`(标的)、`NAME_BUY`(收购方)、`DEAL_AMT`(交易金额)、`TRANSFER_RATIO` 等 |
| 股权激励 | `PLAN_PROCESS`、`EI_TARGET`(对象)、`EI_WAY`(方式)、`TOTAL_INCENTIVE_SHARES`、`INITIAL_EXERCISE_PRICE`(行权价)等 |
| 诉讼仲裁 | `CASE_NAME`(案件名)、`CASE_PROFILE`、`PLAINTIFF`、`DEFENCE`、`CASE_AMOUNT`(涉诉金额)、`LITIGATION_TYPE` 等 |
| 关联交易 | `RELATED_PARTY`(关联方)、`RELATED_RELATION`(关系)、`TRADE_AMT`(金额)、`TRADE_PROFILE` 等 |
| 违规 | `VIOLATE_TYPE`(违规类型)、`PUNISH_TYPE`(处罚类型)、`PUNISH_AMT`、`SOLVE_ORG`(处理机构)等 |
| 担保 | `GUAR_NAME`(担保方)、`GUARANTEED_NAME`(被担保方)、`GUARANTEE_AMT`、`GUARANTEE_WAY`、`IS_RELATED_TRADE` 等 |
---
## 接口一览
| 路径 | 功能 | 数据来源报表 |
|---|---|---|
| `/health` | 健康检查 | — |
| `/fin/summary` | 财务摘要(报告期) | `RPT_CUSTOM_ORGF9_FIN_SUMMARY` |
| `/fin/quarterly-summary` | 财务摘要(单季度) | `RPT_HSF9_FIN_SUMMARYQUARTERNEW` |
| `/fin/main-business` | 主营构成(产品/地区) | `ZYGC_AFLZS` → `RPT_HSF9_FN_MAINOPBUSINESS` |
| `/fin/balance` | 资产负债表 | `CWSJ_ZCFZB` → `RPT_CUSTOM_HSF9_FINA_GBALANCE` |
| `/fin/income` | 利润表 | `CWSJ_LRB` → `RPT_CUSTOM_HSF9_FINA_GINCOMESYN` |
| `/fin/cashflow` | 现金流量表 | `CWSJ_XJLLB` → `RPT_CUSTOM_HSF9_FINA_GCASHFLOW` |
| `/fin/profitability` | 盈利能力与收益质量 | `CWFX_YLNLYSYZL` → `RPT_HSF9_FINA_PROFITEARNING` |
| `/fin/capital-structure` | 资本结构与偿债能力 | `CWFX_ZBJGYCZNL` → `RPT_HSF9_FINA_CAPPAYAB` |
| `/fin/operate-ability` | 营运能力 | `RPT_HSF9_FINA_OPERATEABILITY` |
| `/fin/growth` | 成长能力 | `CWFX_CZNL` → `RPT_HSF9_FINA_GROWTH` |
| `/fin/dupont` | 杜邦分析 | `RPT_HSF9_FINA_DUPONT` |
| `/fin/dividend-detail` | 分红明细 | `RPT_HSF9_ASSIGNPLAN_DETAIL` |
| `/fin/dividend-statics` | 分红统计 | `RPT_HSF9_ASSIGNPLAN_STATICS` |
| `/fin/free-holders` | 十大流通股东 | `RPT_F10_EH_FREEHOLDERS` |
| `/fin/holders` | 十大股东明细 | `RPT_DMSK_HOLDERS` |
| `/fin/holder-num` | 股东户数 | `RPT_F10_EH_HOLDERNUM` |
| `/fin/mda` | 管理层讨论与分析 | `RPT_BUSINESSANALYSIS` |
| `/fin/equity` | 股本结构 | `RPT_F10_EH_EQUITY` |
| `/fin/company-info` | 公司介绍 | `RPT_HSF9_BASIC_ORGINFO` |
| `/fin/industry` | 所属行业 | `RPT_STOCKF9_INDUSTRY` |
| `/fin/index-classif` | 所属指数分类 | `RPT_HSF9_BELONGINDEX_CLASSIF` |
| `/fin/belong-index` | 纳入指数统计 | `RPT_CUSTOM_HSF9_BELONG_INDEX` |
| `/fin/index-membership` | 指数成分权重 | `RPT_HSF9_BELONG_INDEX` |
| `/fin/acquisitions` | 并购事件 | `RPT_HS_ACQUISITIONS_EVENT` |
| `/fin/equity-incentive` | 股权激励 | `RPT_DMSK_SH_EQUITYINCENTIVE` |
| `/fin/litigation` | 诉讼仲裁 | `RPT_LITIGATION_ARBITRATION_BSINFO` |
| `/fin/related-transaction` | 关联交易 | `RPT_RELATED_TRANSACTION` |
| `/fin/violation` | 违规处罚 | `RPT_HSF9_OP_VIOLATION` |
| `/fin/guarantee` | 对外担保 | `RPT_F9_GUARANTEE` |
## 测试
```bash
uv run pytest tests/ -q # 冒烟测试: 连真实接口验证各模块能取到数据 (56 用例)
```