mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 15:44:15 +08:00
feat(cli): company-info 命令合并 + examples/06_finance 文档完善
合并 company-info(列目录)与 company-info-content(读正文)为一个命令,
板块名改为可选位置参数:无参数列目录,有参数读正文。消除两个相似命令名
导致的混淆(用户曾误用 company-info SH 601088 "公司概况" 报错)。
- company-info:name_or_filename 可选,无则列 F10 板块目录,有则读正文
- company-info-content:保留为隐藏别名(hidden=True),向后兼容 v1.15.1
- 提取 _run_category/_run_content 模块级函数复用逻辑
- 新增 examples/06_finance/{README.md,company_cli.sh,company_web_api.py}
覆盖 CLI / Python API / Web API 三种调用方式,含 16 个 F10 板块完整列表
- 更新 company_info.py 板块名为实测的 16 板块
- bump 版本号至 1.15.2
This commit is contained in:
@@ -2,6 +2,24 @@
|
|||||||
|
|
||||||
本文件记录 easy-tdx 的版本变更。格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/)。
|
本文件记录 easy-tdx 的版本变更。格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/)。
|
||||||
|
|
||||||
|
## [1.15.2] — 2026-06-27
|
||||||
|
|
||||||
|
### 变更
|
||||||
|
|
||||||
|
- **`company-info` 命令合并** — 把 `company-info`(列目录)与 `company-info-content`(读正文)合并为一个命令,消除「列目录」和「读正文」两个相似命令名的混淆:
|
||||||
|
- 无板块名参数 → 列 F10 板块目录(原 `company-info`)
|
||||||
|
- 有板块名参数 → 读板块正文(原 `company-info-content`)
|
||||||
|
- `company-info-content` 保留为**隐藏别名**(`hidden=True`),向后兼容 v1.15.1 脚本,不出现在 `--help`。
|
||||||
|
- 示例:`easy-tdx company-info SH 600519 "公司概况"` 现在直接读正文(无需记忆用哪个命令)。
|
||||||
|
|
||||||
|
### 新增
|
||||||
|
|
||||||
|
- **examples/06_finance 文档完善** — 补全财务快照与 F10 公司信息的三种调用方式 demo:
|
||||||
|
- 新增 `README.md`:命令关系图、16 个 F10 板块完整列表、字段说明、三方式快速开始。
|
||||||
|
- 新增 `company_cli.sh`:CLI 命令 demo(finance-info / company-info 全用法、输出格式切换、错误处理)。
|
||||||
|
- 新增 `company_web_api.py`:Web API 调用 demo(`/finance` `/company/category` `/company/content`)。
|
||||||
|
- 更新 `company_info.py` 板块名列表为实测的 16 板块(分红扩股/高层治理/龙虎榜单等)。
|
||||||
|
|
||||||
## [1.15.1] — 2026-06-27
|
## [1.15.1] — 2026-06-27
|
||||||
|
|
||||||
### 新增
|
### 新增
|
||||||
|
|||||||
@@ -835,19 +835,20 @@ easy-tdx f10 000001 --type llb --table # 平安现金流量表,表格输
|
|||||||
|
|
||||||
### 通达信原生 F10 与最新财务快照
|
### 通达信原生 F10 与最新财务快照
|
||||||
|
|
||||||
走通达信协议(与 Web 层 ``/finance`` ``/company/*`` 端点同源),覆盖 ``f10``(新浪三表)之外的 F10 全文板块:
|
走通达信协议(与 Web 层 ``/finance`` ``/company/*`` 端点同源),覆盖 ``f10``(新浪三表)之外的 F10 全文板块。完整示例见 [examples/06_finance/](./examples/06_finance/README.md)。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
easy-tdx finance-info SH 600519 --table # 最新财务快照(30+ 项单期指标)
|
easy-tdx finance-info SH 600519 --table # 最新财务快照(30+ 项单期指标)
|
||||||
easy-tdx company-info SH 600519 # F10 板块目录(最新提示/公司概况/...)
|
easy-tdx company-info SH 600519 # F10 板块目录(最新提示/公司概况/...)
|
||||||
easy-tdx company-info-content SH 600519 "公司概况" # 读板块正文,自动解析板块名→文件
|
easy-tdx company-info SH 600519 "公司概况" # 读板块正文,自动解析板块名→文件
|
||||||
easy-tdx company-info-content SH 600519 "分红扩股" --length 2048 # 加长读取
|
easy-tdx company-info SH 600519 "分红扩股" --length 2048 # 加长读取
|
||||||
easy-tdx company-info-content SH 600519 600519.txt # 也可直接传文件名
|
easy-tdx company-info SH 600519 600519.txt # 也可直接传文件名
|
||||||
```
|
```
|
||||||
|
|
||||||
- ``finance-info``:最新一期财务快照,含股本结构、资产负债、利润、现金流、每股指标(37 字段)。与 ``f10`` 互补——前者是单期快照,后者是多期三表。
|
- ``finance-info``:最新一期财务快照,含股本结构、资产负债、利润、现金流、每股指标(37 字段)。与 ``f10`` 互补——前者是单期快照,后者是多期三表。
|
||||||
- ``company-info``:列出该股 F10 的全部板块(最新提示、公司概况、财务分析、股东研究、股本结构、资本运作、业内点评、行业分析、公司大事、研究报告、经营分析、主力追踪、分红扩股、高层治理、龙虎榜单、关联个股)及其文件偏移。
|
- ``company-info``:**一个命令两种用法**——无板块名参数列 F10 板块目录,有板块名参数读正文。目录含 16 个板块(最新提示、公司概况、财务分析、股东研究、股本结构、资本运作、业内点评、行业分析、公司大事、研究报告、经营分析、主力追踪、分红扩股、高层治理、龙虎榜单、关联个股)。
|
||||||
- ``company-info-content``:``name_or_filename`` 既可传板块名(自动定位到该板块起点读取),也可直接传文件名。``--offset`` / ``--length`` 控制读取范围(字节,默认 0/1024)。
|
- 读正文时 ``name_or_filename`` 既可传板块名(自动定位到该板块起点),也可传文件名;``--offset`` 语义随入参而定(板块名=板块内相对偏移,文件名=文件绝对偏移),``--length`` 控制读取字节数。
|
||||||
|
|
||||||
|
|
||||||
### 扩展市场(港股/美股/期货)
|
### 扩展市场(港股/美股/期货)
|
||||||
|
|
||||||
@@ -1087,8 +1088,7 @@ uvicorn.run(app, host="0.0.0.0", port=8000)
|
|||||||
| `serve` | 启动 Web API 服务器(REST + WebSocket,需 `easy-tdx[web]`) |
|
| `serve` | 启动 Web API 服务器(REST + WebSocket,需 `easy-tdx[web]`) |
|
||||||
| `f10` | 财报三表(新浪:利润表/资产负债表/现金流量表) |
|
| `f10` | 财报三表(新浪:利润表/资产负债表/现金流量表) |
|
||||||
| `finance-info` | 最新财务快照(通达信协议,30+ 项单期指标) |
|
| `finance-info` | 最新财务快照(通达信协议,30+ 项单期指标) |
|
||||||
| `company-info` | F10 公司信息板块目录(通达信协议) |
|
| `company-info` | F10 公司信息(无板块名列目录 / 有板块名读正文) |
|
||||||
| `company-info-content` | F10 板块正文(板块名或文件名,GBK 文本) |
|
|
||||||
| `fund-flow` | 历史资金流向 |
|
| `fund-flow` | 历史资金流向 |
|
||||||
| `ex kline` | 扩展市场 K 线 |
|
| `ex kline` | 扩展市场 K 线 |
|
||||||
| `ex quote` | 扩展市场报价 |
|
| `ex quote` | 扩展市场报价 |
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# 06. 财务数据与 F10 公司信息
|
||||||
|
|
||||||
|
通达信原生协议(TdxClient)提供两类财务/公司数据,独立于 [新浪三表 `f10`](../../README.md#财务):
|
||||||
|
|
||||||
|
| 命令 / 接口 | 数据 | 说明 |
|
||||||
|
|-------------|------|------|
|
||||||
|
| `finance-info` / `GET /api/v1/finance` | **最新财务快照** | 单期 37 字段(股本、资产负债、利润、现金流、每股指标) |
|
||||||
|
| `company-info`(无板块名)/ `GET /api/v1/company/category` | **F10 板块目录** | 列出全部板块及其文件偏移 |
|
||||||
|
| `company-info "板块名"` / `GET /api/v1/company/content` | **F10 板块正文** | 读取指定板块的 GBK 文本 |
|
||||||
|
|
||||||
|
> **与 `f10` 的区别**:`f10` 走新浪 HTTP,返回多期结构化利润表/负债表/现金流(DataFrame,可数值计算);本目录的命令走通达信协议,`finance-info` 是最新一期的快照,`company-info` 是 F10 全文板块(纯文本)。
|
||||||
|
|
||||||
|
## company-info 命令的两种用法
|
||||||
|
|
||||||
|
`company-info` 根据是否传入板块名参数自动切换行为:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 用法 1:无板块名 → 列出 F10 板块目录
|
||||||
|
easy-tdx company-info SH 600519 --table
|
||||||
|
|
||||||
|
# 用法 2:有板块名 → 读取该板块正文
|
||||||
|
easy-tdx company-info SH 600519 "公司概况"
|
||||||
|
easy-tdx company-info SH 600519 "分红扩股" --length 2048
|
||||||
|
```
|
||||||
|
|
||||||
|
读正文时板块名也可换成文件名(`600519.txt`),此时 `--offset` 为文件绝对偏移。
|
||||||
|
|
||||||
|
## F10 板块完整列表
|
||||||
|
|
||||||
|
`company-info` 列目录时返回的全部板块(以贵州茅台 600519 为例,个股板块可能略有差异):
|
||||||
|
|
||||||
|
| 板块名 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 最新提示 | 最新指标、近期公告、机构持股变化、概念板块 |
|
||||||
|
| 公司概况 | 基本资料、发行上市、关联企业 |
|
||||||
|
| 财务分析 | 主要财务指标、环比/同比分析 |
|
||||||
|
| 股东研究 | 十大股东、流通股东、股东变化 |
|
||||||
|
| 股本结构 | 股本结构、股本变化、限售流通、股权激励 |
|
||||||
|
| 资本运作 | 募集资金使用、重大事项 |
|
||||||
|
| 业内点评 | 机构点评、投资建议 |
|
||||||
|
| 行业分析 | 行业地位、市场前景 |
|
||||||
|
| 公司大事 | 重要事件、公告 |
|
||||||
|
| 研究报告 | 券商研报、盈利预测 |
|
||||||
|
| 经营分析 | 主营业务、经营情况 |
|
||||||
|
| 主力追踪 | 主力资金、筹码集中度 |
|
||||||
|
| 分红扩股 | 分红送转、历史派息 |
|
||||||
|
| 高层治理 | 高管简历、薪酬 |
|
||||||
|
| 龙虎榜单 | 龙虎榜上榜记录 |
|
||||||
|
| 关联个股 | 同行业/同概念关联股票 |
|
||||||
|
|
||||||
|
## 示例文件
|
||||||
|
|
||||||
|
| 文件 | 调用方式 | 覆盖内容 |
|
||||||
|
|------|----------|----------|
|
||||||
|
| `finance_info.py` | Python API | 最新财务快照(37 字段) |
|
||||||
|
| `company_info.py` | Python API | F10 板块目录 + 遍历各板块正文 |
|
||||||
|
| `company_cli.sh` | CLI | `finance-info` / `company-info` 全用法 |
|
||||||
|
| `company_web_api.py` | Web API | `/finance` `/company/category` `/company/content` |
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 最新财务快照
|
||||||
|
easy-tdx finance-info SH 600519 --table
|
||||||
|
|
||||||
|
# F10 板块目录
|
||||||
|
easy-tdx company-info SH 600519
|
||||||
|
|
||||||
|
# 读 F10 正文
|
||||||
|
easy-tdx company-info SH 600519 "公司概况"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python API
|
||||||
|
|
||||||
|
```python
|
||||||
|
from easy_tdx import Market, TdxClient
|
||||||
|
|
||||||
|
with TdxClient.from_best_host() as c:
|
||||||
|
# 最新财务快照(单行 DataFrame)
|
||||||
|
finance = c.get_finance_info(Market.SH, "600519")
|
||||||
|
|
||||||
|
# F10 板块目录
|
||||||
|
cats = c.get_company_info_category(Market.SH, "600519")
|
||||||
|
|
||||||
|
# 读某板块正文:先从目录查 filename/start/length
|
||||||
|
row = cats[cats["name"] == "公司概况"].iloc[0]
|
||||||
|
content = c.get_company_info_content(
|
||||||
|
Market.SH, "600519", row["filename"], int(row["start"]), int(row["length"])
|
||||||
|
)
|
||||||
|
print(content)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Web API
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动服务
|
||||||
|
easy-tdx serve
|
||||||
|
|
||||||
|
# 最新财务快照
|
||||||
|
curl "http://localhost:8000/api/v1/finance?market=SH&code=600519"
|
||||||
|
|
||||||
|
# F10 板块目录
|
||||||
|
curl "http://localhost:8000/api/v1/company/category?market=SH&code=600519"
|
||||||
|
|
||||||
|
# 读 F10 正文(filename/offset/length 从目录接口获取)
|
||||||
|
curl "http://localhost:8000/api/v1/company/content?market=SH&code=600519&filename=600519.txt&offset=0&length=2048"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 字段说明
|
||||||
|
|
||||||
|
### finance-info(最新财务快照)
|
||||||
|
|
||||||
|
| 字段 | 单位 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `liutong_guben` / `zong_guben` | 万股 | 流通股本 / 总股本 |
|
||||||
|
| `guojia_gu` / `faren_gu` / `b_gu` / `h_gu` | 万股 | 国家股 / 法人股 / B股 / H股 |
|
||||||
|
| `zong_zichan` / `liudong_zichan` / `guding_zichan` | 元 | 总/流动/固定资产 |
|
||||||
|
| `liudong_fuzhai` / `changqi_fuzhai` / `jing_zichan` | 元 | 流动/长期负债 / 净资产 |
|
||||||
|
| `zhuying_shouru` / `yingye_lirun` / `jing_lirun` | 元 | 主营收入 / 营业利润 / 净利润 |
|
||||||
|
| `jingying_xianjinliu` / `zong_xianjinliu` | 元 | 经营现金流 / 总现金流 |
|
||||||
|
| `meigujing_zichan` | 元 | 每股净资产 |
|
||||||
|
| `updated_date` / `ipo_date` | YYYYMMDD | 财务更新日 / 上市日 |
|
||||||
|
|
||||||
|
完整字段见 `finance_info.py` 顶部注释。
|
||||||
|
|
||||||
|
### company-info(F10 板块目录)
|
||||||
|
|
||||||
|
| 列 | 类型 | 说明 |
|
||||||
|
|----|------|------|
|
||||||
|
| `name` | str | 板块名(如「公司概况」) |
|
||||||
|
| `filename` | str | 内容文件名(如 `600519.txt`) |
|
||||||
|
| `start` | int | 内容在该文件中的起始偏移(字节) |
|
||||||
|
| `length` | int | 内容长度(字节) |
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# easy-tdx 财务快照与 F10 公司信息 — CLI 使用示例
|
||||||
|
#
|
||||||
|
# 三条命令:
|
||||||
|
# finance-info — 最新财务快照(37 字段单期指标)
|
||||||
|
# company-info — F10 板块目录(无板块名)/ 板块正文(有板块名)
|
||||||
|
#
|
||||||
|
# 与 f10(新浪三表)的区别:f10 返回多期利润表/负债表/现金流;
|
||||||
|
# 本组命令走通达信协议,finance-info 是单期快照,company-info 是 F10 全文板块。
|
||||||
|
#
|
||||||
|
# 用法:去掉命令前的 # 即可实际执行。
|
||||||
|
|
||||||
|
CODE=600519 # 贵州茅台
|
||||||
|
MARKET=SH
|
||||||
|
|
||||||
|
echo "================================================================"
|
||||||
|
echo "1. finance-info — 最新财务快照(表格输出)"
|
||||||
|
echo "================================================================"
|
||||||
|
# easy-tdx finance-info $MARKET $CODE --table
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "================================================================"
|
||||||
|
echo "2. company-info 无板块名 — 列出 F10 板块目录"
|
||||||
|
echo "================================================================"
|
||||||
|
# easy-tdx company-info $MARKET $CODE --table
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "================================================================"
|
||||||
|
echo "3. company-info \"板块名\" — 读取 F10 板块正文"
|
||||||
|
echo "================================================================"
|
||||||
|
|
||||||
|
echo "--- 3.1 公司概况 ---"
|
||||||
|
# easy-tdx company-info $MARKET $CODE "公司概况"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--- 3.2 股本结构(板块较短,默认 1024 字节即可读全)---"
|
||||||
|
# easy-tdx company-info $MARKET $CODE "股本结构"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--- 3.3 分红扩股(加长读取)---"
|
||||||
|
# easy-tdx company-info $MARKET $CODE "分红扩股" --length 4096
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--- 3.4 龙虎榜单 ---"
|
||||||
|
# easy-tdx company-info $MARKET $CODE "龙虎榜单"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "================================================================"
|
||||||
|
echo "4. 输出格式切换(JSON / CSV)"
|
||||||
|
echo "================================================================"
|
||||||
|
echo "--- 4.1 财务快照 JSON(默认,适合 Agent 解析)---"
|
||||||
|
# easy-tdx finance-info $MARKET $CODE --output json
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "--- 4.2 板块目录 CSV ---"
|
||||||
|
# easy-tdx company-info $MARKET $CODE --output csv
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "================================================================"
|
||||||
|
echo "5. 直接传文件名读正文(高级用法)"
|
||||||
|
echo "================================================================"
|
||||||
|
echo "# filename 从「company-info 列目录」结果获取;offset 为文件绝对偏移"
|
||||||
|
# easy-tdx company-info $MARKET $CODE ${CODE}.txt --offset 0 --length 2048
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "================================================================"
|
||||||
|
echo "6. 错误处理:板块名不存在时提示可用板块"
|
||||||
|
echo "================================================================"
|
||||||
|
# easy-tdx company-info $MARKET $CODE "不存在的板块"
|
||||||
@@ -10,10 +10,10 @@ get_company_info_category() 返回 CompanyInfoCategory DataFrame,列说明:
|
|||||||
start int 内容在该文件中的起始偏移(字节)
|
start int 内容在该文件中的起始偏移(字节)
|
||||||
length int 内容长度(字节)
|
length int 内容长度(字节)
|
||||||
|
|
||||||
公司信息常见分类:
|
公司信息常见分类(实测,以个股为准可能略有差异):
|
||||||
最新提示、公司概况、财务分析、股本结构、股东研究、机构持股、
|
最新提示、公司概况、财务分析、股本结构、股东研究、资本运作、
|
||||||
分红融资、高管治理、资金动向、资本运作、热点题材、公司公告、
|
业内点评、行业分析、公司大事、研究报告、经营分析、主力追踪、
|
||||||
公司报道、经营分析、行业分析、研报评级
|
分红扩股、高层治理、龙虎榜单、关联个股
|
||||||
|
|
||||||
数据特点:
|
数据特点:
|
||||||
- 目录中每个分类对应同一 .txt 文件的不同偏移位置
|
- 目录中每个分类对应同一 .txt 文件的不同偏移位置
|
||||||
@@ -34,17 +34,17 @@ SHOW_CATEGORIES = [
|
|||||||
"财务分析",
|
"财务分析",
|
||||||
"股本结构",
|
"股本结构",
|
||||||
"股东研究",
|
"股东研究",
|
||||||
"机构持股",
|
|
||||||
"分红融资",
|
|
||||||
"高管治理",
|
|
||||||
"资金动向",
|
|
||||||
"资本运作",
|
"资本运作",
|
||||||
"热点题材",
|
"业内点评",
|
||||||
"公司公告",
|
|
||||||
"公司报道",
|
|
||||||
"经营分析",
|
|
||||||
"行业分析",
|
"行业分析",
|
||||||
"研报评级",
|
"公司大事",
|
||||||
|
"研究报告",
|
||||||
|
"经营分析",
|
||||||
|
"主力追踪",
|
||||||
|
"分红扩股",
|
||||||
|
"高层治理",
|
||||||
|
"龙虎榜单",
|
||||||
|
"关联个股",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -82,22 +82,22 @@ with TdxClient.from_best_host() as c:
|
|||||||
# 3. 也可以单独获取某个分类的完整内容,例如:
|
# 3. 也可以单独获取某个分类的完整内容,例如:
|
||||||
# show_category_content(c, categories, "公司概况", max_chars=99999)
|
# show_category_content(c, categories, "公司概况", max_chars=99999)
|
||||||
|
|
||||||
# 运行结果:
|
# 运行结果(板块名以实际为准,个股可能略有差异):
|
||||||
# 贵州茅台 公司信息目录:
|
# 贵州茅台 公司信息目录:
|
||||||
# name filename start length
|
# name filename start length
|
||||||
# 最新提示 600519.txt 0 3954
|
# 最新提示 600519.txt 0 12145
|
||||||
# 公司概况 600519.txt 3954 14358
|
# 公司概况 600519.txt 12145 12540
|
||||||
# 财务分析 600519.txt 18312 9801
|
# 财务分析 600519.txt 24685 36381
|
||||||
# 股本结构 600519.txt 28113 2670
|
# 股东研究 600519.txt 61066 25101
|
||||||
# 股东研究 600519.txt 30783 8322
|
# 股本结构 600519.txt 86167 3955
|
||||||
# 机构持股 600519.txt 39105 4560
|
# 资本运作 600519.txt 90122 13049
|
||||||
# 分红融资 600519.txt 43665 3285
|
# 业内点评 600519.txt 103171 69451
|
||||||
# 高管治理 600519.txt 46950 4170
|
# 行业分析 600519.txt 172622 16222
|
||||||
# 资金动向 600519.txt 51120 2130
|
# 公司大事 600519.txt 188844 357274
|
||||||
# 资本运作 600519.txt 53250 1890
|
# 研究报告 600519.txt 546118 69776
|
||||||
# 热点题材 600519.txt 55140 1020
|
# 经营分析 600519.txt 615894 22709
|
||||||
# 公司公告 600519.txt 56160 7560
|
# 主力追踪 600519.txt 638603 27913
|
||||||
# 公司报道 600519.txt 63720 5340
|
# 分红扩股 600519.txt 666516 47420
|
||||||
# 经营分析 600519.txt 69060 6780
|
# 高层治理 600519.txt 713936 19145
|
||||||
# 行业分析 600519.txt 75840 3450
|
# 龙虎榜单 600519.txt 756387 25090
|
||||||
# 研报评级 600519.txt 79290 8640
|
# 关联个股 600519.txt 733081 23306
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
"""财务快照与 F10 公司信息 — Web API 调用示例。
|
||||||
|
|
||||||
|
演示如何通过 HTTP 调用 easy-tdx 的 REST API 获取:
|
||||||
|
1. GET /finance — 最新财务快照(finance-info 对应)
|
||||||
|
2. GET /company/category — F10 板块目录(company-info 无板块名对应)
|
||||||
|
3. GET /company/content — F10 板块正文(company-info 有板块名对应)
|
||||||
|
|
||||||
|
前提:
|
||||||
|
1. 启动 Web API 服务:easy-tdx serve --port 8000
|
||||||
|
2. pip install requests
|
||||||
|
|
||||||
|
注意:与 CLI 的 company-info 不同,Web 层把「列目录」和「读正文」拆成两个端点
|
||||||
|
(面向程序,参数更显式)。读正文需要先调 /company/category 拿到 filename/offset/length,
|
||||||
|
再调 /company/content。
|
||||||
|
|
||||||
|
运行方式:
|
||||||
|
python examples/06_finance/company_web_api.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
BASE_URL = "http://localhost:8000/api/v1"
|
||||||
|
MARKET = "SH"
|
||||||
|
CODE = "600519" # 贵州茅台
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_finance() -> dict:
|
||||||
|
"""GET /finance — 最新财务快照(单期 37 字段)。
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
{"data": [{...财务字段...}]}
|
||||||
|
"""
|
||||||
|
resp = requests.get(f"{BASE_URL}/finance", params={"market": MARKET, "code": CODE}, timeout=15)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json()
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_company_category() -> dict:
|
||||||
|
"""GET /company/category — F10 板块目录。
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
{"data": [{"name":..., "filename":..., "start":..., "length":...}, ...]}
|
||||||
|
"""
|
||||||
|
resp = requests.get(
|
||||||
|
f"{BASE_URL}/company/category", params={"market": MARKET, "code": CODE}, timeout=15
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json()
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_company_content(filename: str, offset: int = 0, length: int = 1024) -> str:
|
||||||
|
"""GET /company/content — F10 板块正文(GBK 文本)。
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filename: 文件名(从 /company/category 的 filename 列获取,如 "600519.txt")
|
||||||
|
offset: 内容起始偏移(字节)
|
||||||
|
length: 读取长度(字节)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
板块正文文本
|
||||||
|
"""
|
||||||
|
resp = requests.get(
|
||||||
|
f"{BASE_URL}/company/content",
|
||||||
|
params={
|
||||||
|
"market": MARKET,
|
||||||
|
"code": CODE,
|
||||||
|
"filename": filename,
|
||||||
|
"offset": offset,
|
||||||
|
"length": length,
|
||||||
|
},
|
||||||
|
timeout=15,
|
||||||
|
)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp.json()["content"]
|
||||||
|
|
||||||
|
|
||||||
|
def find_section(categories: dict, section_name: str) -> dict | None:
|
||||||
|
"""从目录结果中按板块名查找条目(name/filename/start/length)。"""
|
||||||
|
for row in categories.get("data", []):
|
||||||
|
if row["name"] == section_name:
|
||||||
|
return row
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# 演示主流程
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"1. 最新财务快照 GET /finance({CODE})")
|
||||||
|
print("=" * 60)
|
||||||
|
finance = fetch_finance()
|
||||||
|
data = finance["data"][0]
|
||||||
|
print(f" 总股本: {data['zong_guben']:.0f} 万股")
|
||||||
|
print(f" 净利润: {data['jing_lirun']:.2e} 元")
|
||||||
|
print(f" 每股净资产: {data['meigujing_zichan']:.4f} 元")
|
||||||
|
print(f" 更新日期: {data['updated_date']}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print(f"2. F10 板块目录 GET /company/category({CODE})")
|
||||||
|
print("=" * 60)
|
||||||
|
categories = fetch_company_category()
|
||||||
|
for row in categories["data"]:
|
||||||
|
print(f" {row['name']:<6} {row['filename']} (offset={row['start']}, len={row['length']})")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("3. F10 板块正文 GET /company/content")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 读正文是两步:先从目录查 filename/offset/length,再调 content
|
||||||
|
section = find_section(categories, "公司概况")
|
||||||
|
if section:
|
||||||
|
print(
|
||||||
|
f"\n--- 3.1 公司概况(filename={section['filename']}, "
|
||||||
|
f"offset={section['start']}, length={section['length']})---"
|
||||||
|
)
|
||||||
|
content = fetch_company_content(
|
||||||
|
section["filename"], section["start"], min(section["length"], 1024)
|
||||||
|
)
|
||||||
|
print(content[:500]) # 只打印前 500 字
|
||||||
|
else:
|
||||||
|
print("未找到「公司概况」板块")
|
||||||
|
|
||||||
|
# 也可只读某板块前 N 字节(用 start + 自定义 length)
|
||||||
|
section2 = find_section(categories, "股本结构")
|
||||||
|
if section2:
|
||||||
|
print(f"\n--- 3.2 股本结构(length={section2['length']},全量读取)---")
|
||||||
|
content2 = fetch_company_content(
|
||||||
|
section2["filename"], section2["start"], section2["length"]
|
||||||
|
)
|
||||||
|
print(content2)
|
||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "easy-tdx"
|
name = "easy-tdx"
|
||||||
version = "1.15.1"
|
version = "1.15.2"
|
||||||
description = "通达信 TCP 协议行情数据客户端,支持在线行情、离线数据读取与写入同步"
|
description = "通达信 TCP 协议行情数据客户端,支持在线行情、离线数据读取与写入同步"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
|
|||||||
@@ -49,36 +49,50 @@ def finance_info(market: str, code: str, use_table: bool, output_fmt: str) -> No
|
|||||||
@click.command("company-info")
|
@click.command("company-info")
|
||||||
@click.argument("market")
|
@click.argument("market")
|
||||||
@click.argument("code")
|
@click.argument("code")
|
||||||
@click.option("--table", "use_table", is_flag=True, help="表格输出")
|
@click.argument("name_or_filename", required=False, default=None)
|
||||||
|
@click.option("--table", "use_table", is_flag=True, help="表格输出(仅列目录时生效)")
|
||||||
@click.option("--output", "output_fmt", type=click.Choice(["json", "table", "csv"]), default="json")
|
@click.option("--output", "output_fmt", type=click.Choice(["json", "table", "csv"]), default="json")
|
||||||
def company_info(market: str, code: str, use_table: bool, output_fmt: str) -> None:
|
@click.option(
|
||||||
"""获取 F10 公司信息板块目录。
|
"--offset",
|
||||||
|
default=0,
|
||||||
返回各板块的名称(最新提示/公司概况/财务分析/持股情况/股本结构/
|
type=int,
|
||||||
分红融资/高管信息/行业产品/新闻公告/回顾展望 等)、文件名及偏移长度。
|
help="读正文偏移(字节):传板块名时为板块内相对偏移,传文件名时为文件绝对偏移,默认 0",
|
||||||
拿到板块名后可用 ``company-info-content`` 读取正文。
|
)
|
||||||
|
@click.option("--length", default=1024, type=int, help="读正文长度(字节,默认 1024)")
|
||||||
|
def company_info(
|
||||||
|
market: str,
|
||||||
|
code: str,
|
||||||
|
name_or_filename: str | None,
|
||||||
|
use_table: bool,
|
||||||
|
output_fmt: str,
|
||||||
|
offset: int,
|
||||||
|
length: int,
|
||||||
|
) -> None:
|
||||||
|
"""获取 F10 公司信息:无板块名参数列目录,有板块名参数读正文。
|
||||||
|
|
||||||
\b
|
\b
|
||||||
示例:
|
两种用法:
|
||||||
|
|
||||||
|
# 1. 列出 F10 板块目录(最新提示/公司概况/财务分析/... 共 16 板块)
|
||||||
easy-tdx company-info SH 600519 --table
|
easy-tdx company-info SH 600519 --table
|
||||||
|
|
||||||
|
# 2. 读取指定板块正文(板块名自动解析定位)
|
||||||
|
easy-tdx company-info SH 600519 "公司概况"
|
||||||
|
easy-tdx company-info SH 600519 "分红扩股" --length 2048
|
||||||
|
|
||||||
|
\b
|
||||||
|
读正文时,name_or_filename 既可传板块名(如 ``最新提示``),也可直接传文件名
|
||||||
|
(如 ``600519.txt``)。``--offset`` 语义随入参而定:传板块名时为板块内相对
|
||||||
|
偏移(0 = 板块起点);传文件名时为文件绝对偏移。
|
||||||
"""
|
"""
|
||||||
from ..exceptions import TdxError
|
|
||||||
from .conn import get_tdx_client
|
|
||||||
from .output import print_error, print_output
|
|
||||||
|
|
||||||
fmt = "table" if use_table else output_fmt
|
|
||||||
mkt = Market(parse_market(market))
|
mkt = Market(parse_market(market))
|
||||||
try:
|
if name_or_filename is None:
|
||||||
with get_tdx_client() as client:
|
_run_category(mkt, code, use_table, output_fmt)
|
||||||
df = client.get_company_info_category(mkt, code)
|
else:
|
||||||
except TdxError as e:
|
_run_content(mkt, code, name_or_filename, offset, length)
|
||||||
print_error(str(e))
|
|
||||||
raise SystemExit(1) from e
|
|
||||||
print_output(df, fmt)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command("company-info-content")
|
@click.command("company-info-content", hidden=True)
|
||||||
@click.argument("market")
|
@click.argument("market")
|
||||||
@click.argument("code")
|
@click.argument("code")
|
||||||
@click.argument("name_or_filename")
|
@click.argument("name_or_filename")
|
||||||
@@ -92,36 +106,56 @@ def company_info(market: str, code: str, use_table: bool, output_fmt: str) -> No
|
|||||||
def company_info_content(
|
def company_info_content(
|
||||||
market: str, code: str, name_or_filename: str, offset: int, length: int
|
market: str, code: str, name_or_filename: str, offset: int, length: int
|
||||||
) -> None:
|
) -> None:
|
||||||
"""读取 F10 公司信息板块正文(GBK 文本)。
|
"""[已弃用,改用 company-info] 读取 F10 公司信息板块正文。
|
||||||
|
|
||||||
``name_or_filename`` 既可传板块名(如 ``最新提示``,自动查目录解析),
|
此命令为向后兼容保留(隐藏,不出现在 --help)。新用法::
|
||||||
也可直接传文件名(如 ``600519.txt``)。建议先用 ``company-info``
|
|
||||||
查看可用板块名。
|
|
||||||
|
|
||||||
``--offset`` 语义随入参而定:传板块名时为**板块内相对偏移**
|
easy-tdx company-info SH 600519 "公司概况"
|
||||||
(0 = 板块起点);传文件名时为**文件绝对偏移**。
|
|
||||||
|
|
||||||
\b
|
|
||||||
示例:
|
|
||||||
|
|
||||||
easy-tdx company-info-content SH 600519 "最新提示"
|
|
||||||
|
|
||||||
easy-tdx company-info-content SH 600519 600519.txt --length 2048
|
|
||||||
"""
|
"""
|
||||||
|
mkt = Market(parse_market(market))
|
||||||
|
_run_content(mkt, code, name_or_filename, offset, length)
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# 内部实现:列目录 / 读正文
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
|
||||||
|
|
||||||
|
def _run_category(market: Market, code: str, use_table: bool, output_fmt: str) -> None:
|
||||||
|
"""列出 F10 板块目录并输出。"""
|
||||||
|
from ..exceptions import TdxError
|
||||||
|
from .conn import get_tdx_client
|
||||||
|
from .output import print_error, print_output
|
||||||
|
|
||||||
|
fmt = "table" if use_table else output_fmt
|
||||||
|
try:
|
||||||
|
with get_tdx_client() as client:
|
||||||
|
df = client.get_company_info_category(market, code)
|
||||||
|
except TdxError as e:
|
||||||
|
print_error(str(e))
|
||||||
|
raise SystemExit(1) from e
|
||||||
|
print_output(df, fmt)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_content(
|
||||||
|
market: Market, code: str, name_or_filename: str, offset: int, length: int
|
||||||
|
) -> None:
|
||||||
|
"""读取 F10 板块正文并输出。"""
|
||||||
from ..exceptions import TdxError
|
from ..exceptions import TdxError
|
||||||
from .conn import get_tdx_client
|
from .conn import get_tdx_client
|
||||||
from .output import print_error
|
from .output import print_error
|
||||||
|
|
||||||
mkt = Market(parse_market(market))
|
|
||||||
try:
|
try:
|
||||||
with get_tdx_client() as client:
|
with get_tdx_client() as client:
|
||||||
filename, seg_start, matched_board = _resolve_filename(
|
filename, seg_start, matched_board = _resolve_filename(
|
||||||
client, mkt, code, name_or_filename
|
client, market, code, name_or_filename
|
||||||
)
|
)
|
||||||
# 板块名命中:--offset 解释为板块内相对偏移(默认 0 = 板块起点)
|
# 板块名命中:--offset 解释为板块内相对偏移(默认 0 = 板块起点)
|
||||||
# 文件名:--offset 解释为文件绝对偏移
|
# 文件名:--offset 解释为文件绝对偏移
|
||||||
effective_offset = seg_start + offset if matched_board else offset
|
effective_offset = seg_start + offset if matched_board else offset
|
||||||
content = client.get_company_info_content(mkt, code, filename, effective_offset, length)
|
content = client.get_company_info_content(
|
||||||
|
market, code, filename, effective_offset, length
|
||||||
|
)
|
||||||
except _ResolveError as e:
|
except _ResolveError as e:
|
||||||
print_error(str(e))
|
print_error(str(e))
|
||||||
raise SystemExit(1) from e
|
raise SystemExit(1) from e
|
||||||
|
|||||||
Reference in New Issue
Block a user