mirror of
https://ghfast.top/https://github.com/aeroxw/easy-tdx.git
synced 2026-09-12 14:34: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:
@@ -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 内容在该文件中的起始偏移(字节)
|
||||
length int 内容长度(字节)
|
||||
|
||||
公司信息常见分类:
|
||||
最新提示、公司概况、财务分析、股本结构、股东研究、机构持股、
|
||||
分红融资、高管治理、资金动向、资本运作、热点题材、公司公告、
|
||||
公司报道、经营分析、行业分析、研报评级
|
||||
公司信息常见分类(实测,以个股为准可能略有差异):
|
||||
最新提示、公司概况、财务分析、股本结构、股东研究、资本运作、
|
||||
业内点评、行业分析、公司大事、研究报告、经营分析、主力追踪、
|
||||
分红扩股、高层治理、龙虎榜单、关联个股
|
||||
|
||||
数据特点:
|
||||
- 目录中每个分类对应同一 .txt 文件的不同偏移位置
|
||||
@@ -34,17 +34,17 @@ SHOW_CATEGORIES = [
|
||||
"财务分析",
|
||||
"股本结构",
|
||||
"股东研究",
|
||||
"机构持股",
|
||||
"分红融资",
|
||||
"高管治理",
|
||||
"资金动向",
|
||||
"资本运作",
|
||||
"热点题材",
|
||||
"公司公告",
|
||||
"公司报道",
|
||||
"经营分析",
|
||||
"业内点评",
|
||||
"行业分析",
|
||||
"研报评级",
|
||||
"公司大事",
|
||||
"研究报告",
|
||||
"经营分析",
|
||||
"主力追踪",
|
||||
"分红扩股",
|
||||
"高层治理",
|
||||
"龙虎榜单",
|
||||
"关联个股",
|
||||
]
|
||||
|
||||
|
||||
@@ -82,22 +82,22 @@ with TdxClient.from_best_host() as c:
|
||||
# 3. 也可以单独获取某个分类的完整内容,例如:
|
||||
# show_category_content(c, categories, "公司概况", max_chars=99999)
|
||||
|
||||
# 运行结果:
|
||||
# 运行结果(板块名以实际为准,个股可能略有差异):
|
||||
# 贵州茅台 公司信息目录:
|
||||
# name filename start length
|
||||
# 最新提示 600519.txt 0 3954
|
||||
# 公司概况 600519.txt 3954 14358
|
||||
# 财务分析 600519.txt 18312 9801
|
||||
# 股本结构 600519.txt 28113 2670
|
||||
# 股东研究 600519.txt 30783 8322
|
||||
# 机构持股 600519.txt 39105 4560
|
||||
# 分红融资 600519.txt 43665 3285
|
||||
# 高管治理 600519.txt 46950 4170
|
||||
# 资金动向 600519.txt 51120 2130
|
||||
# 资本运作 600519.txt 53250 1890
|
||||
# 热点题材 600519.txt 55140 1020
|
||||
# 公司公告 600519.txt 56160 7560
|
||||
# 公司报道 600519.txt 63720 5340
|
||||
# 经营分析 600519.txt 69060 6780
|
||||
# 行业分析 600519.txt 75840 3450
|
||||
# 研报评级 600519.txt 79290 8640
|
||||
# name filename start length
|
||||
# 最新提示 600519.txt 0 12145
|
||||
# 公司概况 600519.txt 12145 12540
|
||||
# 财务分析 600519.txt 24685 36381
|
||||
# 股东研究 600519.txt 61066 25101
|
||||
# 股本结构 600519.txt 86167 3955
|
||||
# 资本运作 600519.txt 90122 13049
|
||||
# 业内点评 600519.txt 103171 69451
|
||||
# 行业分析 600519.txt 172622 16222
|
||||
# 公司大事 600519.txt 188844 357274
|
||||
# 研究报告 600519.txt 546118 69776
|
||||
# 经营分析 600519.txt 615894 22709
|
||||
# 主力追踪 600519.txt 638603 27913
|
||||
# 分红扩股 600519.txt 666516 47420
|
||||
# 高层治理 600519.txt 713936 19145
|
||||
# 龙虎榜单 600519.txt 756387 25090
|
||||
# 关联个股 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)
|
||||
Reference in New Issue
Block a user