gangtise-openapi-cli 0.15.1 → 0.17.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 +58 -14
- package/dist/src/cli.js +68 -22
- package/dist/src/core/client.js +0 -6
- package/dist/src/core/endpoints.js +35 -42
- package/dist/src/core/lookupData/index.js +0 -6
- package/dist/src/core/normalize.js +5 -0
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
- package/dist/src/core/lookupData/announcement-categories.js +0 -554
- package/dist/src/core/lookupData/industries.js +0 -157
- package/dist/src/core/lookupData/industry-codes.js +0 -126
- package/dist/src/core/lookupData/regions.js +0 -78
- package/dist/src/core/lookupData/research-areas.js +0 -266
- package/dist/src/core/lookupData/theme-ids.js +0 -1614
package/README.md
CHANGED
|
@@ -4,6 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
## Changelog
|
|
6
6
|
|
|
7
|
+
### v0.17.0 — 2026-06-15
|
|
8
|
+
|
|
9
|
+
**接口变更(Breaking)**
|
|
10
|
+
- 日程类命令(`roadshow` / `site-visit` / `strategy` / `forum` list)改为各自只暴露 API spec 支持的筛选选项,移除原先一刀切多出的无效选项:`strategy` 仅保留 `--institution` / `--location`;`forum` 仅保留 `--research-area` / `--location`;`site-visit` 移除 `--participant-role` / `--broker-type`;`roadshow` 移除 `--object`。传不支持的选项现由 commander 直接报 `unknown option`(此前会静默发送、服务端返回空结果)
|
|
11
|
+
- `insight announcement list` 移除无效的 `--announcement-type`(服务端忽略、恒返全量);A 股公告分类筛选用 `--category`(`aShareAnnouncementCategory` 常量 ID)
|
|
12
|
+
|
|
13
|
+
**说明 / 修正**
|
|
14
|
+
- `--industry` 用 `citicIndustry` 码(`1008001xx`,全命令通用);`--research-area` 用 `gangtiseIndustry` 码(行业 `1008001xx` + 宏观/策略/固收/金工/海外等方向 `122000xxx`)。详见 `gangtise-openapi/references/commands/reference-and-lookup.md`
|
|
15
|
+
- 日程类 `--location`(domesticCity)服务端过滤已生效(v0.16.0 时曾未生效)
|
|
16
|
+
|
|
17
|
+
### v0.16.0 — 2026-06-12
|
|
18
|
+
|
|
19
|
+
**新增接口(参考数据 · 常量查询,均免积分)**
|
|
20
|
+
- `reference constant-category` — 查询常量分类:全量导出常量分类及各分类适用于哪些接口的哪些参数(7 个分类:中信/申万/Gangtise 行业、国内城市、A股/港股公告分类、区域)
|
|
21
|
+
- `reference constant-list --category <code>` — 查询常量值:按分类导出全量常量(`constantId` / `constantName`,树形分类含 `children` 嵌套)
|
|
22
|
+
- `reference concept-search --keyword <kw>` — 查询题材 ID:按名称/拼音/分组名搜索,返回 `conceptId`(供 `alternative concept-info / concept-securities`、`ai theme-tracking` 使用)
|
|
23
|
+
- `reference sector-search --keyword <kw>` — 查询板块 ID:返回 `sectorId` + `hierarchy` 层级路径
|
|
24
|
+
- `reference sector-constituents --sector-id <id>` — 查询板块成分股:返回该板块全量成分股(`gtsCode` / `gtsName`);注意 sectorId 必须来自 sector-search,题材 conceptId 查不到成分
|
|
25
|
+
|
|
26
|
+
**接口变更(Breaking)**
|
|
27
|
+
- 移除已被新 API 覆盖的 6 个本地 lookup 子命令及静态数据:`lookup research-area / industry / region / announcement-category / theme-id / industry-code list`,请改用 `reference constant-list` / `reference concept-search` / `reference sector-constituents`(申万行业代码 `821xxx.SWI` 全量:`sector-constituents --sector-id 2000000014`,即申万一级行业指数板块)
|
|
28
|
+
- `lookup` 仅保留 2 个 API 未覆盖的本地表:`broker-org` / `meeting-org`
|
|
29
|
+
- 路演/调研/策略会/论坛 list 新增 `--location <id>` 按城市过滤(domesticCity 常量 ID;服务端过滤 v0.17.0 起已生效)
|
|
30
|
+
|
|
7
31
|
### v0.15.0 — 2026-05-29
|
|
8
32
|
|
|
9
33
|
**新增接口**
|
|
@@ -135,7 +159,7 @@ npm version patch --no-git-tag-version
|
|
|
135
159
|
npm run prepare
|
|
136
160
|
VERSION=$(node -p "require('./package.json').version")
|
|
137
161
|
git commit -am "chore: release v$VERSION"
|
|
138
|
-
git tag "v$VERSION"
|
|
162
|
+
git tag -a "v$VERSION" -m "v$VERSION" # 必须 annotated:--follow-tags 不推 lightweight tag
|
|
139
163
|
git push --follow-tags
|
|
140
164
|
```
|
|
141
165
|
|
|
@@ -235,7 +259,7 @@ cp -r gangtise-openapi ~/.hermes/skills/gangtise-openapi
|
|
|
235
259
|
| 模块 | 子命令 | 说明 |
|
|
236
260
|
|------|--------|------|
|
|
237
261
|
| **Auth** | `login` / `status` | 认证登录、状态查询 |
|
|
238
|
-
| **Lookup** | `
|
|
262
|
+
| **Lookup** | `broker-org list` / `meeting-org list` | 本地枚举表(API 未覆盖的部分;行业/区域/公告分类/题材/申万行业代码改用 Reference 接口) |
|
|
239
263
|
| **Insight** | `opinion list` | 内资机构观点 |
|
|
240
264
|
| | `summary list` / `download` | 纪要(含下载,支持 `--file-type` 选原始/HTML) |
|
|
241
265
|
| | `roadshow list` | 路演 |
|
|
@@ -249,6 +273,11 @@ cp -r gangtise-openapi ~/.hermes/skills/gangtise-openapi
|
|
|
249
273
|
| | `foreign-opinion list` | 外资机构观点 |
|
|
250
274
|
| | `independent-opinion list` / `download` | 外资独立分析师观点(含原文/翻译HTML下载) |
|
|
251
275
|
| **Reference** | `securities-search` | GTS Code 搜索(按名称/代码/拼音匹配) |
|
|
276
|
+
| | `constant-category` | 常量分类列表(含各分类适用的接口与参数) |
|
|
277
|
+
| | `constant-list` | 按分类导出常量值全量列表(行业/城市/公告分类/区域等) |
|
|
278
|
+
| | `concept-search` | 题材 ID 搜索(名称/拼音/分组名匹配) |
|
|
279
|
+
| | `sector-search` | 板块 ID 搜索(返回层级路径) |
|
|
280
|
+
| | `sector-constituents` | 板块成分股查询 |
|
|
252
281
|
| **Quote** | `day-kline` / `day-kline-hk` / `day-kline-us` | A股/港股/美股历史日K线 |
|
|
253
282
|
| | `index-day-kline` | 沪深京指数日K线 |
|
|
254
283
|
| | `minute-kline` | A股分钟K线 |
|
|
@@ -302,19 +331,21 @@ cp -r gangtise-openapi ~/.hermes/skills/gangtise-openapi
|
|
|
302
331
|
先查枚举/参数:
|
|
303
332
|
|
|
304
333
|
```bash
|
|
305
|
-
gangtise
|
|
306
|
-
gangtise
|
|
307
|
-
gangtise
|
|
308
|
-
gangtise
|
|
309
|
-
gangtise
|
|
310
|
-
gangtise
|
|
311
|
-
gangtise
|
|
334
|
+
gangtise reference constant-category # 有哪些常量分类、各用于哪些参数
|
|
335
|
+
gangtise reference constant-list --category citicIndustry # 中信行业(--industry 通用)
|
|
336
|
+
gangtise reference constant-list --category gangtiseIndustry # Gangtise 行业 + 方向(--research-area 用)
|
|
337
|
+
gangtise reference constant-list --category swIndustry # 申万行业
|
|
338
|
+
gangtise reference constant-list --category regionCategory # 外资研报区域
|
|
339
|
+
gangtise reference constant-list --category aShareAnnouncementCategory # A股公告分类(树形)
|
|
340
|
+
gangtise reference sector-constituents --sector-id 2000000014 # 申万行业代码 821xxx.SWI 全量(security-clue --gts-code 用)
|
|
341
|
+
gangtise lookup broker-org list # 券商机构(本地表)
|
|
342
|
+
gangtise lookup meeting-org list # 会议机构(本地表)
|
|
312
343
|
```
|
|
313
344
|
|
|
314
345
|
再调用业务命令:
|
|
315
346
|
|
|
316
347
|
```bash
|
|
317
|
-
gangtise insight opinion list --industry
|
|
348
|
+
gangtise insight opinion list --industry 100800128
|
|
318
349
|
gangtise insight summary list --institution C100000017
|
|
319
350
|
gangtise quote day-kline --security 600519.SH --start-date 2025-03-01 --end-date 2025-03-12
|
|
320
351
|
gangtise ai knowledge-batch --query 比亚迪 --query 最近热门概念
|
|
@@ -388,10 +419,10 @@ gangtise auth status
|
|
|
388
419
|
gangtise insight research list --start-time "2026-04-01 00:00:00" --end-time "2026-04-09 23:59:59"
|
|
389
420
|
|
|
390
421
|
# 无时间范围 → 默认 --size 200
|
|
391
|
-
gangtise insight research list --industry
|
|
422
|
+
gangtise insight research list --industry 100800126 --category company --llm-tag inDepth --rating buy
|
|
392
423
|
|
|
393
424
|
# 多值 List 模式:一次查多家券商 + 多个行业 + 多个评级
|
|
394
|
-
gangtise insight research list --broker C100000027 --broker C100000014 --industry
|
|
425
|
+
gangtise insight research list --broker C100000027 --broker C100000014 --industry 100800119 --industry 100800118 --rating buy --rating overweight --format json
|
|
395
426
|
|
|
396
427
|
gangtise insight opinion list --keyword AI
|
|
397
428
|
gangtise insight summary list --keyword 算力
|
|
@@ -421,7 +452,7 @@ gangtise insight foreign-opinion list --keyword "自动驾驶" --region us --ran
|
|
|
421
452
|
gangtise insight foreign-opinion list --security APP.O --rating buy --format json
|
|
422
453
|
|
|
423
454
|
# 外资独立观点
|
|
424
|
-
gangtise insight independent-opinion list --keyword "肿瘤" --industry
|
|
455
|
+
gangtise insight independent-opinion list --keyword "肿瘤" --industry 100800118 --format json
|
|
425
456
|
gangtise insight independent-opinion download --independent-opinion-id 207051900018372 --file-type 2
|
|
426
457
|
|
|
427
458
|
# 纪要下载(会议平台来源可选 HTML 格式)
|
|
@@ -436,6 +467,19 @@ gangtise reference securities-search --keyword "贵州茅台" --category stock
|
|
|
436
467
|
gangtise reference securities-search --keyword "600519" --category stock
|
|
437
468
|
gangtise reference securities-search --keyword gzmt --top 5
|
|
438
469
|
gangtise reference securities-search --keyword "银行" --category stock --category index
|
|
470
|
+
|
|
471
|
+
# 常量查询:先看分类,再按分类导出全量常量值
|
|
472
|
+
gangtise reference constant-category --format json
|
|
473
|
+
gangtise reference constant-list --category citicIndustry --format json
|
|
474
|
+
gangtise reference constant-list --category aShareAnnouncementCategory --format json # 树形,含 children
|
|
475
|
+
|
|
476
|
+
# 题材 ID 搜索(供 concept-info / concept-securities / theme-tracking 使用)
|
|
477
|
+
gangtise reference concept-search --keyword 机器人 --top 3 --format json
|
|
478
|
+
gangtise reference concept-search --keyword jqr # 拼音首字母
|
|
479
|
+
|
|
480
|
+
# 板块:先搜板块 ID,再查成分股(sectorId 必须来自 sector-search)
|
|
481
|
+
gangtise reference sector-search --keyword 半导体设备 --format json
|
|
482
|
+
gangtise reference sector-constituents --sector-id 1000001005 --format json
|
|
439
483
|
```
|
|
440
484
|
|
|
441
485
|
### Quote
|
|
@@ -593,7 +637,7 @@ gangtise alternative edb-data \
|
|
|
593
637
|
--output ./indicator.csv
|
|
594
638
|
|
|
595
639
|
# 题材指数:先查 conceptId(与 theme-id 共用 ID 体系),再拉画像 / 成分股
|
|
596
|
-
gangtise
|
|
640
|
+
gangtise reference concept-search --keyword 机器人 --format json # → 121000130
|
|
597
641
|
gangtise alternative concept-info --concept-id 121000130 --format json
|
|
598
642
|
# 题材成分股(题材深度 F8,按分组返回,标记重点个股)
|
|
599
643
|
gangtise alternative concept-securities --concept-id 121000130 --format json
|
package/dist/src/cli.js
CHANGED
|
@@ -108,21 +108,15 @@ program
|
|
|
108
108
|
const cache = await readTokenCache(config.tokenCachePath);
|
|
109
109
|
await printData({ hasEnvToken: Boolean(config.token), hasCachedToken: Boolean(cache?.accessToken), cache }, parseOutputFormat(options.format));
|
|
110
110
|
}));
|
|
111
|
-
const lookup = new Command("lookup").description("
|
|
111
|
+
const lookup = new Command("lookup").description("Local lookup tables (IDs not covered by 'reference constant-list')");
|
|
112
112
|
const addLookupList = (name, endpointKey, description) => {
|
|
113
113
|
const cmd = new Command(name);
|
|
114
114
|
if (description)
|
|
115
115
|
cmd.description(description);
|
|
116
116
|
lookup.addCommand(cmd.addCommand(new Command("list").option("--format <format>", "Output format", "table").action((options) => emit(options, (client) => client.call(endpointKey)))));
|
|
117
117
|
};
|
|
118
|
-
addLookupList("research-area", "lookup.research-areas.list");
|
|
119
118
|
addLookupList("broker-org", "lookup.broker-orgs.list");
|
|
120
119
|
addLookupList("meeting-org", "lookup.meeting-orgs.list");
|
|
121
|
-
addLookupList("industry", "lookup.industries.list");
|
|
122
|
-
addLookupList("region", "lookup.regions.list", "Foreign report region codes");
|
|
123
|
-
addLookupList("announcement-category", "lookup.announcement-categories.list", "Announcement category codes");
|
|
124
|
-
addLookupList("industry-code", "lookup.industry-codes.list", "Shenwan industry codes for security-clue --gts-code");
|
|
125
|
-
addLookupList("theme-id", "lookup.theme-ids.list", "Theme IDs for theme-tracking --theme-id");
|
|
126
120
|
program.addCommand(lookup);
|
|
127
121
|
const insight = new Command("insight").description("Insight APIs");
|
|
128
122
|
const opinion = new Command("opinion");
|
|
@@ -150,16 +144,57 @@ addTimeFilters(summary.command("list").option("--search-type <number>", "Search
|
|
|
150
144
|
categoryList: maybeArray(options.category), marketList: maybeArray(options.market), participantRoleList: maybeArray(options.participantRole),
|
|
151
145
|
}), { endpointKey: "insight.summary.list", idField: "summaryId" }));
|
|
152
146
|
addDownloadCommand(summary, { endpointKey: "insight.summary.download", idOption: "--summary-id", idField: "summaryId", fallbackPrefix: "summary", fileType: { description: "File type: 1=original(default) 2=HTML; only affects meeting platform summaries" }, titleListEndpoint: "insight.summary.list" });
|
|
153
|
-
const addScheduleList = (command, endpointKey
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
147
|
+
const addScheduleList = (command, endpointKey, fields) => {
|
|
148
|
+
const list = command.command("list");
|
|
149
|
+
if (fields.researchArea)
|
|
150
|
+
list.option("--research-area <id>", "Research area ID (constant-list category gangtiseIndustry: 1008001xx industries + 122000xxx macro/strategy/fixed-income/quant/overseas directions)", collectList, []);
|
|
151
|
+
if (fields.institution)
|
|
152
|
+
list.option("--institution <id>", "Lead institution ID", collectList, []);
|
|
153
|
+
if (fields.security)
|
|
154
|
+
list.option("--security <code>", "Security code", collectList, []);
|
|
155
|
+
if (fields.object)
|
|
156
|
+
list.option("--object <type>", "Object type: company/industry", collectList, []);
|
|
157
|
+
if (fields.category)
|
|
158
|
+
list.option("--category <name>", fields.category, collectList, []);
|
|
159
|
+
if (fields.market)
|
|
160
|
+
list.option("--market <name>", fields.market, collectList, []);
|
|
161
|
+
if (fields.participantRole)
|
|
162
|
+
list.option("--participant-role <name>", "Participant role: management/expert", collectList, []);
|
|
163
|
+
if (fields.brokerType)
|
|
164
|
+
list.option("--broker-type <name>", "Lead broker type: cnBroker/otherBroker", collectList, []);
|
|
165
|
+
if (fields.permission)
|
|
166
|
+
list.option("--permission <number>", "Permission: 1=public 2=private", collectNumberList, []);
|
|
167
|
+
if (fields.location)
|
|
168
|
+
list.option("--location <id>", "Location ID (domesticCity constant, via 'reference constant-list')", collectList, []);
|
|
169
|
+
list.option("--format <format>", "Output format", "table").option("--output <path>", "Output path");
|
|
170
|
+
addTimeFilters(list).action((options) => emit(options, (client) => client.call(endpointKey, {
|
|
171
|
+
from: parseFrom(options.from), size: parseSize(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
172
|
+
researchAreaList: fields.researchArea ? maybeArray(options.researchArea) : undefined,
|
|
173
|
+
institutionList: fields.institution ? maybeArray(options.institution) : undefined,
|
|
174
|
+
securityList: fields.security ? maybeArray(options.security) : undefined,
|
|
175
|
+
objectList: fields.object ? maybeArray(options.object) : undefined,
|
|
176
|
+
categoryList: fields.category ? maybeArray(options.category) : undefined,
|
|
177
|
+
marketList: fields.market ? maybeArray(options.market) : undefined,
|
|
178
|
+
participantRoleList: fields.participantRole ? maybeArray(options.participantRole) : undefined,
|
|
179
|
+
brokerTypeList: fields.brokerType ? maybeArray(options.brokerType) : undefined,
|
|
180
|
+
permission: fields.permission && options.permission?.length ? options.permission : undefined,
|
|
181
|
+
locationList: fields.location ? maybeArray(options.location) : undefined,
|
|
182
|
+
})));
|
|
183
|
+
};
|
|
184
|
+
addScheduleList(roadshow, "insight.roadshow.list", {
|
|
185
|
+
researchArea: true, institution: true, security: true, location: true,
|
|
186
|
+
category: "Roadshow type: earningsCall/strategyMeeting/companyAnalysis/industryAnalysis/fundRoadshow",
|
|
187
|
+
market: "Market: aShares/hkStocks/usChinaConcept/usStocks",
|
|
188
|
+
participantRole: true, brokerType: true, permission: true,
|
|
189
|
+
});
|
|
190
|
+
addScheduleList(siteVisit, "insight.site-visit.list", {
|
|
191
|
+
researchArea: true, institution: true, security: true, location: true, object: true,
|
|
192
|
+
category: "Site-visit form: single/series",
|
|
193
|
+
market: "Market: aShares/hkStocks/usChinaConcept",
|
|
194
|
+
permission: true,
|
|
195
|
+
});
|
|
196
|
+
addScheduleList(strategy, "insight.strategy.list", { institution: true, location: true });
|
|
197
|
+
addScheduleList(forum, "insight.forum.list", { researchArea: true, location: true });
|
|
163
198
|
addTimeFilters(research.command("list").option("--search-type <number>", "Search type: 1=title 2=fulltext", "1").option("--rank-type <number>", "Rank type: 1=composite 2=time desc", "1").option("--broker <id>", "Broker ID", collectList, []).option("--security <code>", "Security code", collectList, []).option("--industry <id>", "Industry ID", collectList, []).option("--category <name>", "Report category", collectList, []).option("--llm-tag <tag>", "Semantic tag", collectList, []).option("--rating <name>", "Rating", collectList, []).option("--rating-change <name>", "Rating change", collectList, []).option("--min-pages <number>", "Min report pages").option("--max-pages <number>", "Max report pages").option("--source <type>", "Source type", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action((options) => emit(options, (client) => client.call("insight.research.list", {
|
|
164
199
|
from: parseFrom(options.from), size: parseSize(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword,
|
|
165
200
|
searchType: parseNumberOption(options.searchType, "--search-type", { integer: true, min: 1 }), rankType: parseNumberOption(options.rankType, "--rank-type", { integer: true, min: 1 }),
|
|
@@ -178,11 +213,11 @@ addTimeFilters(foreignReport.command("list").option("--search-type <number>", "S
|
|
|
178
213
|
minReportPages: parseOptionalNumberOption(options.minPages, "--min-pages", { integer: true, min: 0 }), maxReportPages: parseOptionalNumberOption(options.maxPages, "--max-pages", { integer: true, min: 0 }),
|
|
179
214
|
}), { endpointKey: "insight.foreign-report.list", idField: "reportId" }));
|
|
180
215
|
addDownloadCommand(foreignReport, { endpointKey: "insight.foreign-report.download", idOption: "--report-id", idField: "reportId", fallbackPrefix: "foreign-report", fileType: { description: "File type: 1=PDF 2=Markdown 3=CN-PDF 4=CN-Markdown", default: "1" }, titleListEndpoint: "insight.foreign-report.list" });
|
|
181
|
-
addTimeFilters(announcement.command("list").option("--search-type <number>", "Search type: 1=title 2=fulltext", "1").option("--rank-type <number>", "Rank type: 1=composite 2=time desc", "1").option("--security <code>", "Security code", collectList, []).option("--
|
|
216
|
+
addTimeFilters(announcement.command("list").option("--search-type <number>", "Search type: 1=title 2=fulltext", "1").option("--rank-type <number>", "Rank type: 1=composite 2=time desc", "1").option("--security <code>", "Security code", collectList, []).option("--category <id>", "Category ID", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action((options) => emit(options, (client) => client.call("insight.announcement.list", {
|
|
182
217
|
from: parseFrom(options.from), size: parseSize(options.size),
|
|
183
218
|
startTime: parseTimestamp13(options.startTime, "--start-time"), endTime: parseTimestamp13(options.endTime, "--end-time"),
|
|
184
219
|
searchType: parseNumberOption(options.searchType, "--search-type", { integer: true, min: 1 }), rankType: parseNumberOption(options.rankType, "--rank-type", { integer: true, min: 1 }), keyword: options.keyword,
|
|
185
|
-
securityList: maybeArray(options.security),
|
|
220
|
+
securityList: maybeArray(options.security), categoryList: maybeArray(options.category),
|
|
186
221
|
}), { endpointKey: "insight.announcement.list", idField: "announcementId" }));
|
|
187
222
|
addDownloadCommand(announcement, { endpointKey: "insight.announcement.download", idOption: "--announcement-id", idField: "announcementId", fallbackPrefix: "announcement", fileType: { description: "File type: 1=PDF 2=Markdown", default: "1" }, titleListEndpoint: "insight.announcement.list" });
|
|
188
223
|
addTimeFilters(announcementHk.command("list").option("--search-type <number>", "Search type: 1=title 2=fulltext", "1").option("--rank-type <number>", "Rank type: 1=composite 2=time desc", "1").option("--security <code>", "Security code (e.g. 01913.HK)", collectList, []).option("--category <id>", "Category ID", collectList, []).option("--format <format>", "Output format", "table").option("--output <path>", "Output path")).action((options) => emit(options, (client) => client.call("insight.announcement-hk.list", {
|
|
@@ -302,7 +337,7 @@ ai.command("earnings-review").requiredOption("--security-code <code>").requiredO
|
|
|
302
337
|
}
|
|
303
338
|
}));
|
|
304
339
|
ai.command("earnings-review-check").requiredOption("--data-id <id>", "dataId from earnings-review").option("--format <format>", "Output format", "json").option("--output <path>").action((options) => withClient((client) => checkAsyncContent(client, "ai.earnings-review.get-content", options.dataId, parseOutputFormat(options.format), options.output)));
|
|
305
|
-
ai.command("theme-tracking").requiredOption("--theme-id <id>", "Theme ID (use
|
|
340
|
+
ai.command("theme-tracking").requiredOption("--theme-id <id>", "Theme ID (use 'reference concept-search')").requiredOption("--date <date>", "Date (yyyy-MM-dd)").option("--type <name>", "Report type: morning/night", collectList, []).option("--format <format>", "Output format", "json").option("--output <path>").action((options) => emit(options, (client) => {
|
|
306
341
|
const typeList = options.type.length ? options.type : undefined;
|
|
307
342
|
return client.call("ai.theme-tracking", { themeId: options.themeId, date: options.date, type: typeList });
|
|
308
343
|
}));
|
|
@@ -355,6 +390,17 @@ reference.command("securities-search").requiredOption("--keyword <text>", "Searc
|
|
|
355
390
|
category: options.category.length ? options.category : undefined,
|
|
356
391
|
top: parseNumberOption(options.top, "--top", { integer: true, min: 1 }),
|
|
357
392
|
})));
|
|
393
|
+
reference.command("constant-category").description("List constant categories and which API params accept them").option("--format <format>", "Output format", "table").option("--output <path>").action((options) => emit(options, (client) => client.call("reference.constant-category")));
|
|
394
|
+
reference.command("constant-list").requiredOption("--category <code>", "Category code from 'reference constant-category' (e.g. citicIndustry/swIndustry/regionCategory)").option("--format <format>", "Output format", "table").option("--output <path>").action((options) => emit(options, (client) => client.call("reference.constant-list", { category: options.category })));
|
|
395
|
+
reference.command("concept-search").requiredOption("--keyword <text>", "Search keyword (name/pinyin/group name)").option("--top <number>", "Max results (default: 10, max: 10)", "10").option("--format <format>", "Output format", "table").option("--output <path>").action((options) => emit(options, (client) => client.call("reference.concept-search", {
|
|
396
|
+
keyword: options.keyword,
|
|
397
|
+
top: parseNumberOption(options.top, "--top", { integer: true, min: 1 }),
|
|
398
|
+
})));
|
|
399
|
+
reference.command("sector-search").option("--keyword <text>", "Search keyword (name/pinyin)").option("--top <number>", "Max results (default: 10, max: 10)", "10").option("--format <format>", "Output format", "table").option("--output <path>").action((options) => emit(options, (client) => client.call("reference.sector-search", {
|
|
400
|
+
keyword: options.keyword,
|
|
401
|
+
top: parseNumberOption(options.top, "--top", { integer: true, min: 1 }),
|
|
402
|
+
})));
|
|
403
|
+
reference.command("sector-constituents").requiredOption("--sector-id <id>", "Sector ID from 'reference sector-search'").option("--format <format>", "Output format", "table").option("--output <path>").action((options) => emit(options, (client) => client.call("reference.sector-constituents", { sectorId: options.sectorId })));
|
|
358
404
|
program.addCommand(reference);
|
|
359
405
|
const vault = new Command("vault").description("Vault APIs");
|
|
360
406
|
vault.command("drive-list").option("--from <number>", "Starting offset", "0").option("--size <number>", "Total rows to return; omit to fetch all").option("--start-time <datetime>").option("--end-time <datetime>").option("--keyword <text>").option("--file-type <number>", "File type", collectNumberList, []).option("--space-type <number>", "Space type", collectNumberList, []).option("--format <format>", "Output format", "table").option("--output <path>").action((options) => emit(options, (client) => client.call("vault.drive.list", { from: parseFrom(options.from), size: parseSize(options.size), startTime: options.startTime, endTime: options.endTime, keyword: options.keyword, fileTypeList: options.fileType.length ? options.fileType : undefined, spaceTypeList: options.spaceType.length ? options.spaceType : undefined }), { endpointKey: "vault.drive.list", idField: "fileId" }));
|
|
@@ -390,8 +436,8 @@ alternative.command("edb-data").option("--indicator-id <id>", "Indicator ID (rep
|
|
|
390
436
|
}
|
|
391
437
|
await printData(data, parseOutputFormat(options.format), options.output);
|
|
392
438
|
}));
|
|
393
|
-
alternative.command("concept-info").requiredOption("--concept-id <id>", "Concept (theme index) ID, e.g. 121000130 机器人; discover via 'gangtise
|
|
394
|
-
alternative.command("concept-securities").requiredOption("--concept-id <id>", "Concept (theme index) ID, e.g. 121000130 机器人; discover via 'gangtise
|
|
439
|
+
alternative.command("concept-info").requiredOption("--concept-id <id>", "Concept (theme index) ID, e.g. 121000130 机器人; discover via 'gangtise reference concept-search'").option("--format <format>", "Output format", "json").option("--output <path>").action((options) => emit(options, (client) => client.call("alternative.concept-info", { conceptId: options.conceptId })));
|
|
440
|
+
alternative.command("concept-securities").requiredOption("--concept-id <id>", "Concept (theme index) ID, e.g. 121000130 机器人; discover via 'gangtise reference concept-search'").option("--format <format>", "Output format", "json").option("--output <path>").action((options) => emit(options, (client) => client.call("alternative.concept-securities", { conceptId: options.conceptId })));
|
|
395
441
|
program.addCommand(alternative);
|
|
396
442
|
program.command("raw").description("Raw API calls").addCommand(new Command("call").argument("<endpointKey>").option("--body <json>").option("--query <key=value>", "Query string pair", collectKeyValue, {}).option("--format <format>", "Output format", "json").option("--output <path>").action(async (endpointKey, options) => {
|
|
397
443
|
const endpoint = ENDPOINTS[endpointKey];
|
package/dist/src/core/client.js
CHANGED
|
@@ -101,14 +101,8 @@ export class GangtiseClient {
|
|
|
101
101
|
}
|
|
102
102
|
async readLocalLookup(endpoint) {
|
|
103
103
|
const keyMapping = {
|
|
104
|
-
"lookup.research-areas.list": "research-areas",
|
|
105
104
|
"lookup.broker-orgs.list": "broker-orgs",
|
|
106
105
|
"lookup.meeting-orgs.list": "meeting-orgs",
|
|
107
|
-
"lookup.industries.list": "industries",
|
|
108
|
-
"lookup.regions.list": "regions",
|
|
109
|
-
"lookup.announcement-categories.list": "announcement-categories",
|
|
110
|
-
"lookup.industry-codes.list": "industry-codes",
|
|
111
|
-
"lookup.theme-ids.list": "theme-ids",
|
|
112
106
|
};
|
|
113
107
|
const lookupKey = keyMapping[endpoint.key];
|
|
114
108
|
if (lookupKey) {
|
|
@@ -8,13 +8,6 @@ export const ENDPOINTS = {
|
|
|
8
8
|
description: "Get access token",
|
|
9
9
|
},
|
|
10
10
|
// ─── lookup (served from local data, not HTTP) ───
|
|
11
|
-
"lookup.research-areas.list": {
|
|
12
|
-
key: "lookup.research-areas.list",
|
|
13
|
-
method: "GET",
|
|
14
|
-
path: "/guide/research-area-local",
|
|
15
|
-
kind: "json",
|
|
16
|
-
description: "List research areas from local docs",
|
|
17
|
-
},
|
|
18
11
|
"lookup.broker-orgs.list": {
|
|
19
12
|
key: "lookup.broker-orgs.list",
|
|
20
13
|
method: "GET",
|
|
@@ -29,41 +22,6 @@ export const ENDPOINTS = {
|
|
|
29
22
|
kind: "json",
|
|
30
23
|
description: "List meeting orgs from local docs",
|
|
31
24
|
},
|
|
32
|
-
"lookup.industries.list": {
|
|
33
|
-
key: "lookup.industries.list",
|
|
34
|
-
method: "GET",
|
|
35
|
-
path: "/guide/industries-local",
|
|
36
|
-
kind: "json",
|
|
37
|
-
description: "List industries from local docs",
|
|
38
|
-
},
|
|
39
|
-
"lookup.regions.list": {
|
|
40
|
-
key: "lookup.regions.list",
|
|
41
|
-
method: "GET",
|
|
42
|
-
path: "/guide/regions-local",
|
|
43
|
-
kind: "json",
|
|
44
|
-
description: "List regions from local docs",
|
|
45
|
-
},
|
|
46
|
-
"lookup.announcement-categories.list": {
|
|
47
|
-
key: "lookup.announcement-categories.list",
|
|
48
|
-
method: "GET",
|
|
49
|
-
path: "/guide/announcement-categories-local",
|
|
50
|
-
kind: "json",
|
|
51
|
-
description: "List announcement categories from local docs",
|
|
52
|
-
},
|
|
53
|
-
"lookup.industry-codes.list": {
|
|
54
|
-
key: "lookup.industry-codes.list",
|
|
55
|
-
method: "GET",
|
|
56
|
-
path: "/guide/industry-codes-local",
|
|
57
|
-
kind: "json",
|
|
58
|
-
description: "List Shenwan industry codes from local docs",
|
|
59
|
-
},
|
|
60
|
-
"lookup.theme-ids.list": {
|
|
61
|
-
key: "lookup.theme-ids.list",
|
|
62
|
-
method: "GET",
|
|
63
|
-
path: "/guide/theme-ids-local",
|
|
64
|
-
kind: "json",
|
|
65
|
-
description: "List theme IDs from local docs",
|
|
66
|
-
},
|
|
67
25
|
// ─── insight ───
|
|
68
26
|
"insight.opinion.list": {
|
|
69
27
|
key: "insight.opinion.list",
|
|
@@ -211,6 +169,41 @@ export const ENDPOINTS = {
|
|
|
211
169
|
kind: "json",
|
|
212
170
|
description: "Search GTS codes (securities)",
|
|
213
171
|
},
|
|
172
|
+
"reference.constant-category": {
|
|
173
|
+
key: "reference.constant-category",
|
|
174
|
+
method: "GET",
|
|
175
|
+
path: "/application/open-reference/constants/category",
|
|
176
|
+
kind: "json",
|
|
177
|
+
description: "List constant categories and their API usage scopes",
|
|
178
|
+
},
|
|
179
|
+
"reference.constant-list": {
|
|
180
|
+
key: "reference.constant-list",
|
|
181
|
+
method: "POST",
|
|
182
|
+
path: "/application/open-reference/constants/getList",
|
|
183
|
+
kind: "json",
|
|
184
|
+
description: "List all constant values of a category",
|
|
185
|
+
},
|
|
186
|
+
"reference.concept-search": {
|
|
187
|
+
key: "reference.concept-search",
|
|
188
|
+
method: "POST",
|
|
189
|
+
path: "/application/open-reference/concepts/search",
|
|
190
|
+
kind: "json",
|
|
191
|
+
description: "Search concept (theme) IDs by keyword",
|
|
192
|
+
},
|
|
193
|
+
"reference.sector-search": {
|
|
194
|
+
key: "reference.sector-search",
|
|
195
|
+
method: "POST",
|
|
196
|
+
path: "/application/open-reference/sectors/search",
|
|
197
|
+
kind: "json",
|
|
198
|
+
description: "Search sector IDs by keyword",
|
|
199
|
+
},
|
|
200
|
+
"reference.sector-constituents": {
|
|
201
|
+
key: "reference.sector-constituents",
|
|
202
|
+
method: "POST",
|
|
203
|
+
path: "/application/open-reference/sectors/constituents",
|
|
204
|
+
kind: "json",
|
|
205
|
+
description: "List constituent securities of a sector",
|
|
206
|
+
},
|
|
214
207
|
// ─── quote ───
|
|
215
208
|
"quote.day-kline": {
|
|
216
209
|
key: "quote.day-kline",
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
const cache = new Map();
|
|
2
2
|
const loaders = {
|
|
3
|
-
"research-areas": () => import("./research-areas.js"),
|
|
4
3
|
"broker-orgs": () => import("./broker-orgs.js"),
|
|
5
4
|
"meeting-orgs": () => import("./meeting-orgs.js"),
|
|
6
|
-
"industries": () => import("./industries.js"),
|
|
7
|
-
"regions": () => import("./regions.js"),
|
|
8
|
-
"announcement-categories": () => import("./announcement-categories.js"),
|
|
9
|
-
"industry-codes": () => import("./industry-codes.js"),
|
|
10
|
-
"theme-ids": () => import("./theme-ids.js"),
|
|
11
5
|
};
|
|
12
6
|
export async function getLookupData(key) {
|
|
13
7
|
if (cache.has(key))
|
|
@@ -29,5 +29,10 @@ export function normalizeRows(value) {
|
|
|
29
29
|
const hasMeta = Object.keys(meta).length > 0;
|
|
30
30
|
return hasMeta ? { ...meta, list: chatRoomList } : chatRoomList;
|
|
31
31
|
}
|
|
32
|
+
if (Array.isArray(record.constants)) {
|
|
33
|
+
const { constants, ...meta } = record;
|
|
34
|
+
const hasMeta = Object.keys(meta).length > 0;
|
|
35
|
+
return hasMeta ? { ...meta, list: constants } : constants;
|
|
36
|
+
}
|
|
32
37
|
return value;
|
|
33
38
|
}
|
package/dist/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated — DO NOT EDIT
|
|
2
|
-
export const CLI_VERSION = "0.
|
|
2
|
+
export const CLI_VERSION = "0.17.0";
|