gangtise-openapi-cli 0.50.0 → 0.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  README 仅列最近 5 个版本摘要:
8
8
 
9
+ - **v0.51.0 — 2026-11-07**:① **新增 `ai expert-intel` AI 专家情报**:从专家会议、会议纪要提炼的个股情报(标题 + 内容标签 + 正文,附关联证券 / 研究方向 / 题材),可按证券、研究方向、题材、内容标签、关键词与发布时间筛选;**20 积分/条**、自动翻页,省略 `--size` 时估算超过 1000 积分须加 `--yes`。② **新增 `reference index-weight` 指数成分股权重**(免费):按指数代码与交易日返回全部成分股及权重(%),可一次查多个指数。权重按**每月最后一个交易日**提供,其他日期、非交易日与写错的指数代码都返回空结果、不报错——CLI 在 stderr 点名没取到数据的指数。③ **新增 `vault wechat-message-download` 群消息文件下载**(免费):用 `wechat-message-list` 返回的 `msgId` 下载文档 / 图片 / 音频 / 视频消息的文件,按服务端给的文件名保存、内容原样落盘(`.txt` / `.json` 等文本类文件同样不改动);文本 / 链接消息返回 `130005`,消息不存在或无权访问返回 `130003`。④ `vault wechat-message-list --category` 新增 `audio` / `video`;⚠️ 文档类消息的取值是 `document`,写成 `documents` 会报 `100005`,脚本里用了后者的要改。⑤ 文档:EDE 新增银行 / 保险 / 券商专项财务指标、估值分位数等;⚠️ `scr_indu`(所属行业)、`cdr_conv_ratio`(CDR 转换比例)与半年期行情、周 / 月 / 季 / 年均成交额与成交量共 23 项指标预计下线,`indicator search` 已搜不到;行业分类改用 `scr_indu_citic` / `scr_indu_sw` / `scr_indu_gics`。⑥ `fund etf-pcf-components` 补代码:同名 A / H 股价格碰巧相同、或另一市场那只排除不了时,改用该行的 `pctChange` 核对(收盘价与涨跌幅都相同的那只),此前这类行要么按其余各行的市场补(可能补错),要么留 `null`;涨跌幅也定不了时留 `null`,不再按其余各行的市场补。⑦ `fund_ret_rank` / `fund_ret_rank_pct` 的同类基金数量现与 `industryLevel` 对应的分类一致,同类比较可直接使用,不必再自行核对分母。
10
+
9
11
  - **v0.50.0 — 2026-11-01**:① **新增个股笔记**:`vault stock-note-list` 查询(全部 / 按证券 / 按笔记 ID)、`stock-note-add` 新增(一条关联 1~50 只证券)、`stock-note-update` 改写正文、`stock-note-delete` 删除(须 `--yes`),均免费。② **新增 `quote sector-fund-flow` 板块日资金流向**(免费;按当日成分股加总、只计沪深京;撞 `100006` 要缩区间或减板块 / 字段,调小 `--limit` 无效)。③ `vault stock-pool-list` / `stock-pool-stocks` 加 `--space-type 2` 查所属租户的股票池。④ 路演 / 调研 / 策略会 / 论坛加 `--publish-start-time` / `--publish-end-time`,按收录时间筛选,可与举办时间同时用。⑤ `indicator time-series` 不传 `--calendar-type` 时由服务端按指标定日期轴(不再先查 `indicator search`);区间里没有报告期末时报告期类指标返回空结果(此前是逐日 `null` 行);⚠️ 一致预期 `frcst_*` 要逐日序列须显式传 `ND`。⑥ ETF 成分补代码在名称查询失败、A / H 定不了等情形下留 `null`,不再按其余行推断;A / H 价格都对得上时按其余行所在的单一市场取。⑦ 指标参数报错的改法提示按服务端新写法修正。⑧ 文档:量比、自由流通、流通股本与市值、AH 溢价率、涨跌停、TTM 利润类等 EDE 指标;⚠️ 基金收益率同类排名的分母不一定等于所属分类的基金数,同类比较前先核对。
10
12
 
11
13
  - **v0.49.0 — 2026-10-28**:① **新增 `gangtise update`**:一条命令更新到最新版(从 npmjs.org `npm install -g`),并替换 `~/.claude` / `~/.codex` / `~/.openclaw/workspace` / `~/.hermes` 下版本较旧的 Agent Skill 副本;`--check` 只查不装,`--no-skill` 不动 skill 副本。② **新版本提示**:在终端里运行任何命令时,若已有新版本,结束后 stderr 提示一行(同一新版本约一天一次);版本信息在后台刷新、命令不等网络,脚本 / Agent / CI 中不提示,`GANGTISE_NO_UPDATE_CHECK=1` 关闭。③ **管理层情绪的 `publishTime` 现为北京时间**,与 `--start-time` / `--end-time` 同一口径;按 v0.48.0 说明「先加 8 小时」处理过的脚本要去掉这一步。④ **路演 / 调研 / 策略会 / 论坛列表的翻页去重改按各自的 ID**(`roadshowId` / `siteVisitId` / `strategyMeetingId` / `forumId`):跨页重复的行会被去掉、结果标为不完整(退出码 3),提示缩短时间范围重拉;`response-schema.md` 同步更正这四个列表的字段名。⑤ **公募基金**:`fund holder-structure` 的 `holderCount` 现为整数,按 v0.44.0 说明「先去千分位逗号再转数字」的处理要去掉(对整数做字符串替换会报错);`fund etf-pcf-components` 的接口只返回成分名称,CLI 按名称匹配补上 `componentCode`(带市场后缀,如 `600519.SH` / `00941.HK`;用该行收盘价核对,A+H 同名两行分别匹配;现金行等匹配不到的为 `null`,stderr 列出),`--no-component-code` 关闭。⑥ `ai security-clue` 的 `--query-mode` / `--gts-code` 补充帮助说明。
@@ -14,8 +16,6 @@ README 仅列最近 5 个版本摘要:
14
16
 
15
17
  - **v0.47.0 — 2026-10-17**:① **`insight opinion list` 新增 `--category`(观点类别:业绩点评 / 异动点评 / 调研访谈更新 / 交易台 / 行业分析)与 `--broker-tag`(头部券商 / 新财富团队)**,返回行带 `categoryList` / `brokerTagList`。② **`--llm-tag` 改为 28 项投研业务标签**(强烈推荐、超预期、涨价、龙头等,取值见 `--help`);⚠️ **存量脚本要改**:业绩点评、头部券商、新财富团队改用 `--category earningsReview` / `--broker-tag topBroker` / `--broker-tag newFortune`,传给 `--llm-tag` 报 `100005`。同一选项传多个值取并集。③ `--with-content` 不支持 `--category` / `--broker-tag`(本地报错、不发请求),其 `--llm-tag` 仍只收旧的四个值;要按新标签筛又要正文,用 `list` + `detail`。④ **`bond daily-quote` / `bond valuation` 首行比起始日晚超过 14 天时 stderr 提示**(上市较晚或数据起点较晚;多只同查只看整批最早的首行,逐只起点按 `securityCode` 核对)。⑤ 文档:股东结构类 EDE 指标(`shr_*`),大股东系列须传 `rank`、户均持股系列须传 `shareType`。
16
18
 
17
- - **v0.46.0 — 2026-10-14**:① **`reference securities-search --category bond`**:按代码或简称搜债券,代码用于 `bond` 命令组。⚠️ **可转债可能出现在任何 `--category` 的结果里**(按简称查股票时常排第一),**只取返回行 `category` 等于所查类别的那一行**;债券代码传给 `fund` 命令会返回空结果、不报错。② **场外基金可按名称搜到**(`--category fund` 同时返回 `.OF` 与场内代码)。③ **计费单价按平台最新价目更新**:一页通等 AI 生成 10/次、业绩点评 / 观点 PK 20/次、热点话题 10/篇、个股看点 1/条、路演四件套 10/条、独立观点列表 1/条、纪要 / 外资研报 / 我的会议下载 30/篇、公告下载 A 股 1 / 港美股 2、`edb-data` 30/指标;额度保护随之调整。④ **数据范围**:`SKILL.md` 按官方权限表逐命令列出正式 / 试用两档,规划查询区间按表来。⑤ **报错口径**:EDE 漏传必填的 `fiscalYear` 报 `100001`;`main-business` / `valuation-analysis` 的 `--field` 写错名字报 `100005`;`screener` 计费按筛选前范围保守估算。完整列表见 CHANGELOG。
18
-
19
19
  ### 历史里程碑
20
20
 
21
21
  - **v0.44.0**:新增公募基金 `fund` 命令组 18 个命令(0.4 积分/次),额度保护覆盖显式 `--size`。
@@ -184,6 +184,7 @@ install_skill ~/.hermes/skills # Hermes
184
184
  | | `concept-search` | 题材 ID 搜索(名称/拼音/分组名匹配) |
185
185
  | | `sector-search` | 板块 ID 搜索(返回层级路径) |
186
186
  | | `sector-constituents` | 板块成分股查询 |
187
+ | | `index-weight` | 指数成分股及权重(%)(按指数代码 + 月末交易日;可一次查多个指数;免费) |
187
188
  | **Quote** | `day-kline` | 历史日K线——A股/港股/美股个股 + 沪深 ETF + 交易所/概念/行业指数 + 全球指数,可混查 |
188
189
  | | `day-kline-hk` / `day-kline-us` | ⚠️ 已弃用,能力并入 `day-kline`(接口仍可调,但不校验证券代码) |
189
190
  | | `index-day-kline` | ⚠️ 已弃用,能力并入 `day-kline`(返回字段相同);只收明确的指数代码,`--security all` 会被 CLI 拒绝 |
@@ -232,6 +233,7 @@ install_skill ~/.hermes/skills # Hermes
232
233
  | | `earnings-review` / `earnings-review-check` | 业绩回顾 |
233
234
  | | `theme-tracking` | 主题跟踪 |
234
235
  | | `hot-topic` | 热点话题 |
236
+ | | `expert-intel` | AI 专家情报(从专家会议与纪要提炼的个股情报,按证券 / 研究方向 / 题材 / 内容标签筛;20 积分/条) |
235
237
  | | `research-outline` | 研究提纲 |
236
238
  | | `management-discuss-announcement` | 管理层讨论-财报 |
237
239
  | | `management-discuss-earnings-call` | 管理层讨论-业绩会 |
@@ -247,6 +249,7 @@ install_skill ~/.hermes/skills # Hermes
247
249
  | | `record-list` / `record-download` | 录音速记列表与下载 |
248
250
  | | `my-conference-list` / `my-conference-download` | 我的会议列表与下载 |
249
251
  | | `wechat-message-list` / `wechat-chatroom-list` | 群消息列表与群ID查询 |
252
+ | | `wechat-message-download` | 群消息文件下载(文档 / 图片 / 音频 / 视频消息,按 `msgId`) |
250
253
  | | `stock-pool-list` / `stock-pool-stocks` | 自选股股票池列表与证券明细(`--space-type 2` 查所属租户的股票池) |
251
254
  | | `stock-pool-create` / `stock-pool-rename` / `stock-pool-delete` | 建池 / 改名 / 删池(删池须加 `--yes`) |
252
255
  | | `stock-pool-add-stock` / `stock-pool-remove-stock` | 批量关注 / 批量取消关注个股 |
@@ -319,11 +322,12 @@ gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
319
322
  - **流式下载**:二进制响应(PDF 等)直接 `pipeline` 到磁盘,不经过内存缓冲;不带 `--output` 时先写入临时文件,定好文件名后再改名。50MB PDF 内存占用近乎为零。
320
323
  - **流式输出**:`--format jsonl` 或 `csv` 加 `--output <file>` 时,翻页 / 全市场分片 / 多证券分批请求的行**按到达顺序逐批写盘**,取数阶段不持有整份结果,内存不随行数增长;csv 先落临时行文件、收尾时按列并集写表头再转成 csv(磁盘两遍、内存不变)。jsonl / csv 无论写文件还是输出到终端都按批写出,每行以换行结尾。任一只 / 页 / 片失败,命令退出时后台已无取数与写盘,不留 `.part`。
321
324
  - **导出元信息**:`csv` / `jsonl` 落盘时旁边生成 `<文件>.meta.json`——命令行、数据行数、列名、`complete`(写元信息时的判定:退出 3 即 `false`)、`total` / `partial` / `failedPages` / `failedShards` / `truncatedShards` / `droppedColumns` / `missingFields` / `duplicateRows` / `changedRows` / `totalCapped` 等全部完整性标记(以及不影响完整性判定的 `outOfWindowShards`)、抓取时间与时区、CLI 版本,以及数据文件的字节数 `bytes` 与内容哈希 `sha256`。命令行与结果里的 key / secret / token 类字段写成 `[redacted]`。元信息在数据文件发布之后才就位,导出失败不会留下新数据配旧元信息。**转交或归档前建议核一次**:`shasum -a 256 <文件>` 与元信息里的 `sha256` 相等,才说明这份元信息描述的就是旁边这份数据——两个进程同时导出到**同一个 `--output`** 时,最终文件一定是其中某一次的完整产物,但旁边的元信息有可能来自另一次,核哈希就能发现。**输的那一次自己也会报**:收尾时核对 `--output` 是否仍是本次写出的文件(仍是同一个文件就不必回读,否则回读比对哈希),不符就在 stderr 说明「这个文件不是本次命令的产物」并**退出码 4**。这两种格式的文件本身只有数据行,转交之后靠它核验是否完整;`json` 自带标记,不生成。
322
- - **自动重试**:5xx / 429 / `ECONNREFUSED` / `ECONNRESET` / `ETIMEDOUT` / `ENOTFOUND` / `EAI_AGAIN` / `UND_ERR_*`(undici 连接/超时类)/ `999999` 系统错误自动指数退避重试 2 次。**不重放的端点例外**(贵档:one-pager 等生成/提交类 + `tool file-parse` 提交 + 30/篇 的 summary / foreign-report / my-conference 下载 + 单价未公布但保守同档的 pamirs-summary 下载 + 题材 `concept-info` / `concept-securities`(含 `--full`)+ `ai management-sentiment-detail`;`bond` 全部 13 个命令(多数按次,三个评级命令按条 / 按债券 / 按发行人)、`fund` 全部 18 个命令(按次)与按次计费的 `tool web-search`;按条计费的 `insight highlight list`、观点 `detail` 与 `list --with-content`,以及单次最多 6000 只、按只计费的 `ai stock-summary` 与行数随日期区间增长的 `fundamental earning-forecast`;另加不计分但不可重复执行的 `vault stock-pool-create`、`vault stock-note-add` 与云盘的上传 / 新建文件夹 / 复制 / 两个删除,共 67 个):5xx/超时不重放,仅连接失败、429 与 token 自愈重试。**两类端点各有各的理由**:贵档是**重放会重复扣分**——服务端可能已经执行并计费,重发按次计费的再扣一次,重发按篇/按条计费的会把已交付的行再计一次;不计分的那几个是**重放会造成副作用或把成功报成失败**——股票池名不允许重复,重发一个其实已经建成的请求,回来的是 `230006 股票池名称重复`;笔记没有防重机制,重发一个其实已经写入的新增会多出一条笔记;云盘允许同名,重发上传 / 新建 / 复制会多出一份;重发一个其实已经删掉的删除,回来的是「文件不存在」或 `130002`。**`indicator`(EDE)端点对 `999999` 不重试**——重放一次已计费的查询没有意义(EDE 无数据不用此码,而是保留行列的占位单元格 `null`;代码或参数名写错报 `100003`、缺必填参数报 `100001`)。**终态码 `999011`(凭证无效)/ `140002`(终态失败:异步生成失败、参数错误或业务处理失败)在任何 HTTP 状态下都不重试**——凭证错不会因重试而变,`140002` 立即重发得到的还是同一结果。
325
+ - **自动重试**:5xx / 429 / `ECONNREFUSED` / `ECONNRESET` / `ETIMEDOUT` / `ENOTFOUND` / `EAI_AGAIN` / `UND_ERR_*`(undici 连接/超时类)/ `999999` 系统错误自动指数退避重试 2 次。**不重放的端点例外**(贵档:one-pager 等生成/提交类 + `tool file-parse` 提交 + 30/篇 的 summary / foreign-report / my-conference 下载 + 单价未公布但保守同档的 pamirs-summary 下载 + 题材 `concept-info` / `concept-securities`(含 `--full`)+ `ai management-sentiment-detail`;`bond` 全部 13 个命令(多数按次,三个评级命令按条 / 按债券 / 按发行人)、`fund` 全部 18 个命令(按次)与按次计费的 `tool web-search`;按条计费的 `insight highlight list`、`ai expert-intel`、观点 `detail` 与 `list --with-content`,以及单次最多 6000 只、按只计费的 `ai stock-summary` 与行数随日期区间增长的 `fundamental earning-forecast`;另加不计分但不可重复执行的 `vault stock-pool-create`、`vault stock-note-add` 与云盘的上传 / 新建文件夹 / 复制 / 两个删除,共 68 个):5xx/超时不重放,仅连接失败、429 与 token 自愈重试。**两类端点各有各的理由**:贵档是**重放会重复扣分**——服务端可能已经执行并计费,重发按次计费的再扣一次,重发按篇/按条计费的会把已交付的行再计一次;不计分的那几个是**重放会造成副作用或把成功报成失败**——股票池名不允许重复,重发一个其实已经建成的请求,回来的是 `230006 股票池名称重复`;笔记没有防重机制,重发一个其实已经写入的新增会多出一条笔记;云盘允许同名,重发上传 / 新建 / 复制会多出一份;重发一个其实已经删掉的删除,回来的是「文件不存在」或 `130002`。**`indicator`(EDE)端点对 `999999` 不重试**——重放一次已计费的查询没有意义(EDE 无数据不用此码,而是保留行列的占位单元格 `null`;代码或参数名写错报 `100003`、缺必填参数报 `100001`)。**终态码 `999011`(凭证无效)/ `140002`(终态失败:异步生成失败、参数错误或业务处理失败)在任何 HTTP 状态下都不重试**——凭证错不会因重试而变,`140002` 立即重发得到的还是同一结果。
323
326
 
324
327
  <!-- no-replay-endpoints
325
328
  上面那句点名的「不重放」端点,完整清单如下(endpoint key,与 `gangtise raw list` 一致):
326
329
  ai.earnings-review.get-id
330
+ ai.expert-intel.list
327
331
  ai.hot-topic
328
332
  ai.investment-logic
329
333
  ai.knowledge-batch
@@ -429,10 +433,11 @@ vault.stock-pool.create
429
433
  - `ai hot-topic`
430
434
  - `ai management-sentiment-indicator`
431
435
  - `ai management-sentiment-conclusion`
436
+ - `ai expert-intel`
432
437
 
433
438
  规则:
434
439
  - **省略 `--size` 一律拉全量**(无论是否传时间范围),CLI 自动翻页查完
435
- - **按条计费的列表有额度保护**:省略 `--size` 时,CLI 先拿到 `total`,按 `total × 单价` 估算全量要花的积分,超过 1000 积分就报错、退出码 1,不再往下拉,报错写明估算值。整页不超过 50 积分的列表用第一页拿 `total`;整页更贵的(路演 / 调研 / 策略会 / 论坛、会议线索、个股线索、热点话题、管理层情绪指标 / 结论、`--with-content`)先只取 1 条:结果最多 1 条时它就是全部结果;否则放行后从头翻页,这 1 条会多计一次费(知道要多少条就直接传 `--size N`,不走这一步)。确认要全量就加 `--yes`,只要一部分就传 `--size N`——显式 `--size` 按 `min(--size, total) × 单价` 估算仍超过 1000 积分时同样报错(`--size 100000` 不能当「全量」绕过),要 `--yes`。`fundamental earning-forecast` 不分页,按日期区间估算(工作日数 × 3 条 × 0.5),同一条线。免费列表不受影响
440
+ - **按条计费的列表有额度保护**:省略 `--size` 时,CLI 先拿到 `total`,按 `total × 单价` 估算全量要花的积分,超过 1000 积分就报错、退出码 1,不再往下拉,报错写明估算值。整页不超过 50 积分的列表用第一页拿 `total`;整页更贵的(路演 / 调研 / 策略会 / 论坛、会议线索、个股线索、热点话题、管理层情绪指标 / 结论、AI 专家情报、`--with-content`)先只取 1 条:结果最多 1 条时它就是全部结果;否则放行后从头翻页,这 1 条会多计一次费(知道要多少条就直接传 `--size N`,不走这一步)。确认要全量就加 `--yes`,只要一部分就传 `--size N`——显式 `--size` 按 `min(--size, total) × 单价` 估算仍超过 1000 积分时同样报错(`--size 100000` 不能当「全量」绕过),要 `--yes`。`fundamental earning-forecast` 不分页,按日期区间估算(工作日数 × 3 条 × 0.5),同一条线。免费列表不受影响
436
441
  - 数据量未知时,可先 `--size 1` 从 stderr 的 `Total: N` 探明量级,再决定是否全量
437
442
  - 如果显式传了 `--size`,则按指定值翻页,直到达到 `size` 或数据取完
438
443
  - `--from` 必须是非负整数,`--size` 必须是正整数;非法数字会在本地直接报 `ValidationError`,不会继续请求 API
@@ -454,6 +459,8 @@ vault.stock-pool.create
454
459
 
455
460
  推荐工作流:先 `list` 再 `download`,文件名自动正确且零额外成本。
456
461
 
462
+ `vault wechat-message-download` 不走标题缓存:直接用服务端返回的文件名(一般就是群里发送时的文件名;图片、视频多为一串随机字符),没有时用 `wechat-file-{msgId}`,同名同样自动加 `-1`、`-2`。文件内容原样保存,不做转码。
463
+
457
464
  🔴 **缓存未命中时不会自动回查 list 接口**。回查要拉最近 200 条记录(4 次请求),而这些 list 多数按 **0.1 积分/条**计费,约 20 积分——这笔开销只用于取一个更易读的文件名(下载本身 1–30 积分),所以默认不回查。需要时加 `--resolve-title`:
458
465
 
459
466
  ```bash
@@ -600,6 +607,10 @@ gangtise reference concept-search --keyword jqr # 拼音首字母
600
607
  # 板块:先搜板块 ID,再查成分股(sectorId 必须来自 sector-search)
601
608
  gangtise reference sector-search --keyword 半导体设备 --format json
602
609
  gangtise reference sector-constituents --sector-id 1000001005 --format json
610
+
611
+ # 指数成分股权重(%):日期取月末交易日,可一次查多个指数
612
+ gangtise reference index-weight --index 000300.SH --date 2026-10-30 --format csv --output hs300-weight.csv
613
+ gangtise reference index-weight --index 000300.SH,000905.SH,000852.SH --date 2026-09-30 --format json
603
614
  ```
604
615
 
605
616
  ### Quote
@@ -771,6 +782,9 @@ gangtise ai theme-tracking --theme-id 121000131 --date 2026-03-01 --type morning
771
782
  gangtise ai hot-topic --start-date 2026-03-22 --end-date 2026-03-27 --category morningBriefing --category noonBriefing --with-related-securities --with-close-reading
772
783
  # 不传 --category 默认查全部类型(早报+午报+盘中快报+晚报),--with-related-securities 和 --with-close-reading 默认开启,可用 --no-with-related-securities / --no-with-close-reading 关闭
773
784
  gangtise ai hot-topic --start-date 2026-04-15 --end-date 2026-04-17
785
+ # AI 专家情报:20 积分/条,记得带 --size;--tag 是纯文本内容标签,多个为「任一命中」
786
+ gangtise ai expert-intel --security 300750.SZ --start-time 2026-10-01 --size 10
787
+ gangtise ai expert-intel --keyword 特斯拉 --concept 121000745 --tag 景气上行 --tag 超预期 --size 20
774
788
  gangtise ai research-outline --security-code 600519.SH
775
789
  # 管理层讨论-财报(三个细分维度)
776
790
  gangtise ai management-discuss-announcement --report-date 2025-06-30 --security-code 000001.SZ --dimension businessOperation
@@ -836,6 +850,9 @@ gangtise vault wechat-chatroom-list --room-name "AI学习群,投研分享群" --
836
850
  gangtise vault wechat-message-list --keyword AI应用 --wechat-group-id ueKEGyhdjFGkjyebh --category text --category url --tag roadShow --tag meetingSummary --size 50
837
851
  # 按证券代码过滤群消息
838
852
  gangtise vault wechat-message-list --security 000001.SZ --security 300750.SZ --size 50
853
+ # 群里的文件:先筛文档 / 图片 / 音频 / 视频消息拿 msgId,再按 msgId 下载(text / url 消息没有文件)
854
+ gangtise vault wechat-message-list --wechat-group-id ueKEGyhdjFGkjyebh --category document --category image --category audio --category video --size 50 --format json
855
+ gangtise vault wechat-message-download --msg-id 4784255865508301077
839
856
 
840
857
  # 自选股股票池
841
858
  gangtise vault stock-pool-list
@@ -6,7 +6,7 @@ import { ValidationError } from "../core/errors.js";
6
6
  import { markFailed } from "../core/exitStatus.js";
7
7
  import { parseOutputFormat } from "../core/output.js";
8
8
  import { printData } from "../core/printer.js";
9
- import { emit, withClient, runDownload, multiChoice, field, required, date, list, choiceList, flag, format, output, from, size, startTime, endTime, requestBody, query } from "./shared.js";
9
+ import { emit, withClient, runDownload, multiChoice, field, value, required, date, list, choiceList, flag, format, output, from, size, startTime, endTime, requestBody, query } from "./shared.js";
10
10
  import { checkMarketKeywords } from "./quote.js";
11
11
  export const ai = new Command("ai").description("AI APIs");
12
12
  function addGenerationTask(name, spec) {
@@ -105,6 +105,21 @@ query(ai, "hot-topic", {
105
105
  format("json"), output(),
106
106
  ],
107
107
  });
108
+ query(ai, "expert-intel", {
109
+ description: "AI expert intel: company takeaways distilled from expert meetings and minutes, newest first (20 credits/row)",
110
+ endpoint: "ai.expert-intel.list",
111
+ fields: [
112
+ from(), size("Total rows to return; omit to fetch all (max page 50). Billed per row — bound this on wide ranges"),
113
+ startTime("Publish time from (yyyy-MM-dd or yyyy-MM-dd HH:mm:ss)"), endTime("Publish time to (yyyy-MM-dd or yyyy-MM-dd HH:mm:ss; a bare date covers the whole day)"),
114
+ value("--keyword <text>", "Keyword", "keyword"),
115
+ field(new Option("--search-type <number>", "Where --keyword matches: 1=title 2=title + body (the API default). Titles carry no company name — filter companies with --security").choices(["1", "2"]), (v) => ({ searchType: v === undefined ? undefined : Number(v) })),
116
+ list("--security <code>", "Security code with market suffix, e.g. 300750.SZ (repeatable); intel linked to ANY of them matches. A missing or unknown suffix rejects the call (120001); a real suffix of the wrong market (600519.SZ) is not rejected and matches nothing", "securityList"),
117
+ list("--research-area <id>", "Research area ID: citicIndustry code (1008001xx, reference constant-list). swIndustry (104xx0000), gangtiseIndustry direction (122000xxx) and unknown codes return 0 here", "researchAreaList"),
118
+ list("--concept <id>", "Concept ID (reference concept-search); an unknown ID matches nothing", "conceptList"),
119
+ list("--tag <text>", "Content tag, plain text, e.g. 景气上行 / 超预期 / 重大催化 (repeatable; any of them matches)", "tagList"),
120
+ format("json"), output(),
121
+ ],
122
+ });
108
123
  query(ai, "management-discuss-announcement", {
109
124
  endpoint: "ai.management-discuss-announcement",
110
125
  fields: [
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { value, required, choiceList, top, format, output, query } from "./shared.js";
2
+ import { value, required, requiredList, date, choiceList, top, format, output, query } from "./shared.js";
3
3
  export const reference = new Command("reference").description("Reference data APIs");
4
4
  query(reference, "securities-search", {
5
5
  endpoint: "reference.securities-search",
@@ -34,6 +34,29 @@ query(reference, "sector-constituents", {
34
34
  endpoint: "reference.sector-constituents",
35
35
  fields: [required("--sector-id <id>", "Sector ID from 'reference sector-search'", "sectorId"), format(), output()],
36
36
  });
37
+ function noteMissingIndices(data, requested, tradeDate) {
38
+ const rows = data?.list;
39
+ if (!Array.isArray(rows))
40
+ return;
41
+ const found = new Set(rows.map((row) => String(row?.indexCode).toUpperCase()));
42
+ const missing = requested.filter((code) => !found.has(code.toUpperCase()));
43
+ if (!missing.length)
44
+ return;
45
+ process.stderr.write(`[gangtise] note: no constituent weights for ${missing.join(", ")} on ${tradeDate}. Weights come for the last trading day of each month — another date, like an unknown index code, comes back empty without an error. Check the date, and the code with 'reference securities-search --category index'.\n`);
46
+ }
47
+ query(reference, "index-weight", {
48
+ description: "Index constituents and their weights (%) on the last trading day of a month (free)",
49
+ endpoint: "reference.index-weight",
50
+ fields: [
51
+ requiredList("--index <code>", "Index code, e.g. 000300.SH / 000905.SH / 399006.SZ (repeat or comma-separate)", "indexCodeList"),
52
+ date("--date <date>", "Trading date (yyyy-MM-dd): the last trading day of a month, e.g. 2026-10-30; any other date returns no rows", "tradeDate", { required: true }),
53
+ format(), output(),
54
+ ],
55
+ shape: async (data, _client, options) => {
56
+ noteMissingIndices(data, options.index, options.date);
57
+ return data;
58
+ },
59
+ });
37
60
  query(reference, "chiefs-search", {
38
61
  endpoint: "reference.chiefs-search",
39
62
  fields: [required("--keyword <text>", "Search keyword (chief name / institution / team)", "keyword"), top(10), format(), output()],
@@ -150,11 +150,12 @@ query(vault, "wechat-message-list", {
150
150
  list("--security <code>", "Security code (e.g. 000001.SZ)", "securityList"),
151
151
  list("--wechat-group-id <id>", "WeChat group ID", "wechatGroupIdList"),
152
152
  list("--industry <id>", "Industry ID -- citicIndustry codes (1008001xx) only; swIndustry codes and unknown values are rejected with 100005", "industryIdList"),
153
- list("--category <name>", "Message type: text/image/documents/url", "categoryList"),
153
+ list("--category <name>", "Message type: text/image/document/url/audio/video; any other value is rejected with 100005", "categoryList"),
154
154
  list("--tag <name>", "Tag: roadShow/research/strategyMeeting/meetingSummary/industryComment/companyComment/earningsReview", "tagList"),
155
155
  format(), output(),
156
156
  ],
157
157
  });
158
+ addDownloadCommand(vault, { endpointKey: "vault.wechat-message.download", name: "wechat-message-download", idOption: "--msg-id", idField: "msgId", fallbackPrefix: "wechat-file" });
158
159
  query(vault, "wechat-chatroom-list", {
159
160
  endpoint: "vault.wechat-chatroom.list",
160
161
  fields: [
@@ -621,7 +621,8 @@ export class GangtiseClient {
621
621
  }
622
622
  const contentType = Array.isArray(response.headers['content-type']) ? response.headers['content-type'][0] : response.headers['content-type'];
623
623
  const retryAfterMs = parseRetryAfterMs(response.headers['retry-after'], Date.now());
624
- if (contentType?.includes('application/json')) {
624
+ const rawFile = endpoint.fileOnSuccess === true && response.statusCode < 300;
625
+ if (!rawFile && contentType?.includes('application/json')) {
625
626
  const text = await response.body.text();
626
627
  logTiming(`${endpoint.method} ${endpoint.path} (json)`, Date.now() - startedAt, `${response.statusCode}, ${text.length}B`);
627
628
  let parsed;
@@ -650,7 +651,7 @@ export class GangtiseClient {
650
651
  }
651
652
  return { text: JSON.stringify(data, null, 2), contentType };
652
653
  }
653
- if (contentType?.includes('text/plain') || contentType?.includes('text/html')) {
654
+ if (!rawFile && (contentType?.includes('text/plain') || contentType?.includes('text/html'))) {
654
655
  const text = await response.body.text();
655
656
  logTiming(`${endpoint.method} ${endpoint.path} (text)`, Date.now() - startedAt, `${response.statusCode}, ${text.length}B`);
656
657
  if (response.statusCode >= 400) {
@@ -390,6 +390,13 @@ const ENDPOINT_DEFS = {
390
390
  kind: "json",
391
391
  description: "List constituent securities of a sector",
392
392
  },
393
+ "reference.index-weight": {
394
+ method: "POST",
395
+ path: "/application/open-quote/index/constituent-weight",
396
+ kind: "json",
397
+ description: "List index constituents with their weights (%) on one trading date",
398
+ expects: "list",
399
+ },
393
400
  "quote.day-kline": {
394
401
  method: "POST",
395
402
  path: "/application/open-quote/kline/daily",
@@ -922,6 +929,18 @@ const ENDPOINT_DEFS = {
922
929
  pagination: { enabled: true, maxPageSize: 20 },
923
930
  retry: "no-replay",
924
931
  },
932
+ "ai.expert-intel.list": {
933
+ method: "POST",
934
+ path: "/application/open-insight/expertIntel/getList",
935
+ kind: "json",
936
+ description: "List AI expert intel (takeaways distilled from expert meetings and minutes)",
937
+ billing: { per: "row", price: 20 },
938
+ pagination: { enabled: true, maxPageSize: 50 },
939
+ rowId: "intelId",
940
+ rowIdUnverified: true,
941
+ retry: "no-replay",
942
+ expects: "list",
943
+ },
925
944
  "ai.management-discuss-announcement": {
926
945
  method: "POST",
927
946
  path: "/application/open-ai/management-discuss/from-announcement",
@@ -1103,6 +1122,13 @@ const ENDPOINT_DEFS = {
1103
1122
  pagination: { enabled: true, maxPageSize: 50, maxWindow: 10000 },
1104
1123
  rowId: "msgId",
1105
1124
  },
1125
+ "vault.wechat-message.download": {
1126
+ method: "GET",
1127
+ path: "/application/open-vault/wechatgroupmsg/download/file",
1128
+ kind: "download",
1129
+ description: "Download the file of a WeChat group message (document / image / audio / video)",
1130
+ fileOnSuccess: true,
1131
+ },
1106
1132
  "vault.wechat-chatroom.list": {
1107
1133
  method: "POST",
1108
1134
  path: "/application/open-vault/wechatgroupmsg/chatroomId",
@@ -55,9 +55,9 @@ const ERROR_HINTS = {
55
55
  "120001": "用 `gangtise reference securities-search` 确认代码与后缀(如 600519.SH / 00700.HK)。",
56
56
  "130001": "未找到数据——先核对查询条件;EDE 指标端点此码也可能是未开通该指标权限,仍失败联系客户经理。",
57
57
  "130002": "确认 ID 有效且本账号可见(云盘的文件 / 文件夹 ID 用 `vault drive-folder-list` 核对,笔记 ID 用 `vault stock-note-list` 核对;删除类命令收到此码可能是目标已被删掉);下载类还需检查 --file-type 取值是否合法。",
58
- "130003": "资源未生成或该条记录未附带文件——换一条有附件的记录(列表里 hasAttachment/hasFile 为 true 的),或稍后再试。",
58
+ "130003": "资源未生成或该条记录未附带文件——换一条有附件的记录(列表里 hasAttachment/hasFile 为 true 的),或稍后再试;`vault wechat-message-download` 收到此码是消息不存在、本账号无权访问或文件已不可用,重试不会变。",
59
59
  "130004": "下载 ID 需为数字,检查该命令的 --*-id 参数是否传对。",
60
- "130005": "对照命令 --help 检查 --file-type / --content-type 取值。",
60
+ "130005": "对照命令 --help 检查 --file-type / --content-type 取值;`vault wechat-message-download` 收到此码是该消息为 text / url、没有文件——只有 document / image / audio / video 消息可下载。",
61
61
  "140001": "稍后用对应 *-check 命令查询。",
62
62
  "140002": "终态失败,立即重试同一请求不会变。msg 指向参数(EDE 的指标参数名/枚举以 indicator search 的 parameterList 为准)就改参数重新提交;msg 是「业务处理失败」则与参数无关,稍后再试,持续出现请带 trace 报障。",
63
63
  "210001": "换一篇,或改用 list 取正文摘要。",
@@ -3,6 +3,7 @@ import { normalizeRows } from "./normalize.js";
3
3
  import { PAGE_CONCURRENCY, runWithConcurrency } from "./transport.js";
4
4
  const PRICE_TOLERANCE = 0.0005;
5
5
  const agrees = (close, price) => price > 0 && Math.abs(close - price) / price <= PRICE_TOLERANCE;
6
+ const CHANGE_TOLERANCE = 0.005;
6
7
  const QUOTABLE = /^(\d{6}\.(SH|SZ|BJ)|\d{5}\.HK|[A-Z][A-Z0-9.]*\.(O|N|A))$/;
7
8
  const QUOTE_BATCH = 500;
8
9
  const CLOSES_WINDOW_DAYS = 10;
@@ -210,11 +211,30 @@ export async function fillComponentCodes(rows, lookup) {
210
211
  }
211
212
  }
212
213
  }
214
+ for (const { own, etf } of etfs.values()) {
215
+ for (const row of own) {
216
+ const change = row.pctChange;
217
+ if (codes.has(row) || typeof change !== "number" || typeof row.close !== "number")
218
+ continue;
219
+ const close = row.close;
220
+ const pool = candidatesOf(row).filter((c) => !etf.used.has(c.code));
221
+ if (!pool.length || !pool.every((c) => isQuotable(c) && history.has(c.code)))
222
+ continue;
223
+ const atClose = (c) => history.get(c.code).filter(([, price]) => agrees(close, price));
224
+ const hit = pool.filter((c) => atClose(c).some(([, , moved]) => moved !== undefined && Math.abs(moved - change) <= CHANGE_TOLERANCE));
225
+ const unknown = pool.some((c) => !hit.includes(c) && atClose(c).some(([, , moved]) => moved === undefined));
226
+ if (!hit.length || unknown || marketsOf(hit).size > 1)
227
+ continue;
228
+ const code = narrow(hit, etf);
229
+ if (code)
230
+ place(row, code, etf);
231
+ }
232
+ }
213
233
  for (const { own, etf } of etfs.values()) {
214
234
  const markets = new Set([...etf.used].map(market));
215
235
  let undecided = own.some((r) => failed.has(r.componentName));
216
236
  for (const r of own) {
217
- if (codes.get(r) || tentative.has(r))
237
+ if (codes.get(r))
218
238
  continue;
219
239
  const held = marketsOf(candidatesOf(r).filter((c) => !etf.used.has(c.code) && (typeof r.close !== "number" || mayBe(r, c))));
220
240
  if (held.size > 1)
@@ -329,14 +349,14 @@ export function clientLookup(client) {
329
349
  return Array.isArray(data?.list) ? data.list : [];
330
350
  },
331
351
  async closes(codes, startDate, endDate) {
332
- const data = normalizeRows(await client.call("quote.day-kline", { securityList: codes, startDate, endDate, fieldList: ["securityCode", "tradeDate", "close"], limit: 10_000 }));
352
+ const data = normalizeRows(await client.call("quote.day-kline", { securityList: codes, startDate, endDate, fieldList: ["securityCode", "tradeDate", "close", "preClose"], limit: 10_000 }));
333
353
  const list = Array.isArray(data) ? data : (data?.list ?? []);
334
354
  const out = new Map();
335
355
  for (const k of list) {
336
356
  if (typeof k.securityCode !== "string" || typeof k.tradeDate !== "string" || typeof k.close !== "number")
337
357
  continue;
338
358
  const series = out.get(k.securityCode) ?? [];
339
- series.push([k.tradeDate, k.close]);
359
+ series.push(typeof k.preClose === "number" && k.preClose > 0 ? [k.tradeDate, k.close, (k.close / k.preClose - 1) * 100] : [k.tradeDate, k.close]);
340
360
  out.set(k.securityCode, series);
341
361
  }
342
362
  for (const series of out.values())
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: gangtise-openapi
3
- version: "0.50.0"
3
+ version: "0.51.0"
4
4
  description: |-
5
5
  通过 gangtise CLI 直接调用 Gangtise OpenAPI,拉取投研原始数据、批量导出、下载文件、调用 AI 能力。
6
6
 
7
7
  **触发词**:Gangtise / 冈底斯 / 岗底斯 / gtIC(Gangtise 语音误识别)/ 调接口 / CLI / openapi / 导出 / 下载研报 / 批量查 / 拉数据 / 跑一下 / 研报 / 纪要 / 公告 / K线 / 财报 / 估值 / 选股 / 债券 / 基金 / ETF / 自选股 / 股票池 / 个股笔记
8
8
 
9
- **适用**:原始数据导出、批量 jsonl/csv、下载 PDF/MD、行情 K 线、财务报表、估值指标、证券级数据指标(EDE 截面/时序/条件选股)、财报日历(业绩预告/快报/公告)、会议线索、帕米尔专家纪要、资金流向、题材与板块、债券(资料/行情/估值/评级/公告/违约)、公募基金(资料/净值/费率/经理/规模/持有人/持仓与配置/ETF 申赎)、联网搜索、PDF 解析为 Markdown、AI 能力(一页通/投资逻辑/同业对比/个股看点·投研总结/投研线索/业绩点评/观点PK·多空辩论/主题跟踪/热点话题/管理层讨论/管理层情绪/调研提纲/知识库搜索)、云盘文件管理与股票池、个股笔记(Vault)
9
+ **适用**:原始数据导出、批量 jsonl/csv、下载 PDF/MD、行情 K 线、财务报表、估值指标、证券级数据指标(EDE 截面/时序/条件选股)、财报日历(业绩预告/快报/公告)、会议线索、帕米尔专家纪要、资金流向、题材与板块、指数成分权重、债券(资料/行情/估值/评级/公告/违约)、公募基金(资料/净值/费率/经理/规模/持有人/持仓与配置/ETF 申赎)、联网搜索、PDF 解析为 Markdown、AI 能力(一页通/投资逻辑/同业对比/个股看点·投研总结/投研线索/AI 专家情报/业绩点评/观点PK·多空辩论/主题跟踪/热点话题/管理层讨论/管理层情绪/调研提纲/知识库搜索)、云盘文件管理、群消息与群文件下载、股票池、个股笔记(Vault)
10
10
 
11
11
  **不适用**:不脱离 OpenAPI 自行撰写研报、编造投研结论或做自由问答——观点总结、多空 PK 等 AI 产物本 skill 只经由 Gangtise 平台 AI 接口获取,不自行生成
12
12
 
@@ -36,7 +36,7 @@ description: |-
36
36
  - K 线全市场关键字(`aShares` / `hkStocks` / `usStocks`;旧命令 `all`)跨日期 → 自动按日切片并合并,粒度按各市场单日行数定(A 1 个工作日 / 港 2 个工作日 / 美 1 个工作日)
37
37
  - 5xx / `429` / 网络错误 / `999999` → 自动指数退避重试(🔴 贵档端点例外:仅连接失败 / 429 / token 自愈重试,5xx/超时不重放防重复扣分;`indicator` 端点对 `999999` 不重试)
38
38
  - Token 失效 → 自动换用已刷新的 token 或重新登录,再重发;凭证错 `999011` → **不重试**(AK/SK 不对不会自己好),查环境变量
39
- 8. **参数命名差异**:`--security-code` 只用于 **Fundamental 全组、AI 单证券生成类**(`one-pager` / `investment-logic` / `peer-comparison` / `earnings-review` / `research-outline` / `management-discuss-*`)**与 `insight qa list`**;`ai security-clue` 用 `--gts-code`;`fund manager-info` 按人名查、用 `--manager`;其余(Insight 其他命令、Quote、Vault、Bond、Fund、Indicator、`ai stock-summary`、`ai management-sentiment-indicator` / `-conclusion`)一律用 `--security`。
39
+ 8. **参数命名差异**:`--security-code` 只用于 **Fundamental 全组、AI 单证券生成类**(`one-pager` / `investment-logic` / `peer-comparison` / `earnings-review` / `research-outline` / `management-discuss-*`)**与 `insight qa list`**;`ai security-clue` 用 `--gts-code`;`fund manager-info` 按人名查、用 `--manager`;其余(Insight 其他命令、Quote、Vault、Bond、Fund、Indicator、`ai stock-summary`、`ai management-sentiment-indicator` / `-conclusion`、`ai expert-intel`)一律用 `--security`;`reference index-weight` 的指数代码用 `--index`。
40
40
  9. **调试**:`--verbose` 或 `GANGTISE_VERBOSE=1` 打印每个请求的耗时/字节数到 stderr。
41
41
  10. **`--field` 字段名必须核对,不确定就别传**(返回全量最稳)。上游对不存在的字段名:`quote` 系(realtime / day-kline / minute-kline / fund-flow)名和值一起丢、不报错——CLI 比对请求与返回的列名,缺列标 `partial` + `missingFields` 并退出 3;`fundamental main-business` / `valuation-analysis`、`quote sector-fund-flow` 报 `100005`、`bond` / `fund` 报 `100003`,都会点名写错的名字。CLI 另检查每行的值个数与字段数,对不上直接报错退出 1,报障时带上报错末尾的 `(trace …)`。多只证券或全市场时,缺的身份列 CLI 会补到最前(日 K 补 `securityCode` / `tradeDate`、分钟 K 补 `securityCode` / `tradeTime`、realtime 补 `securityCode`);单只不补。realtime **无 `close`**(用 `latestPrice`)、**无市值**(总市值走 `indicator cross-section --indicator qte_mkt_cptl`,A/港/美股均有数)。
42
42
  11. 🔴 **EDE(`indicator` 截面 / 时序 / 选股)取不到数返 `null` 占位、行列都保留、退出码 0**;代码写错才报 `100003` 并指名。报告期类指标(`is_*` 等)的日期一律落**报告期末**(`03-31` / `06-30` / `09-30` / `12-31`),截面用 `--indicator-param "<指标code>:reportDate=YYYY-MM-DD"`(`screener` 用 `"F1:reportDate=..."`)——日期不在报告期末时整批 `null`,`screener` 筛出空集是**日期用错,不是没有符合条件的标的**。时序与交易日类指标混查、或显式传 `ND` / `TD` / `WD` 时,报告期类指标只有报告期末那几行是真值,**别对整列直接求均值 / 求和**。**`--calendar-type` 默认别传**(服务端按指标定日期轴:行情类给交易日、报告期类给报告期、混查给两者并集——单独查报告期类指标时区间要含报告期末,否则返回空结果;显式传 `TD` 时报告期类指标落在非交易日的报告期末那几期整期缺失、不报错,其余几期照常有值,看着像正常数据;一致预期 `frcst_*` 要节假日也有值的逐日序列才传 `ND`)。详见 `references/commands/indicator.md`。
@@ -67,7 +67,7 @@ description: |-
67
67
  - 公司名 → 先速查表,否则 `reference securities-search`
68
68
  - opaque ID → 先 `references/lookup-ids.md`
69
69
  - 模糊时间词 → 查"时间词映射"
70
- - 列表类命令用户没要求全量 → 按单价主动加 `--size` 兜底(不必问):免费或 0.1 积分/条的列表用 `--size 200`;**≥1 积分/条的(观点、独立观点、路演四件套、会议线索、个股线索、热点话题、管理层情绪等)用 `--size 20`**,要更多先 `--size 1` 看 stderr 的 `Total` 估总价再定。CLI 省略 `--size` 会拉全量;按条计费的列表估算全量超过 1000 积分时报错退出(报错里有估算积分),此时把估算积分告诉用户,确认后加 `--yes` 重跑或改传较小的 `--size N`。**显式 `--size` 本身估算超过 1000 积分也同样拦截**(别用 `--size 100000` 当「全量」绕过),`fundamental earning-forecast` 按日期区间估算、同一条线
70
+ - 列表类命令用户没要求全量 → 按单价主动加 `--size` 兜底(不必问):免费或 0.1 积分/条的列表用 `--size 200`;**≥1 积分/条的(观点、独立观点、路演四件套、会议线索、个股线索、热点话题、管理层情绪、AI 专家情报等)用 `--size 20`**,要更多先 `--size 1` 看 stderr 的 `Total` 估总价再定。CLI 省略 `--size` 会拉全量;按条计费的列表估算全量超过 1000 积分时报错退出(报错里有估算积分),此时把估算积分告诉用户,确认后加 `--yes` 重跑或改传较小的 `--size N`。**显式 `--size` 本身估算超过 1000 积分也同样拦截**(别用 `--size 100000` 当「全量」绕过),`fundamental earning-forecast` 按日期区间估算、同一条线
71
71
  - 预估结果 >200 行 → 别全量 `--format json` 引进上下文,改 `--format jsonl --output <file>` 落盘(行边取边写、内存不随行数增长,stdout 只回显文件路径),再 `wc -l` + `head` 采样呈现。落盘的 `csv` / `jsonl` 旁边会有 `<file>.meta.json`:`complete` / `rows` / `result.partial` 与缺失项标记都在里面,转交文件时一并给、核验完整性先看它(`complete: false` = 那次导出退出码 3)
72
72
  - 路由到 AI 同步生成命令 → 同步生成类(`one-pager` / `investment-logic` / `peer-comparison` / `research-outline` / `theme-tracking` / `management-discuss-*`)CLI 已内置 120s 超时下限,无需前缀;`stock-summary` 同样有 120s 下限;`hot-topic` 仍建议前置 `GANGTISE_TIMEOUT_MS=120000`。**贵档端点超时/5xx 不自动重试**(重放=重复扣分)——超时报错后内容可能已在服务端生成并扣费,同参数再调仍会**再扣一次**(无缓存豁免),所以一次调用给足超时比失败重跑省钱。`earnings-review` / `viewpoint-debate` 是异步(`--wait` 或 `*-check` 轮询),不吃这个超时
73
73
  - "AI速记/智能摘要/会议纪要"→`summary`、"原始文件/原文件"→`original`、"语音识别/转写文本/ASR"→`asr` — 用户已明示时直接映射 content-type,不必问
@@ -84,17 +84,19 @@ description: |-
84
84
  - **0.4 的 `fund` 系**:`fund` 全部命令 **0.4/次**(按次,与返回行数、基金只数无关)——多只基金合并成一次调用最省
85
85
  - **`tool web-search` 1/次**(按次,与返回条数、是否带 `--include-content` 无关;零结果与报错不扣)
86
86
  - 🔴 **`insight highlight list` 5/条**——**按返回条数计**,`--size 20` 的一页 = 100 积分。省略 `--size` 时 CLI 先估算,超过 1000 积分(约 200 条)报错退出,要全量须加 `--yes`
87
+ - 🔴 **`ai expert-intel` 20/条**——**按返回条数计**,`--size 20` = 400 积分,一整页(50 条)= 1000 积分。省略 `--size` 时 CLI 先取 1 条拿总数再估算,超过 1000 积分(50 条)报错退出,要全量须加 `--yes`;先用 `--security` / `--tag` / 时间收窄
87
88
  - **按页**:`tool file-parse` 0.8/页,**提交(`--file`)时按实际页数一次性扣**,取结果(`file-parse-check`)免费——50 页 PDF = 40 积分,别重复提交同一文件
88
89
  - 🔴 **按次**:`ai knowledge-batch` 10、`management-discuss-earnings-call` 10、`management-discuss-announcement` 5、`management-sentiment-detail` 10;AI Agent `one-pager` / `investment-logic` / `peer-comparison` / `research-outline` / `theme-tracking` **10/次**,`earnings-review` / `viewpoint-debate` **20/次**
89
90
  - 🔴 **`ai hot-topic` 10/篇,按返回条数计**(不是按调用次数)。📌 **一「篇」= 一整份报告**(一份早报 / 午报 / 盘中快报 / 晚报),**不是报告里的一条话题**——一份报告通常包含多条热点话题。所以 `--size 20` 的一页 = 最多 20 份报告 = 200 积分,**先用 `--start-date`/`--end-date` + `--category` 收窄再拉**,别省略 `--size` 直接全量。**可查的历史范围是前溯 3 个月**(各档相同)——超出范围的日期返回空结果而不是报错,拿到空先想想是不是撞了权限窗口
90
91
  - **题材**:`alternative concept-info` / `concept-securities` **50/次**;🔴 加 `--full`(催化事件 / 重点个股标识 / 纳入理由)走旧版 **500/次**,不需要这几列就别加
91
92
  - ✅ **扣费发生在接口成功返回数据之后**(平台计费规则):没查到内容(空结果)、报错都不扣分——各 download、`ai hot-topic`(10/篇)、`ai stock-summary`(1/条,无看点总结的个股不进返回列表也不计费)、AI 生成类(`one-pager` 等 10~20/次),以及按次计费的 `ai knowledge-batch`、题材、`tool web-search` 都是这样。**所以「先小范围试探再放大」是安全的**——先用窄条件确认能查到东西,再扩范围。⚠️ **「成功返回」按服务端算**:超时报错时服务端可能已经生成并返回了内容(只是客户端没收到),这次已经扣过,同参数重调会再扣一次;异步的 `earnings-review` / `viewpoint-debate` 在提交成功(拿到任务 ID)时就扣,之后生成失败不退。**单价未公布的** `pamirs-summary`(见下)别据此假定
92
93
  - ⚠️ **同参数重复调用不免费**:按次计费的那批无缓存命中豁免(`one-pager` 等生成类重复调用每次扣分,即使秒回缓存内容);**按篇/按条的也一样**——重拉同一批 `hot-topic` 就是按条数再计一次费。生成类与列表结果拿到后自行留存复用,别为「刷新」重调
93
- - ⚠️ **这些端点超时 / 5xx 不自动重放**(共 67 个,完整清单见下方注释块:按次计费的 AI Agent 那批、`ai knowledge-batch` / `management-discuss-*` / `management-sentiment-detail` / `hot-topic`、题材两接口(含 `--full`)、`bond` 与 `fund` 全部命令、`tool web-search`、`tool file-parse` 提交;summary / foreign-report / my-conference 三个 download;按条计费的 `insight highlight list`、观点 `detail` / `list --with-content`、`ai stock-summary` 与 `fundamental earning-forecast`;以及不计分但重放有副作用的 `vault stock-pool-create`、`vault stock-note-add` 与云盘上传 / 新建文件夹 / 复制 / 删除)。仅连接失败、429 与 token 自愈会重试。服务端可能已经执行并计费,重放会重复扣分、多建一份或把成功报成失败——**一次调用给足超时比失败重跑省钱**
94
+ - ⚠️ **这些端点超时 / 5xx 不自动重放**(共 68 个,完整清单见下方注释块:按次计费的 AI Agent 那批、`ai knowledge-batch` / `management-discuss-*` / `management-sentiment-detail` / `hot-topic`、题材两接口(含 `--full`)、`bond` 与 `fund` 全部命令、`tool web-search`、`tool file-parse` 提交;summary / foreign-report / my-conference 三个 download;按条计费的 `insight highlight list`、`ai expert-intel`、观点 `detail` / `list --with-content`、`ai stock-summary` 与 `fundamental earning-forecast`;以及不计分但重放有副作用的 `vault stock-pool-create`、`vault stock-note-add` 与云盘上传 / 新建文件夹 / 复制 / 删除)。仅连接失败、429 与 token 自愈会重试。服务端可能已经执行并计费,重放会重复扣分、多建一份或把成功报成失败——**一次调用给足超时比失败重跑省钱**
94
95
 
95
96
  <!-- no-replay-endpoints
96
97
  上面那句点名的「不重放」端点,完整清单如下(endpoint key,与 `gangtise raw list` 一致):
97
98
  ai.earnings-review.get-id
99
+ ai.expert-intel.list
98
100
  ai.hot-topic
99
101
  ai.investment-logic
100
102
  ai.knowledge-batch
@@ -181,6 +183,7 @@ vault.stock-pool.create
181
183
  | `indicator cross-section` / `time-series` / `screener` | **5 年** | 3 年 |
182
184
  | `indicator search`、`alternative edb-search` / `edb-data` | **不限** | 不限 |
183
185
  | `alternative concept-info` / `concept-securities` | 最新截面 | 最新截面 |
186
+ | `reference index-weight` | 按账号权限(界外报 `110003`);只有月末交易日有数 | 同左 |
184
187
  | `bond daily-quote` / `valuation` / `issuance-plan` | **5 年** | 3 年 |
185
188
  | `bond` 其余命令 | **不限** | 不限 |
186
189
  | `fund` 净值 / 规模 / 持有人 / 资产配置 / 持仓与分布 / `etf-share-change` | **5 年**(两端日期都不传 = 窗口内全部) | 3 年 |
@@ -193,6 +196,7 @@ vault.stock-pool.create
193
196
  | `insight qa` | **1 年** | 1 年 |
194
197
  | `insight pamirs-summary` 帕米尔纪要 | **不限**(需单独购买专家纪要库) | — |
195
198
  | `ai hot-topic` / `security-clue` | **3 个月** | 3 个月 |
199
+ | `ai expert-intel` | 按账号权限(界外报 `110003`) | 同左 |
196
200
  | `ai theme-tracking` | **1 个月** | 1 个月 |
197
201
  | `ai management-discuss-*` | **1 年** | 1 年 |
198
202
  | `ai management-sentiment-indicator` / `-conclusion` | **1 年** | 6 个月 |
@@ -221,7 +225,7 @@ vault.stock-pool.create
221
225
  | `vault record-download` | `--content-type` | `original` 原始文件 / `asr` 语音识别 / `summary` AI 速记 |
222
226
  | `vault my-conference-download` | `--content-type` | `asr` 语音识别 / `summary` AI 速记 |
223
227
 
224
- 省略 `--output` 时 CLI 用本地 title-cache 里的真实标题做文件名(`independent-opinion` 与 `report-image` 的下载不在此列,也没有 `--resolve-title`)——**只读缓存**,命中就零额外调用。缓存由同端点的 `list` 写入,所以「先 `list` 再 `download`」这个正常工作流本来就免费拿到正确文件名。
228
+ 省略 `--output` 时 CLI 用本地 title-cache 里的真实标题做文件名(`independent-opinion`、`report-image` 与 `vault wechat-message-download` 的下载不在此列,也没有 `--resolve-title`;群消息文件按服务端给的文件名保存,内容原样落盘)——**只读缓存**,命中就零额外调用。缓存由同端点的 `list` 写入,所以「先 `list` 再 `download`」这个正常工作流本来就免费拿到正确文件名。
225
229
 
226
230
  🔴 **未命中时默认不回查**,退回服务端文件名或 `<type>-<id>.<ext>`。要回查得显式加 `--resolve-title`——它拉最近 200 条(4 次请求),而这些 list 多数按 **0.1 积分/条**计费,约 20 积分,只用于取一个更易读的文件名(下载本身 1–30)。**批量下载或按 ID 下旧文件**时:要么先跑一次 `list` 把标题灌进缓存,要么直接 `--output ./<名>.<ext>` 自己定名;`--resolve-title` 会把取回的 200 条一并写回缓存,同批后续下载不再重复消耗。
227
231
 
@@ -255,6 +259,7 @@ vault.stock-pool.create
255
259
  | 热点话题 / 早午晚报 | `ai hot-topic` |
256
260
  | 管理层讨论(财报) | `ai management-discuss-announcement` |
257
261
  | 管理层讨论(业绩会) | `ai management-discuss-earnings-call` |
262
+ | AI 专家情报 / 专家会议情报 / 专家怎么看某公司 | `ai expert-intel`(🔴 **20 积分/条**,必须带 `--size`;`--security` / `--research-area` / `--concept` / `--tag` 收窄,`--tag` 是纯文本内容标签如 `景气上行`) |
258
263
  | 管理层情绪 / 业绩会问答是否回避 · 乐观 · 确定 / 情绪较上一场的变化 | `ai management-sentiment-indicator`(三维评分,5/条)/ `ai management-sentiment-conclusion`(结论文本与较上一场的对比,5/条);逐条问答与判断依据 → `ai management-sentiment-detail --source-id <source.sourceId>`(10/次) |
259
264
  | 日 K(历史,A 股 / 港股 / 美股 / 沪深 ETF / 各类指数含全球指数,可混查) | `quote day-kline` |
260
265
  | 沪深京指数日 K / 要指数名称 | `quote day-kline` 逐个传指数代码(**没有一次拿全部指数的写法**,`index-day-kline --security all` 会被 CLI 拒绝);指数名称用 `reference securities-search --keyword <指数代码> --category index`(返回 `gtsName`) |
@@ -303,6 +308,7 @@ vault.stock-pool.create
303
308
  | 录音速记 | `vault record-list / record-download` |
304
309
  | 我的会议(业绩会/策略会/路演内部记录) | `vault my-conference-list / my-conference-download` |
305
310
  | 微信群消息 | `vault wechat-message-list`(先 `vault wechat-chatroom-list` 拿群 ID) |
311
+ | 群里的文件 / 群消息附件(PDF / Excel / 图片 / 录音 / 视频)下载 | `vault wechat-message-list --category document --category image --category audio --category video` 拿 `msgId` → `vault wechat-message-download --msg-id <msgId>`(text / url 消息没有文件,报 `130005`) |
306
312
  | 自选股股票池(查询) | `vault stock-pool-list / stock-pool-stocks`(所属租户的股票池加 `--space-type 2`,两个命令要用同一个值) |
307
313
  | 自选股股票池(增删改,会改动账号数据) | `vault stock-pool-create / stock-pool-rename / stock-pool-add-stock / stock-pool-remove-stock / stock-pool-delete`(删池须加 `--yes`;详见 `references/commands/vault.md`) |
308
314
  | 个股笔记 / 投资笔记(查询) | `vault stock-note-list`(不传筛选即全部;`--security` 或 `--note-id` 二选一) |
@@ -324,6 +330,7 @@ vault.stock-pool.create
324
330
  | 题材 ID 搜索 | `reference concept-search` |
325
331
  | 板块 ID 搜索 | `reference sector-search` |
326
332
  | 板块成分股 | `reference sector-constituents`(前置:`reference sector-search` 拿 `sector-id`) |
333
+ | 指数成分股权重 / 沪深300 / 中证500 成分权重 / 指数权重 | `reference index-weight --index <指数代码> --date <月末交易日>`(免费;🔴 **只有每月最后一个交易日有数**,其他日期返回空、不报错) |
327
334
  | PDF 转 Markdown / 解析文件 / 提取 PDF 正文 | `tool file-parse --file <x.pdf> --wait`(异步,0.8 积分/页,提交时扣;取结果 `tool file-parse-check --task-id`。**平台自有研报/公告优先用各 download 的 `--file-type 2` 直出 Markdown**,别花解析费) |
328
335
 
329
336
  **易混淆消歧**:
@@ -332,10 +339,10 @@ vault.stock-pool.create
332
339
  - 港股代码用在 `insight foreign-opinion --security` 还是 `quote day-kline --security`?前者要"境外"格式(`UBER.N`),后者要 `.HK`
333
340
  - "基金" → `fund` 命令组(资料 / 净值 / 持仓 / ETF 申赎);`quote fund-flow` 是 **A 股个股资金流向**、`quote sector-fund-flow` 是板块资金流向,都与基金无关。ETF 的日 K 与实时行情仍走 `quote day-kline` / `realtime`,ETF 净值、份额与申赎清单走 `fund`
334
341
  - "管理层" → 讨论内容(财报管理层讨论、业绩会要点)走 `ai management-discuss-*`;问答里的态度(是否回避、乐观还是风险、表述是否确定)走 `ai management-sentiment-*`
335
- - "成分股" → 题材深度(分组;重点标记/纳入理由需 `--full`)走 `alternative concept-securities`;板块(行业/概念分类树,纯代码名单)走 `reference sector-constituents`
342
+ - "成分股" → 题材深度(分组;重点标记/纳入理由需 `--full`)走 `alternative concept-securities`;板块(行业/概念分类树,纯代码名单)走 `reference sector-constituents`;要**指数成分权重**走 `reference index-weight`(月末交易日)
336
343
  - **证券指标按任务形态路由,不是搜到 EDE 就一律走 EDE**(细节见 `references/commands/indicator.md`):
337
344
  - 单证券 → 优先 `fundamental` 专用命令(多数免费 / 低价);多证券批量取**已实现**指标 → `indicator`(EDE)一次拉取:同一日期 / 报告期横比用 `cross-section`,区间走势用 `time-series`(不能多指标 × 多证券同时)
338
- - 始终不走 EDE:盈利预测 / 一致预期 → `fundamental earning-forecast`(EDE 的 EPS 是已实现值,**不能冒充预测**);A 股估值历史分位 → `valuation-analysis`;行情与 K 线 → `quote`;行业 / 宏观指标(无证券维度)→ `alternative edb-*`。**例外:总市值只有 EDE 有**——`indicator cross-section --indicator qte_mkt_cptl`(单位「元」,用 `--scale` 缩放)
345
+ - 始终不走 EDE:盈利预测 / 一致预期 → `fundamental earning-forecast`(EDE 的 EPS 是已实现值,**不能冒充预测**);A 股估值历史分位 → `valuation-analysis`(港 / 美股的估值历史分位走 EDE `finc_*_quantile`,逐指标核 `scopeList`);行情与 K 线 → `quote`;行业 / 宏观指标(无证券维度)→ `alternative edb-*`。**例外:总市值只有 EDE 有**——`indicator cross-section --indicator qte_mkt_cptl`(单位「元」,用 `--scale` 缩放)
339
346
  - 取数前 `indicator search --format json` 核三项:`indicatorName` + `description` 语义对、`scopeList` 覆盖全部目标市场、`parameterList` 必填参数可满足;任一不符就回退专用接口,港 / 美股缺专用能力时如实说不支持。「某市场无数据」这类否定结论以当次 `scopeList` + 抽查一行为准
340
347
  - 日期参数**只看 `parameterList` 必填哪个**:`tradeDate` → `--date`,`reportDate` → `--indicator-param "code:reportDate=..."`(多数报告期类要后者,但 `_ttm` 整族要 `tradeDate`);两个都必填(如 `div_cash_yld`)就两个都用 `--indicator-param` 显式给,只给 `reportDate` 时 `--date` 不再注入、会报 `100001`。`parameterList` 要 `fiscalYear` 的(预测类 `frcst_*`、分红类 `div_cash_yr` 等)显式给,漏传报 `100001` 并点名。日频估值(`finc_pe_ttm` / `finc_pb_mrq`)用最新交易日,用报告期末日期会取到陈值;参数名同样以 `parameterList` 为准(复权是 `adjustType`)
341
348
  - 结果**按 `security` 字段取值**,别按请求下标对位(证券的返回顺序不作保证);批量回填加 `--key-by code`
@@ -411,7 +418,7 @@ gangtise reference securities-search --keyword <公司名> --category stock --to
411
418
 
412
419
  🔴 **`--end-time` 写到当天末尾 `23:59:59` 最稳**:A 股公告与 `knowledge-batch` 只写日期时 CLI 按当日 23:59:59 换算;其余列表把时间串原样交给接口,写全时间才不依赖接口对「只有日期」的理解。
413
420
 
414
- 日期参数**按参数名判断、不按命令组**:名字带 `-date` 的(`--start-date` / `--end-date` / `--date` / `--report-date`)收年在前日期(`YYYY-MM-DD` 首选,`YYYY/MM/DD` / `YYYYMMDD` 也收);名字带 `-time` 的(`--start-time` / `--end-time`)收年在前日期 + 可选 ` HH:mm[:ss]`(空格或 `T` 分隔)或 10 / 13 位时间戳(`ai management-sentiment-indicator` / `-conclusion` 写时刻必须带秒,`HH:mm` 报 `110001`)。易错:Insight / Vault 各 list 用 `-time`,**唯独 `insight performance-calendar` 用 `-date`**;AI 组两种都有(`theme-tracking --date`、`hot-topic` / `management-discuss-*` 用 `-date`,`security-clue` / `knowledge-batch` / `management-sentiment-indicator` / `-conclusion` 用 `-time`);`quote minute-kline` 用 `-time`,其余 Quote / Fundamental / Indicator / `bond` / `fund` / `edb-data` 用 `-date`。拿不准看该命令 `--help`。
421
+ 日期参数**按参数名判断、不按命令组**:名字带 `-date` 的(`--start-date` / `--end-date` / `--date` / `--report-date`)收年在前日期(`YYYY-MM-DD` 首选,`YYYY/MM/DD` / `YYYYMMDD` 也收);名字带 `-time` 的(`--start-time` / `--end-time`)收年在前日期 + 可选 ` HH:mm[:ss]`(空格或 `T` 分隔)或 10 / 13 位时间戳(`ai management-sentiment-indicator` / `-conclusion` 写时刻必须带秒,`HH:mm` 报 `110001`)。易错:Insight / Vault 各 list 用 `-time`,**唯独 `insight performance-calendar` 用 `-date`**;AI 组两种都有(`theme-tracking --date`、`hot-topic` / `management-discuss-*` 用 `-date`,`security-clue` / `knowledge-batch` / `management-sentiment-indicator` / `-conclusion` / `expert-intel` 用 `-time`);`quote minute-kline` 用 `-time`,其余 Quote / Fundamental / Indicator / `bond` / `fund` / `edb-data` 与 `reference index-weight` 用 `-date`。拿不准看该命令 `--help`。
415
422
 
416
423
  支持排序切换的 list:opinion / summary / pamirs-summary / research / foreign-report / 三个公告 / foreign-opinion / independent-opinion / official-account。**要最新加 `--rank-type 2`(按 `publishTime` 倒序);要最相关用默认 `--rank-type 1` + `--keyword`**——两者从同一结果集取的是**不同子集**,没有 `--keyword` 时无差异。`--search-type 2`(只有 summary / pamirs-summary / research / foreign-report / 三个公告 / official-account 有)扩大命中总数与 `--rank-type 2` 的候选池,**不改变 `--rank-type 1` 取回的条目**,要相关度不必加。判断这两个参数是否生效的方法见 `references/commands/insight.md` 开头。
417
424
 
@@ -445,14 +452,14 @@ gangtise reference securities-search --keyword <公司名> --category stock --to
445
452
  - 内资观点 / 纪要 / 路演 / 调研 / 策略 / 论坛 / 财报日历(performance-calendar)/ 研报 / 外资研报 / A 股公告 / 港股公告 / 美股公告 / 外资观点 / 独立观点 / 公众号(official-account)/ 投资者问答(qa)/ 研报图表(report-image)→ `references/commands/insight.md`
446
453
  - 行情命令(A 股 / 港股 / 美股 / ETF / 指数日 K、分钟 K、实时行情、资金流向 fund-flow / sector-fund-flow,含全球指数清单) → `references/commands/quote.md`
447
454
  - 三大报表(A 股 / 港股 / 美股)/ 主营 / 估值 / 盈利预测 / 股东 → `references/commands/fundamental.md`
448
- - knowledge-batch / security-clue / 个股看点(stock-summary)/ AI agent / 异步任务 / 主题跟踪 / 热点 / 管理层讨论 / 管理层情绪 → `references/commands/ai.md`
449
- - drive / record / my-conference / wechat / 股票池 / 个股笔记 → `references/commands/vault.md`
455
+ - knowledge-batch / security-clue / 个股看点(stock-summary)/ AI 专家情报(expert-intel)/ AI agent / 异步任务 / 主题跟踪 / 热点 / 管理层讨论 / 管理层情绪 → `references/commands/ai.md`
456
+ - drive / record / my-conference / wechat(含群消息文件下载)/ 股票池 / 个股笔记 → `references/commands/vault.md`
450
457
  - 行业指标数据库(EDB)/ 题材指数画像与成分股(concept-info / concept-securities)→ `references/commands/alternative.md`
451
458
  - 数据指标(EDE:search / cross-section / time-series / screener,证券级指标截面、时序与条件选股)→ `references/commands/indicator.md`
452
459
  - 债券(basic-info / issuer-info / daily-quote / valuation / cash-flow / announcement / issuance-* / rating-overview / rating-change / issuer-rating-change / exercise-notice / default-list)→ `references/commands/bond.md`
453
460
  - 公募基金(basic-info / nav / fee-rate / manager-* / asset-size / holder-structure / top10-holders / asset-allocation / 持仓与分布六个 / etf-pcf-* / etf-share-change)→ `references/commands/fund.md`
454
461
  - PDF 解析(file-parse)/ 联网搜索(web-search)→ `references/commands/tool.md`
455
- - securities-search / chiefs-search(首席 ID)/ institution-search(机构 ID)/ official-account-search(公众号 ID)/ 常量查询(constant-category / constant-list)/ 题材 ID(concept-search)/ 板块(sector-search / sector-constituents)/ lookup 本地表 / 行业别名 / raw call → `references/commands/reference-and-lookup.md`
462
+ - securities-search / chiefs-search(首席 ID)/ institution-search(机构 ID)/ official-account-search(公众号 ID)/ 常量查询(constant-category / constant-list)/ 题材 ID(concept-search)/ 板块(sector-search / sector-constituents)/ 指数成分股权重(index-weight)/ lookup 本地表 / 行业别名 / raw call → `references/commands/reference-and-lookup.md`
456
463
  - 错误码全表 / 不报错的坑 / 退出码 3 与 `screener` 缺列判据 / Troubleshooting → `references/errors.md`
457
464
 
458
465
  跑通流程对照 → `references/examples.md`
@@ -147,6 +147,32 @@ gangtise ai hot-topic [--start-date <date>] [--end-date <date>] [--category <nam
147
147
  - 🔴 **计费 10/篇,按返回条数计**(不是按调用次数)。📌 **一「篇」= 一整份报告**(一份早报 / 午报 / 盘中快报 / 晚报),**不是报告里的一条话题**——一份报告通常包含多条热点话题,`--category` 选的也是报告类型而不是话题。所以一页 20 条 = 20 份报告 = 200 积分:**先用 `--start-date`/`--end-date` + `--category` 把范围收窄,再考虑要不要全量**(省略 `--size` 时 CLI 先取 1 篇拿到总数来估算,超过 1000 积分报错,确认要全量加 `--yes`;结果多于 1 篇时这 1 篇会多计一次,知道要几篇就直接传 `--size`)
148
148
  - **可查的历史范围是前溯 3 个月**(各档相同)。超出范围的日期**返回空结果、不报错**——拿到空先确认是不是撞了本账号的窗口,别当成「那天没有报告」
149
149
 
150
+ ## AI 专家情报 `ai expert-intel`
151
+
152
+ ```bash
153
+ gangtise ai expert-intel [--security <code>...] [--research-area <id>...] [--concept <id>...] [--tag <text>...] [--keyword <text>] [--search-type 1|2] [--start-time <datetime>] [--end-time <datetime>] [--from <n>] [--size <n>] [--yes]
154
+ ```
155
+
156
+ AI 从专家会议、会议纪要等一手信息里提炼的个股情报:一条 = 主体公司 + 核心观点标题 + 内容标签 + 正文,适合追踪产品进展、经营与景气变化。按发布时间倒序。
157
+
158
+ - 🔴 **积分:20/条**(按返回条数计),`--size 20` = 400 积分。省略 `--size` 时 CLI 先取 1 条拿总数估算,超过 1000 积分(50 条)报错退出,确认要全量加 `--yes`;**先用筛选收窄,务必带 `--size`**。超时 / 5xx 不自动重发
159
+ - `--security`:带市场后缀的代码(如 `300750.SZ`),可重复;一条情报关联多只证券时任一命中即返回。不带后缀或后缀不存在(如 `.XX`)报 `120001`;⚠️ **后缀存在但与代码的市场对不上(如 `600519.SZ`)不报错、返回空结果**——拿到空先核对后缀。证券简称先用 `reference securities-search` 换代码
160
+ - `--research-area`:研究方向 ID,**用中信码 `1008001xx`**(`reference constant-list --category citicIndustry`)。⚠️ 申万码 `104xx0000` 与方向码 `122000xxx` 在这里返回空结果、不报错;`--concept`:题材 ID(`reference concept-search`);`--tag`:纯文本内容标签(如 `景气上行` / `超预期` / `重大催化` / `产品进展`)。三者写错的值都按无匹配处理,**返回空结果、不报错**——拿到空先核对 ID 与标签写法
161
+ - 不同筛选之间是「且」,同一筛选的多个取值是「或」
162
+ - `--keyword` + `--search-type`:不传 `--search-type` 时按接口默认的全文检索(标题 + 正文);`1` 只搜标题——**标题不含公司名**,按公司查用 `--security`
163
+ - `--start-time` / `--end-time`:按发布时间筛,`yyyy-MM-dd` 或 `yyyy-MM-dd HH:mm:ss`;只写日期的 `--end-time` 含当天整天。起止颠倒报 `110002`,超出账号可查范围报 `110003`
164
+ - `--from` / `--size`:自动翻页(单页 50)
165
+ - 返回字段:`intelId` / `title` / `mainSecurity{securityCode, securityName}`(标题前缀展示用的主体公司)/ `tagList[]`(纯文本)/ `content`(正文,纯文本)/ `publishTime`(北京时间)/ `securityList[]{securityCode, securityName}`(含主体公司在其他市场的上市主体)/ `researchAreaList[]{researchAreaId, researchAreaName}` / `conceptList[]{conceptId, conceptName}`
166
+ - 未开通该数据库的账号报 `999004`
167
+
168
+ **示例:**
169
+ ```bash
170
+ # 某公司近期的专家情报
171
+ gangtise ai expert-intel --security 300750.SZ --start-time 2026-10-01 --size 10 --format json
172
+ # 题材 + 标签:特斯拉机器人里景气上行或超预期的
173
+ gangtise ai expert-intel --concept 121000745 --tag 景气上行 --tag 超预期 --size 20 --format json
174
+ ```
175
+
150
176
  ## 管理层讨论-财报 `ai management-discuss-announcement`
151
177
 
152
178
  ```bash
@@ -166,7 +166,7 @@ gangtise fund etf-share-change --security <code>... [--start-date <d>] [--end
166
166
  - **`etf-pcf-header` / `etf-pcf-components` 只返回最新一份申购赎回清单**,无日期参数,查不了历史清单。`tradeDate` 是清单对应的交易日(清单盘前发布,可能就是当天)
167
167
  - **`etf-pcf-header`**:申赎允许情况(`允许申购·允许赎回` 这种 `·` 分隔的组合)、最小申赎单位(份)及其净值(元)、单日申购 / 赎回上限(份,无上限为 `null`)、现金差额与预估现金(元,可为负)、现金替代比例上限(%)、`componentCount` 成分记录数
168
168
  - **`etf-pcf-components`**:每个成分一行,按 `serialNumber` 排序:成分代码 `componentCode`、成分名称 `componentName`、收盘价、涨跌幅、市值占比(%)、申购数量(股)、`cashSubstituteFlag`(`允许` / `必须`,中文)、申购 / 赎回现金替代溢价比例(%)、固定替代金额与申购 / 赎回替代金额(元)。宽基 ETF 动辄数百行,多只一起查注意 10000 行上限
169
- - 🔴 **`componentCode` 是 CLI 按名称匹配补上的**(接口只返回名称),带市场后缀(如 `600519.SH` / `00941.HK` / `NVDA.O` / 国债 `019848.SH`)。匹配方式:按名称找证券(先查证券列表,没有再搜索),再用该行的 `close` 核对候选证券的最新价或昨收;核对不上的(清单价格滞后于行情、停牌等),改按清单价格所属那天的收盘价核对(A 股与港股各自定日期)——A+H 型 ETF 里同名的 A 股与 H 股两行据此分开。同名证券在两个市场都有时,实时价对上的一方还要另一市场那只的近期收盘价都对不上才直接采用(清单价格滞后时,另一市场那只的实时价可能碰巧等于该行)。价格定不了时(债券、停牌、除权除息当天、行情查询失败):成分都在同一市场的 ETF 取该市场里名称完全一致的那只,同市场多只时取与 ETF 同一交易所的;两个市场的价格都对得上、或另一市场那只排除不了的行,同样在成分都在同一市场时取该市场那只。**A+H 等跨市场的 ETF,以及还有一行可能在两个市场(同名 A / H 股、或港股名称更长的同一公司)没定下来、或某个名称查询失败的 ETF,这两类行一律为 `null`**,不按名称猜。⚠️「成分都在同一市场」是从其余各行推断的:一只 A+H 型 ETF 若除这一行外没有别的行显出港股,而这一行同名 A / H 的价格又恰好都对得上,会被补成 A 股代码——A+H 型 ETF 用 `componentCode` 前先看港股行是否都有代码
169
+ - 🔴 **`componentCode` 是 CLI 按名称匹配补上的**(接口只返回名称),带市场后缀(如 `600519.SH` / `00941.HK` / `NVDA.O` / 国债 `019848.SH`)。匹配方式:按名称找证券(先查证券列表,没有再搜索),再用该行的 `close` 核对候选证券的最新价或昨收;核对不上的(清单价格滞后于行情、停牌等),改按清单价格所属那天的收盘价核对(A 股与港股各自定日期)——A+H 型 ETF 里同名的 A 股与 H 股两行据此分开。同名证券在两个市场都有时,实时价对上的一方还要另一市场那只的近期收盘价都对不上才直接采用(清单价格滞后时,另一市场那只的实时价可能碰巧等于该行);**两个市场的价格都对得上、或另一市场那只排除不了时,再用该行的 `pctChange` 核对**:哪只证券有一天的收盘价与涨跌幅都和该行相同,就是哪只(同一公司 A / H 股价格碰巧相同的日子,涨跌幅几乎不会也相同)。价格定不了时(债券、停牌、除权除息当天、行情查询失败):成分都在同一市场的 ETF 取该市场里名称完全一致的那只,同市场多只时取与 ETF 同一交易所的。价格与涨跌幅都定不了的(候选里有一只没有近期日 K、或在该收盘价那天算不出涨跌幅、或涨跌幅和哪只都对不上,如除权除息日):另一市场那只的近期收盘价都对不上时按其余行所在的单一市场取,否则为 `null`——这样的行本身就说明 ETF 可能跨市场,不拿其余行替它定。**A+H 等跨市场的 ETF,以及还有一行可能在两个市场(同名 A / H 股、或港股名称更长的同一公司)没定下来、或某个名称查询失败的 ETF,价格定不了的行一律为 `null`**,不按名称猜
170
170
  - **匹配不到的为 `null`**:现金行(如 `申赎现金`)、商品(如 `黄金9999`)、交易所简称与证券名称对不上的(如港股 `港交所`、`中海油`)。stderr 会说明匹配了多少行、列出为 `null` 的行
171
171
  - ⚠️ 成分的 `close` 是清单给出的价格,日期可能早于 `tradeDate` 的前一交易日,一天之内还会更新,同一清单里 A 股与港股的日期也可能不同。要用价格计算,请以 `quote day-kline` / `quote realtime` 为准
172
172
  - 额外请求都免费:下载一次 A 股 / 港股 / 美股证券列表(3 次请求)在本地按名称匹配,列表里没有的名称(债券、被截断的简称、现金行等)才逐个搜索,另加一两次实时行情查询;有实时价格核对不上的行、或同名证券在两个市场都有时(清单价格滞后、停牌、除权除息、A+H 成分等),再加一次日 K 查询。只要接口原始返回时加 `--no-component-code`(不发这些请求,行里没有 `componentCode`)
@@ -89,7 +89,7 @@ gangtise fundamental main-business --security-code <code> [--breakdown <type>] [
89
89
  gangtise fundamental valuation-analysis --security-code <code> --indicator <name> [--start-date <date>] [--end-date <date>] [--limit <n>] [--field <name>] [--skip-null]
90
90
  ```
91
91
 
92
- - **市场与路由**:本命令仅支持 A 股(港股 / 美股会报 `120001`「非有效A股」)。A股单证券估值序列与估值历史分位始终优先本命令;多证券批量取一组已实现估值点值,且 `indicator search` 三项校验都通过时,才优先 EDE `cross-section` / `time-series`。港 / 美股估值历史分位当前 CLI 不支持,不能用普通 EDE 点值冒充
92
+ - **市场与路由**:本命令仅支持 A 股(港股 / 美股会报 `120001`「非有效A股」)。A股单证券估值序列与估值历史分位始终优先本命令;多证券批量取一组已实现估值点值,且 `indicator search` 三项校验都通过时,才优先 EDE `cross-section` / `time-series`。港 / 美股估值历史分位走 EDE 的 `finc_*_quantile`(各指标覆盖的市场以 `scopeList` 为准,见 `indicator.md`),不能用普通 EDE 点值冒充
93
93
  - `--indicator`(**必选**):`peTtm` 滚动PE | `pbMrq` PB | `peg` PEG | `psTtm` 滚动PS | `pcfTtm` 滚动PCF | `em` 企业倍数
94
94
  - `--limit` 默认 2000,省略 `--start-date` 时自动查近一年
95
95
  - 🔴 **序列按自然日逐日一行(含周末)**,行数超过 `--limit` 时接口**保留最近的行、丢掉区间开头**。CLI 撞满即标 `partial`、退出码 3 并在 stderr 说明(首行恰好就是 `--start-date` 时说明没丢,不标)。取长区间把 `--limit` 设到不小于区间天数:取 N 年就设 `--limit` ≥ 366 × N(且不早于账号权限窗口的起点)
@@ -13,13 +13,14 @@
13
13
  | 多证券批量取一组**已实现**财务 / 估值指标 | 先 `indicator search`,通过下方三项校验后用 `cross-section` / `time-series` 一次拉取,避免逐只循环 |
14
14
  | A股盈利预测 / 一致预期(含预测 EPS) | `fundamental earning-forecast`;EDE 搜到的基本 / 稀释 EPS 是已实现值,不能替代预测 |
15
15
  | A股估值历史分位 | `fundamental valuation-analysis` |
16
+ | 港 / 美股估值历史分位 | EDE `finc_*_quantile`(`sDate` 至 `--date` 区间里的分位;各指标覆盖的市场不同,以 `scopeList` 为准,见下方「银行 / 保险 / 券商专项指标与估值分位数」) |
16
17
  | **估值指标的历史序列**(分位 / 回测 / 择时) | 两个接口口径不同、都要交叉核——EDE 按正式财报披露日切换财报口径,`valuation-analysis` 按业绩快报切,见下方专门小节 |
17
18
  | 开高低收 / 成交量等行情与 K 线 | `quote`;免费且支持多证券批量。**换接口不换口径**:`quote` 的 `volume` 与 EDE `qte_vol` 逐位相同(A股 / 港股 / 美股,单位均为股)。EDE 只在 `quote` 不提供的口径上才需要——周 / 月 / 季 / 年 / 区间成交量 |
18
19
  | 单只基金的净值 / 持仓 / 规模 / 经理 | `fund` 命令组;多只基金批量取分类、复权净值与风险收益指标才用 EDE,见下方「基金指标」 |
19
20
  | 单证券资金流向(要占比字段) | `quote fund-flow`;免费,且有 EDE 没有的 `*Ratio` 占比。多证券批量取某一两个档位才用 EDE 的 `flow_*` |
20
21
  | 单证券三大报表全部科目 | 对应 `fundamental` 利润表 / 资产负债表 / 现金流量表命令 |
21
22
 
22
- EDE 不是“搜到就优先”。取数前必须核对:① `indicatorName` + `description` 与目标语义一致;② `scopeList` 覆盖**全部**目标市场和证券类型;③ `parameterList` 的必填参数与枚举可满足。`scopeList` 缺失 / `null` / 空或任一项不符,都视为无法证明覆盖并回退上表的专用接口;专用接口也不支持目标市场时,如实说明当前 CLI 无可用口径,不能用其他语义代替。`valuation-analysis` / `earning-forecast` 仅支持 A 股,港 / 美股的**估值历史分位**与**盈利预测**当前无可用口径。但估值指标本身港股有数:`finc_pe_ttm`(PE TTM) 与 `finc_pb_mrq`(PB MRQ)。⚠️ **本文里所有「仅 A 股」「无数据」这类否定结论都只是某个时点的抽查**——服务端在持续补数据,正面结论过期会给错数,负面结论过期则会让你白白拒掉一个现在能跑的查询(不报错、不告警,只是少调一次)。**一律以当次 `scopeList` + 抽查一行为准。**`search` 免费,EDE 取数按单元格计费;除多证券批量的效率收益外,仍优先免费 / 低价的 `quote` 或 `fundamental`。
23
+ EDE 不是“搜到就优先”。取数前必须核对:① `indicatorName` + `description` 与目标语义一致;② `scopeList` 覆盖**全部**目标市场和证券类型;③ `parameterList` 的必填参数与枚举可满足。`scopeList` 缺失 / `null` / 空或任一项不符,都视为无法证明覆盖并回退上表的专用接口;专用接口也不支持目标市场时,如实说明当前 CLI 无可用口径,不能用其他语义代替。`valuation-analysis` / `earning-forecast` 仅支持 A 股:港 / 美股的**盈利预测**当前无可用口径;**估值历史分位**走 EDE 的 `finc_*_quantile`(逐指标核 `scopeList`,见上表)。估值指标本身港 / 美股也有数:`finc_pe_ttm`(PE TTM,`scopeList` 列 A / 港 / 美)与 `finc_pb_mrq`(PB MRQ,列 A / 港)。⚠️ **本文里所有「仅 A 股」「无数据」这类否定结论都只是某个时点的抽查**——服务端在持续补数据,正面结论过期会给错数,负面结论过期则会让你白白拒掉一个现在能跑的查询(不报错、不告警,只是少调一次)。**一律以当次 `scopeList` + 抽查一行为准。**`search` 免费,EDE 取数按单元格计费;除多证券批量的效率收益外,仍优先免费 / 低价的 `quote` 或 `fundamental`。
23
24
 
24
25
  ## 指标搜索 `indicator search`
25
26
 
@@ -31,7 +32,7 @@ gangtise indicator search --keyword <text> [--limit <n>]
31
32
  - `--limit`:返回条数上限,默认 50,最大 100
32
33
  - 默认 `--format table` 只适合浏览名称;正式路由 / 取数前必须加 `--format json`,才能完成语义、`scopeList`、`parameterList` 三项校验
33
34
  - 返回字段:`indicatorCode` / `indicatorName` / `description`(算法与口径)/ `scopeList`(该指标适用的市场 + 证券类型 + `usageRestriction`)/ `parameterList`(可传的 `--indicator-param` 参数名及枚举)/ `score`
34
- - **市场范围按指标判断**:`scopeList` 会返回实际覆盖范围,且指标之间不同;不能笼统写成每个指标都覆盖 A / 港 / 美股。覆盖面在持续扩,别把抽查结论当常量:例如 `qte_mkt_cptl`/`shr_tot` 覆盖 A/港/美股,`finc_pe_ttm` / `finc_pb_mrq` 覆盖 A/港股,`is_op_rev_ttm`/`is_shnp_ttm` 覆盖 A/港股。目标列表含任一 scope 外证券时,本批 EDE 校验不通过,应回退专用接口
35
+ - **市场范围按指标判断**:`scopeList` 会返回实际覆盖范围,且指标之间不同;不能笼统写成每个指标都覆盖 A / 港 / 美股。覆盖面在持续扩,别把抽查结论当常量:例如 `qte_mkt_cptl` / `shr_tot` / `finc_pe_ttm` / `is_op_rev_ttm` / `is_shnp_ttm` 覆盖 A/港/美股,`finc_pb_mrq` 的 `scopeList` 只列 A/港股。目标列表含任一 scope 外证券时,本批 EDE 校验不通过,应回退专用接口
35
36
  - **`scopeList[].usageRestriction`**:该指标在具体接口上的限制,`null` = 无限制。⚠️ **它是提示不是硬约束**——标着「不支持指标时间序列接口」的 `qte_vol_intvl` 调时序照样返数据、不会被拦下。当成「口径可能不对、结果别当真」看,别指望它会报错
36
37
  - ⚠️ **`scopeList` 是声明不是保证**:它可能**超前于数据**(声明覆盖但该市场暂无数据),也可能**滞后于数据**(已有数据尚未声明)。**「某某仍无数据」这类否定结论过期得和正面结论一样快**,照着它走会白白拒掉一个现在能跑的查询,而且不报错。**判断成本很低**:无数据会保留行列、给一个占位单元格,抽查一行就能看出覆盖情况;code 写错则直接报 `100003`,两种情形不会混淆。占位值统一是 `null`(详见下方「缺数据 vs 代码写错」)
37
38
  - 美股代码用交易所后缀 `.O`(NASDAQ) / `.N`(NYSE) / `.A`(NYSE American,原 AMEX):用 `AAPL.O`,`AAPL.US` 取不到数据
@@ -292,7 +293,7 @@ gangtise indicator cross-section --indicator qte_close --security 600519.SH \
292
293
  | `periodNum` | N 期统计(N 期均值/最值,如 `finc_roe_avg_avg` 平均ROE N期均值) | `--indicator-param "finc_roe_avg_avg:periodNum=4"`;`finc_roe_avg_avg` 属报告期类,还要补 `--indicator-param "finc_roe_avg_avg:reportDate=2025-12-31"`(只给 `--date` 报 `100003`) |
293
294
  | `sDate` | 区间类的**起始日**(如 `qte_vol_intvl` 区间成交量、`qte_avg_vol` 区间日均成交量),格式 `yyyy-MM-dd` | `--indicator-param "qte_vol_intvl:sDate=2024-01-02"`。⚠️ **`sDate` 不能替代 `tradeDate`**——它是区间起点,`tradeDate`(=区间终点)仍是 required,`--date` 会照常下发。区间起始日的参数名就是 `sDate`,写成 `startDate` 会报 `100003 不支持参数 startDate`。⚠️ **不传 `sDate` 不报错**——它是可选参数,缺了就按默认区间算,所以要的是特定区间就必须显式传。另:`qte_amp_mo`(月振幅)等周期变体只吃 `tradeDate`,没有起始日参数 |
294
295
  | `fiscalYear` | 年度/报告期类(如 `div_cash_yr` 年度现金分红)、预测类(如 `frcst_pe`,与 `tradeDate` 同时必填) | `--indicator-param "div_cash_yr:fiscalYear=2025"` |
295
- | `industryType` + `industryLevel` | `scr_indu` 所属行业(两个都 required,缺任一报 `100001`) | `--indicator-param "scr_indu:industryType=1" --indicator-param "scr_indu:industryLevel=0"` |
296
+ | `industryType` + `industryLevel` | `scr_indu` 所属行业(两个都 required,缺任一报 `100001`;⚠️ 预计下线,改用下文的 `scr_indu_citic` / `scr_indu_sw` / `scr_indu_gics`) | `--indicator-param "scr_indu:industryType=1" --indicator-param "scr_indu:industryLevel=0"` |
296
297
 
297
298
  > `paramValue` 一律按**字符串**约定传(`periodNum=4` 内部即 `"4"`,CLI 已处理)。
298
299
 
@@ -339,7 +340,7 @@ gangtise indicator cross-section --indicator mgn_bal --indicator mgn_fin_bal --i
339
340
  # 茅台 2026-08-07:两融 176.7 亿 / 融资 175.4 亿 / 融券 1.3 亿
340
341
  ```
341
342
 
342
- **行业分类 `scr_indu`(所属行业)**——一个指标覆盖四套体系,A/港/美股均支持,返回**字符串**:
343
+ **行业分类 `scr_indu`(所属行业)**——⚠️ **预计下线**:`indicator search` 已搜不到,取数暂时仍可用,新写的取数一律改用下文的**行业组合指标**。一个指标覆盖四套体系,A/港/美股均支持,返回**字符串**:
343
344
 
344
345
  - `industryType`:`1`=申万 `2`=中信 `3`=恒生 `4`=GICS
345
346
  - `industryLevel`:`0`=全路径(用 `-` 连接各级)`1`=一级 `2`=二级 `3`=三级 `4`=四级
@@ -354,11 +355,11 @@ gangtise indicator cross-section --indicator scr_indu \
354
355
 
355
356
  体系与市场要配对:A 股查恒生 / GICS、美股查申万,都返 `null`(如茅台 `industryType=3/4` 均为 `null`)。
356
357
 
357
- **行业组合指标(3 个)**——把体系写进指标编码,省掉 `industryType`:
358
+ **行业组合指标(3 个)**——把体系写进指标编码,省掉 `industryType`;`scr_indu` 下线后行业分类走这三个:
358
359
 
359
360
  | 指标 | 体系 | 参数 |
360
361
  | :-- | :-- | :-- |
361
- | `scr_indu_citic` | 中信行业 | `tradeDate`(必填)+ `industryLevel`(**可选**) |
362
+ | `scr_indu_citic` | 中信行业 | `industryLevel`(**可选**,取值同上;不传为全路径)。`parameterList` 现列为空,但 `--date` 照常传、不会被拒 |
362
363
  | `scr_indu_sw` | 申万行业 | 同上 |
363
364
  | `scr_indu_gics` | GICS 行业 | 同上 |
364
365
 
@@ -367,7 +368,7 @@ gangtise indicator cross-section --indicator scr_indu_citic --indicator scr_indu
367
368
  --security 600519.SH --date 2026-08-13
368
369
  ```
369
370
 
370
- 与 `scr_indu` 的取舍:**只要一套体系就用组合指标**(少一个必填参数,且 `industryLevel` 可省),**要在同一次请求里横比多套体系**才用 `scr_indu`(换 `industryType` 即可,不必记三个编码)。恒生体系没有组合指标,仍走 `scr_indu:industryType=3`。
371
+ 多套体系横比就在同一次请求里列多个组合指标(如上例)。⚠️ **恒生体系没有组合指标**:目前只能走 `scr_indu:industryType=3`,`scr_indu` 下线后 EDE 不再提供恒生行业。
371
372
 
372
373
  **`finc_pb_mrq`(市净率 MRQ)是日频指标**:每个交易日都有数且逐日变动,别按报告期末取(那会拿到几个月前的陈值)。
373
374
 
@@ -416,6 +417,53 @@ gangtise indicator cross-section --indicator qte_vol_ratio --indicator qte_turn_
416
417
  --security 600036.SH --security 600519.SH --date 2026-10-30
417
418
  ```
418
419
 
420
+ ### 银行 / 保险 / 券商专项指标与估值分位数
421
+
422
+ **行业专项财务指标**——`scopeList` 只有 **A 股**,都是报告期类(`reportDate` 必填,`reportType` 可选、默认 `1` 合并报表);**非本行业的公司返回 `null`**。比率类直接是百分数(`0.94` 即 0.94%)。
423
+
424
+ | 族 | 覆盖 | 例 |
425
+ | :-- | :-- | :-- |
426
+ | 银行 `bk_*` | 资本充足率(含 2013 口径 `_2`)与资本净额、存贷款余额与成本 / 收益率、不良贷款率与拨备覆盖率、净息差 / 净利差、流动性比率、非利息收入、客户集中度 | `bk_npl_rti` 不良贷款比率、`bk_npl_prvs_covrg` 拨备覆盖率、`bk_net_int_margin` 净息差 |
427
+ | 保险 `insu_*` | 寿险 / 产险分列(`_li` / `_pci`)的实际资本与偿付能力充足率、产险综合成本率 / 费用率 / 赔付率、退保率、净 / 总投资收益率 | `insu_solv_adeq_rti_li`、`insu_compr_cost_rti_pci` |
428
+ | 券商 `secu_*` | 净资本、净资本 / 净资产、净资本 / 各项风险准备之和 | `secu_net_captl`(另有可选 `currency` / `scale`) |
429
+
430
+ ```bash
431
+ gangtise indicator cross-section --indicator bk_npl_rti --indicator bk_npl_prvs_covrg --indicator bk_captl_adeq_rti_2 \
432
+ --indicator-param "bk_npl_rti:reportDate=2025-12-31" --indicator-param "bk_npl_prvs_covrg:reportDate=2025-12-31" \
433
+ --indicator-param "bk_captl_adeq_rti_2:reportDate=2025-12-31" --security 600036.SH --date 2026-11-06
434
+ # 招商银行 2025 年报:不良贷款比率 0.94 / 拨备覆盖率 391.79 / 资本充足率(2013) 18.24
435
+ ```
436
+
437
+ **估值分位数(5 个 `finc_*_quantile`)**——`finc_pe_ttm_quantile` 市盈率(TTM)、`finc_pb_mrq_quantile` 市净率(MRQ)、`finc_ps_ttm_quantile` 市销率(TTM)、`finc_pcf_ttm_quantile` / `finc_pcf_ncf_ttm_quantile` 市现率(TTM,经营 / 全部现金净流量)。`scopeList`:`finc_pb_mrq_quantile` 列 A / 港股,其余四个列 A / 港 / 美股——按目标市场逐个核,个别证券取不到时为 `null`。返回当前估值在 `sDate` 至 `tradeDate` 区间里的历史分位(%,0–100,越低越便宜);负值估值不参与计算,取不到时为 `null`。
438
+
439
+ - `tradeDate`(即 `--date`)与 **`sDate`(统计区间起点)都必填**,缺 `sDate` 报 `100001`;`quantile` 可选
440
+
441
+ ```bash
442
+ gangtise indicator cross-section --indicator finc_pe_ttm_quantile --indicator-param "finc_pe_ttm_quantile:sDate=2021-11-05" \
443
+ --security 600519.SH --security 00700.HK --date 2026-11-06
444
+ ```
445
+
446
+ **其他新增的常用指标**(参数以 `parameterList` 为准):
447
+
448
+ - **N 年增长率 `*_yoy_n`**(营业收入、净利润、归母净利润、扣非归母净利润、营业利润、利润总额、总资产、股东权益、经营现金流、ROE 等)与 `is_tot_op_rev_cagr` 营业总收入复合增长率:报告期类,`reportDate` + `periodNum`(N 年)都必填
449
+ - **相对年初增长率 `*_yoy_ytd`**(总资产、每股净资产、归母权益):报告期类
450
+ - **单季度**:`is_gr_prft_qtr` 毛利、`is_oth_bus_incm_qtr` 其他业务净收益、`cf_op_cf_indir_qtr` 间接法经营现金流、`cf_exchg_eff_qtr` 汇率变动影响
451
+ - **TTM 与交易日类**:`finc_fcff_ttm` 企业自由现金流、`finc_roic_ttm` 投入资本回报率——用 `tradeDate`(`--date`)
452
+ - **`div_cash_paid_ratio_cum` 累计股利支付率**:`tradeDate` + `periodNum` 都必填
453
+
454
+ ### 预计下线的指标
455
+
456
+ 共 23 个,`indicator search` 已搜不到,取数暂时仍可用,**存量取数尽快迁走**:
457
+
458
+ | 预计下线 | 改用 |
459
+ | :-- | :-- |
460
+ | `scr_indu` 所属行业 | `scr_indu_citic` / `scr_indu_sw` / `scr_indu_gics`(恒生行业暂无替代) |
461
+ | `cdr_conv_ratio` CDR 转换比例 | — |
462
+ | 半年期行情 `qte_*_halfyr`:振幅、涨跌幅、收盘价、最高 / 最低价、前收盘价、换手率与最高 / 最低换手率、成交额、成交量 | 带 `sDate` 的区间指标,`sDate` 取半年前:`qte_amp_intvl` / `qte_chg_pct_intvl` / `qte_high_intvl` / `qte_low_intvl` / `qte_turn_intvl` / `qte_amt_intvl` / `qte_vol_intvl`;收盘价、前收盘价直接用 `quote day-kline` 取对应日 |
463
+ | 周 / 月 / 季 / 半年 / 年均成交额与均成交量 `qte_avg_amt_{wk,mo,qtr,halfyr,yr}` / `qte_avg_vol_{…}` | `qte_avg_amt` 区间日均成交额 / `qte_avg_vol` 区间日均成交量,`sDate` 取对应周期的起点 |
464
+
465
+ 区间指标的 `sDate` 是可选参数,**不传不报错、按默认区间算**——要的是特定区间就必须显式传。
466
+
419
467
  ### 基金指标
420
468
 
421
469
  `--security` 传基金代码(场外 `.OF`,场内 `.SH` / `.SZ`,如 `005827.OF` / `510300.SH`)。
@@ -428,7 +476,7 @@ gangtise indicator cross-section --indicator qte_vol_ratio --indicator qte_turn_
428
476
 
429
477
  - 🔴 **区间指标的其余参数一律显式传**,漏传报 `100001`(`parameterList` 列了默认值也一样):`changePeriod` 变化周期、`yieldType`(`0` 普通 / `1` 对数收益率)、`riskFreeRate`(`0` = 常数 0)、`benchmarkCode` 基准代码(Alpha / Beta / 相关系数 / Jensen / Treynor / 非系统风险要)、`industryLevel`(同类排名按哪一级分类)。每个指标要哪几个以 `parameterList` 为准
430
478
  - ⚠️ **`changePeriod` 列出的默认值 `6`(区间)不是每个指标都收**:Sharpe 等的 `description` 写明只支持日 / 周 / 月 / 年(`0` / `1` / `2` / `5`),传 `6` 报 `100003`
431
- - ⚠️ **`fund_ret_rank` / `fund_ret_rank_pct` 的「同类基金数量」不一定等于所属分类的基金数**:不同分类的基金(如偏股混合型 FOF、偏股混合型、QDII 偏股混合型)在同一 `industryLevel` 下可能拿到几乎相同、接近全部基金数的分母。按同类位置下结论前先核对分母;要在同类里比,用 `fund_cls2_typ` 自己分组后比区间收益(`finc_ann_ret` 等)
479
+ - `fund_ret_rank` / `fund_ret_rank_pct` 的「同类」是 `industryLevel` 指定那一级的 Gangtise 分类:`1` 按 `fund_cls1_typ`、`2` 按 `fund_cls2_typ`,同分类的基金分母相同(如两只偏股混合型基金在 `industryLevel=2` 下同为 `/3098`)
432
480
  - `finc_intvl_max_dd` 返回负的百分数(`-19.23` 即 -19.23%),无回撤为 `0`;`fund_estb_dt` 返回 `yyyyMMdd` 整数(如 `20180905`),不是日期字符串
433
481
  - 这批区间指标的 `scopeList` 标着「不支持指标时间序列接口」,用 `cross-section` 取
434
482
  - 单只基金的净值序列、持仓、规模走 `fund` 命令组;EDE 适合多只基金横向比
@@ -134,6 +134,7 @@ gangtise reference constant-category [--format json]
134
134
  > | `insight forum` | ✅ | **❌ 返 0** | ✅ |
135
135
  > | `vault my-conference-list` | ✅ | **❌ 返 0** | ✅ |
136
136
  > | `insight highlight` | ✅ | **❌ 不可用** | ✅ |
137
+ > | `ai expert-intel` | ✅ | **❌ 返 0** | 返 0(情报按公司归类,未见方向类) |
137
138
  >
138
139
  > 一句话结论:**行业维度一律传中信码**(唯一全端点通吃的一套),方向维度传 `122000xxx`(`pamirs-summary` 不支持方向)。
139
140
 
@@ -212,6 +213,25 @@ gangtise reference sector-constituents --sector-id 2000000014 --format json
212
213
 
213
214
  单个行业也可以直接 `reference securities-search --keyword 申万银行 --category index` → `821047.SWI`。
214
215
 
216
+ ## 指数成分股权重 `reference index-weight`
217
+
218
+ ```bash
219
+ gangtise reference index-weight --index <code>... --date <yyyy-MM-dd>
220
+ ```
221
+
222
+ - 免费。`--index`(**必选**,可重复或逗号分隔):指数代码,如 `000300.SH` 沪深300、`000905.SH` 中证500、`000852.SH` 中证1000、`000016.SH` 上证50、`000688.SH` 科创50、`399006.SZ` 创业板指;不确定用 `reference securities-search --keyword <指数名> --category index`
223
+ - `--date`(**必选**):单个交易日。🔴 **只有每月最后一个交易日有数**(如 `2026-09-30`、`2026-10-30`)——其他交易日、非交易日与写错的指数代码都返回空结果、**不报错**;CLI 在 stderr 点名没取到数据的指数。要「最新」权重就取上个月最后一个交易日
224
+ - 超出账号可查范围报 `110003`
225
+ - 不分页、不限条数:一次返回所选指数当日的全部成分股,多个指数合在同一个 `list` 里,按 `indexCode` 区分
226
+ - 返回 `{total, list}`,`list[]`:`indexCode` / `indexName` / `tradeDate` / `securityCode` / `securityName` / `weight`(**单位 %**,最多四位小数)。同一指数的权重合计约为 100,受舍入影响不严格等于 100,校验合计时留容差
227
+ - 与 `reference sector-constituents` 的区别:后者是板块的纯成分名单、不带权重;要权重(基金归因、指数对标)用本接口
228
+
229
+ **示例:**
230
+ ```bash
231
+ gangtise reference index-weight --index 000300.SH --date 2026-10-30 --format csv --output hs300-weight.csv
232
+ gangtise reference index-weight --index 000300.SH,000905.SH --date 2026-09-30 --format json
233
+ ```
234
+
215
235
  ## Lookup 本地表
216
236
 
217
237
  **按名称找机构 ID 优先用 `reference institution-search`**(服务端搜索、覆盖全部 5 类机构、带 usageScopes);本地表主要用于**全量枚举**券商/会议机构(institution-search 为搜索型:top≤10、非全量):
@@ -83,12 +83,34 @@ gangtise vault wechat-message-list [--keyword <text>] [--security <code>] [--wec
83
83
  - 🔴 **`--industry` 是收窄工具,不是全量召回**:行业标签由服务端标注,**同一条消息可能挂多个行业,也可能一个都没挂**。同一个关键词加上「本行业」过滤后,命中数会明显少于只用关键词——**少掉的既有没打标签的,也有被标到相邻行业去的**(如半导体相关的消息在计算机 / 机械 / 通信下同样查得到)。所以「按行业筛出 N 条」不能读成「该行业只有 N 条」;要尽量全,用 `--keyword` 取回后本地判断,或把相邻行业码一起查再去重
84
84
  - `--wechat-group-id`:先用 `vault wechat-chatroom-list` 查;可重复
85
85
  - 按偏移量**最多取到第 10000 条**(`--from` + 条数不能超过 10000),且 `total` 最多也只报到 10000——正好报 10000 时实际条数可能更多,CLI 按封顶处理:标 `partial` + `totalCapped`、退出码 3。要更多请缩短时间范围分段取,每段的 `total` 低于 10000 才说明取全了
86
- - `--category`:`text` | `image` | `documents` | `url`(可重复)
86
+ - `--category`:`text` | `image` | `document`(PDF、Excel 等文档)| `url` | `audio` | `video`(可重复)。其他取值(如 `documents`、`pdf`、`mp4` 这类文件格式名)报 `100005`,`--tag` / `--industry` 同样整批拒绝、不会忽略筛选返回全部
87
87
  - `--tag`:`roadShow` | `research` | `strategyMeeting` | `meetingSummary` | `industryComment` | `companyComment` | `earningsReview`(可重复)
88
- - 返回字段:`msgId` / **`content`**(正文)/ **`url`**(链接)/ `msgTime` / `wechatGroupId` / `wechatGroupName` / `speakerName` / `category` / `tagList[]{tagCode, tagName}` / `securityList[]{securityCode, securityName}` / `quoteMsg{quoteMsgId, quoteContent, quoteUrl}`。正文取 `content`、链接取 `url`(不是 `msgContent` / `contentUrl`)
89
- - `quoteMsg`:被引用的消息,无引用时为 `null`;`quoteContent` / `quoteUrl` 也可能为空。做上下文还原时用它把「回复」接回原消息
88
+ - 返回字段:`msgId` / **`content`**(正文)/ **`url`**(链接)/ `msgTime` / `wechatGroupId` / `wechatGroupName` / `speakerName` / `category` / `fileInfo{fileName, fileSize}` / `tagList[]{tagCode, tagName}` / `securityList[]{securityCode, securityName}` / `quoteMsg{quoteMsgId, quoteCategory, quoteContent, quoteUrl, quoteFileInfo}`。正文取 `content`、链接取 `url`(不是 `msgContent` / `contentUrl`)
89
+ - `msgId` 是长数字串,可能超过 JavaScript 安全整数范围——**始终按字符串保存和传递**,别转成数字(会被舍入,拿去下载就对不上)
90
+ - `content` 随 `category` 不同:`text` 为正文、`document` 为文件名、`image` 为图片识别出的文字(可能含 AI 摘要段落,也可能为空,不保证逐字准确)、`url` 为链接标题、`audio` / `video` 为附带文字(常为空,不含转写)
91
+ - `fileInfo`:`document` / `image` / `audio` / `video` 消息的文件名与字节数(`fileSize`,未知时为 `null`),其他类型为 `null`。要文件本身用下面的 `wechat-message-download`
92
+ - `quoteMsg`:被引用的消息,无引用时为 `null`;`quoteContent` / `quoteUrl` 也可能为空。做上下文还原时用它把「回复」接回原消息。被引用的是文件消息时,`quoteFileInfo` 给文件名与大小,下载用 `quoteMsgId`
90
93
  - 未打标签/未关联证券的消息,`tagList` / `securityList` 返回 `null`(不是空数组)
91
94
 
95
+ ## 群消息文件下载 `vault wechat-message-download`
96
+
97
+ ```bash
98
+ gangtise vault wechat-message-download --msg-id <msgId> [--output <path>]
99
+ ```
100
+
101
+ - 免费。`--msg-id` 取自 `wechat-message-list` 的 `msgId`(按字符串原样传);只有 `document` / `image` / `audio` / `video` 消息有文件。引用里的文件用 `quoteMsg.quoteMsgId`(先确认 `quoteCategory` 是这四类之一)
102
+ - 一次一个文件。不带 `--output` 时按服务端给的文件名保存(文档、音频一般是原文件名,图片、视频多为一串随机字符),同名自动加 `-1`、`-2`;stdout 是保存路径
103
+ - 内容原样落盘:`.txt` / `.json` / `.html` 等文本类文件也按原字节保存,不做转码。图片是平台保存的版本,不保证原图分辨率;音频、视频只有文件本身,没有转写
104
+ - 报错:`130005` = 该消息是 `text` / `url`,没有文件;`130003` = 消息不存在、本账号无权访问或文件已不可用(三种情况不区分,**重试不会变**,别轮询);`100003` = `--msg-id` 不是纯数字
105
+ - 列表里有 `fileInfo` 不代表文件一定还能下载,以下载结果为准
106
+
107
+ ```bash
108
+ # 某个群里最近的文件消息 → 逐个下载
109
+ gangtise vault wechat-message-list --wechat-group-id <群ID> --category document --category image --category audio --category video --size 20 --format json
110
+ gangtise vault wechat-message-download --msg-id 4784255865508301077
111
+ gangtise vault wechat-message-download --msg-id 4784255865508301077 --output ./群文件/研报.pdf
112
+ ```
113
+
92
114
  ## 群 ID 查询 `vault wechat-chatroom-list`
93
115
 
94
116
  ```bash
@@ -16,7 +16,7 @@
16
16
  | `999999` | 系统错误。`indicator`(EDE)的「无数据」不用此码(无数据是保留行列的占位单元格 `null`,见 `commands/indicator.md`;代码或参数名写错报 `100003`、缺必填参数报 `100001`,都会点名),所以这个码基本只剩真故障 | 普通端点自动重试 ×2;🔴 贵档与 `indicator` 端点不重试 | 确认参数无误仍报此码即服务端故障 |
17
17
  | `410110` | **异步生成中**(HTTP 400,旧码)。新码 `140001`,CLI 两码都认 | 轮询视为 pending | 继续等 |
18
18
  | `410111` | **异步生成失败**(HTTP 400,旧码)。新码 `140002`,CLI 两码都认 | 终态 | **不重试**,换参数 |
19
- | `130002` | 资源不存在——下载类的常见码:`reportId` 不存在 / 非数字多归此码。另有更具体的 `130003`(资源未生成 / 无附件);`--file-type` 写错由 CLI 在本地报错、不发请求。`vault stock-note-update` 传了不存在或不属于本人的笔记 ID 也报此码(`stock-note-delete` 不报,这类 ID 计入 `successList`) | — | 确认 ID 有效且本账号可见(笔记 ID 用 `vault stock-note-list` 核对);换 `--file-type` 或换一篇验证 |
19
+ | `130002` | 资源不存在——下载类的常见码:`reportId` 不存在 / 非数字多归此码。另有更具体的 `130003`(资源未生成 / 无附件;`vault wechat-message-download` 收到它是消息不存在、无权访问或文件已不可用,不区分原因、重试不会变)与 `130005`(`vault wechat-message-download`:该消息是 text / url,没有文件);`--file-type` 写错由 CLI 在本地报错、不发请求。`vault stock-note-update` 传了不存在或不属于本人的笔记 ID 也报此码(`stock-note-delete` 不报,这类 ID 计入 `successList`) | — | 确认 ID 有效且本账号可见(笔记 ID 用 `vault stock-note-list` 核对);换 `--file-type` 或换一篇验证 |
20
20
  | `130001` | 数据未找到,或**该指标无权限**(`indicator` 内层失败会带具体 msg 如"指标无权限") | — | 检查查询条件与指标权限 |
21
21
  | `100001` | 缺必填参数——**msg 带字段名**(「缺少必填参数: reportId」) | — | 按 msg 指的字段补上 |
22
22
  | `110001` / `110002` | 日期格式错(msg 带字段名)/ 起晚于止。⚠️ **服务端对多种格式做宽松解析**(`2026/07/01`、`20260701`、`07/01/2026` 都能被接受),所以「没报 110001」不等于「格式被按你的意思理解了」 | — | 按参数名:`--*-date` 用 `YYYY-MM-DD`、`--*-time` 用 `YYYY-MM-DD HH:mm:ss`;`ai knowledge-batch` 的 --start-time/--end-time 收时间戳或 datetime,CLI 统一转 13 位毫秒 |
@@ -61,6 +61,7 @@ CLI 自动处理 envelope:`{code, msg, data}` 信封会按 `code === "000000"`
61
61
  | reference concept-search | `{returnedCount, list}` | `list[].conceptId` / `list[].conceptName` / `list[].matchScore` |
62
62
  | reference sector-search | `{returnedCount, list}` | `list[].sectorId` / `list[].sectorName` / `list[].hierarchy`(层级路径) / `list[].matchScore` |
63
63
  | reference sector-constituents | `{total, list}` | `list[].gtsCode` / `list[].gtsName`;total=0 说明 sectorId 不对(先 sector-search 确认) |
64
+ | reference index-weight | `{total, list}`,不分页 | `list[].indexCode` / `indexName` / `tradeDate` / `securityCode` / `securityName` / `weight`(%);多个指数合在一个 `list`,按 `indexCode` 区分;total=0 多为日期不是月末交易日 |
64
65
  | quote day-kline(及已弃用的 day-kline-hk / day-kline-us / index-day-kline) | `{fieldList, list}` 或规范化后 `{list: [{...}]}` | `tradeDate` / `securityCode` / `open` / `close` / `pctChange` / `volume` / `amount`(全球指数为 `null`)/ `adjustFactor`(指数为 `null`,ETF 有值);四者字段相同,均不含指数名称 |
65
66
  | quote minute-kline | `{list: [{...}]}` | `tradeTime` / `open` / `close` / `volume` |
66
67
  | quote realtime | `{fieldList, list, total}` 或规范化后 `{list: [{...}]}` | `securityCode` / `exchange` / `tradeDate` / `tradeTime` / `tradeStatus` / `open` / `high` / `low` / `latestPrice` / `preClose` / `change` / `pctChange` / `volume` / `amount` / `amplitude`(共 15 个,**无 `close`、无市值、无 `turnoverRate` / `volumeRatio`**;美股 `amount`、全球指数 `volume` / `amount` / `amplitude` 为 `null`) |
@@ -78,6 +79,7 @@ CLI 自动处理 envelope:`{code, msg, data}` 信封会按 `code === "000000"`
78
79
  | ai theme-tracking | `[{type, date, content}, ...]`(列表,每元素一份报告) | 遍历筛选 `type === "morning" / "night"`;某主题在该日期可能只有一种类型,或两种都没(空列表) |
79
80
  | ai hot-topic | `{list, total}` | `list[].title` / `list[].reportDate` / `list[].category` / `list[].topics[].topicTitle` / `list[].topics[].driverEvent` / `list[].topics[].investLogic` |
80
81
  | ai management-discuss-* | `{securityCode, reportDate, discussionDimension, content}` | `content` 为字符串(业绩会)或字符串数组(财报) |
82
+ | ai expert-intel | `{list, total}` | `list[].intelId` / `title` / `mainSecurity.securityCode` · `securityName` / `tagList[]`(纯文本)/ `content` / `publishTime` / `securityList[]` / `researchAreaList[].researchAreaName` / `conceptList[].conceptName` |
81
83
  | ai management-sentiment-indicator | `{list, total}`,一条 = 一只证券 × 一场业绩会 | `list[].securityCode` / `publishTime` / `sentimentResponsiveness` · `sentimentPolarity` · `sentimentConviction`(0–5)/ `qaCount` / `qaEvasionRatio` · `qaRiskRatio` · `qaUncertaintyRatio`(百分数)/ `questionCategoryList[]` / `source.sourceType` + `source.sourceId` |
82
84
  | ai management-sentiment-conclusion | `{list, total}`,粒度同上 | `list[].sentimentSummary.{overallSentiment, questionCategorySentiment, qaSentimentChange}` / `sentimentSignal.*Signal`(文本)/ `qaSentimentContrast[]` / `source` / `previousSource`(无可对比的上一场时为 `null`) |
83
85
  | ai management-sentiment-detail | `{list, total}`,一条 = 一条问答,不分页 | `list[].qaId` / `questionCategory` / `questionBrief` / `question` / `answer` / `qaResponsiveness` · `qaPolarity` · `qaConviction`(`5.0` / `2.5` / `0.0` 三档)/ 三组 `*Quote` + `*Reason` |
@@ -96,7 +98,8 @@ CLI 自动处理 envelope:`{code, msg, data}` 信封会按 `code === "000000"`
96
98
  | vault record-download | 文件路径(stdout) | — |
97
99
  | vault my-conference-list | `{list, total}` | `list[].conferenceId` / `list[].title` / `list[].category` / `list[].institution.institutionName` / `list[].publishTime` |
98
100
  | vault my-conference-download | 文件路径(stdout) | — |
99
- | vault wechat-message-list | `{list, total}` | `list[].msgId` / `list[].content`(正文)/ `list[].url` / `list[].msgTime` / `list[].wechatGroupName` / `list[].speakerName` / `list[].category` / `list[].tagList[].tagCode` / `list[].securityList[].securityCode` / `list[].quoteMsg.quoteContent`(引用消息,无引用为 `null`)。**字段名是 `content` / `url`**,不是 `msgContent` / `contentUrl` |
101
+ | vault wechat-message-list | `{list, total}` | `list[].msgId` / `list[].content`(正文)/ `list[].url` / `list[].msgTime` / `list[].wechatGroupName` / `list[].speakerName` / `list[].category` / `list[].tagList[].tagCode` / `list[].securityList[].securityCode` / `list[].fileInfo.fileName` · `fileSize`(文档 / 图片 / 音频 / 视频消息,其他为 `null`)/ `list[].quoteMsg.quoteMsgId` · `quoteCategory` · `quoteContent` · `quoteFileInfo`(引用消息,无引用为 `null`)。**字段名是 `content` / `url`**,不是 `msgContent` / `contentUrl`;`msgId` 是长数字串,按字符串保存 |
102
+ | vault wechat-message-download | 文件路径(stdout) | — |
100
103
  | vault wechat-chatroom-list | `{list, total}` | `list[].chatroomName` / `list[].chatroomId` |
101
104
  | vault stock-pool-list | 数组 | `[].poolId`(后续命令的 `--pool-id`)/ `[].poolName` / `[].spaceType`(`1` 个人、`2` 租户;查明细时 `--space-type` 要与之一致) |
102
105
  | vault stock-pool-stocks | 数组 | `[].securityCode` / `[].securityName`。空池返回 `[]` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gangtise-openapi-cli",
3
- "version": "0.50.0",
3
+ "version": "0.51.0",
4
4
  "description": "CLI for Gangtise OpenAPI",
5
5
  "license": "MIT",
6
6
  "repository": {