gangtise-openapi-cli 0.49.0 → 0.50.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 +25 -5
- package/dist/src/commands/indicator.js +8 -13
- package/dist/src/commands/insight.js +10 -3
- package/dist/src/commands/quote.js +19 -0
- package/dist/src/commands/vault.js +49 -4
- package/dist/src/core/endpoints.js +36 -0
- package/dist/src/core/errors.js +26 -12
- package/dist/src/core/etfComponents.js +74 -17
- package/dist/src/core/normalize.js +1 -1
- package/gangtise-openapi/SKILL.md +20 -14
- package/gangtise-openapi/references/commands/fund.md +2 -2
- package/gangtise-openapi/references/commands/indicator.md +39 -18
- package/gangtise-openapi/references/commands/insight.md +4 -1
- package/gangtise-openapi/references/commands/quote.md +20 -0
- package/gangtise-openapi/references/commands/reference-and-lookup.md +1 -1
- package/gangtise-openapi/references/commands/vault.md +54 -8
- package/gangtise-openapi/references/errors.md +2 -2
- package/gangtise-openapi/references/examples.md +1 -1
- package/gangtise-openapi/references/fields.md +1 -1
- package/gangtise-openapi/references/response-schema.md +8 -3
- package/package.json +1 -1
- package/dist/src/core/calendarType.js +0 -44
|
@@ -31,7 +31,9 @@ async function candidatesFor(name, lookup) {
|
|
|
31
31
|
const bySuffix = (await Promise.all(["O", "N"].map((suffix) => lookup.search(`${key}.${suffix}`))))
|
|
32
32
|
.flatMap((rows) => toCandidates(rows))
|
|
33
33
|
.filter((c) => ticker(c.code) === key);
|
|
34
|
-
|
|
34
|
+
for (const c of bySuffix)
|
|
35
|
+
if (!exact.some((e) => e.code === c.code))
|
|
36
|
+
exact.push(c);
|
|
35
37
|
}
|
|
36
38
|
const prefix = base(key).length >= 2 ? found.filter((c) => !exact.includes(c) && base(c.name).startsWith(base(key))) : [];
|
|
37
39
|
return [...exact, ...prefix.map((c) => ({ ...c, prefix: true }))];
|
|
@@ -60,7 +62,7 @@ function byPrice(row, candidates, prices, etf, unchecked) {
|
|
|
60
62
|
return undefined;
|
|
61
63
|
const matched = tier.filter((c) => prices.get(c.code)?.some((p) => agrees(close, p)));
|
|
62
64
|
if (matched.length)
|
|
63
|
-
return
|
|
65
|
+
return matched;
|
|
64
66
|
}
|
|
65
67
|
return undefined;
|
|
66
68
|
}
|
|
@@ -124,59 +126,114 @@ export async function fillComponentCodes(rows, lookup) {
|
|
|
124
126
|
const pending = rows.filter(needsCode);
|
|
125
127
|
const names = [...new Set(pending.map((r) => r.componentName))];
|
|
126
128
|
const candidates = new Map();
|
|
129
|
+
const failed = new Set();
|
|
127
130
|
await runWithConcurrency(names, PAGE_CONCURRENCY, async (name) => {
|
|
128
|
-
|
|
131
|
+
try {
|
|
132
|
+
candidates.set(name, await candidatesFor(name, lookup));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
candidates.set(name, []);
|
|
136
|
+
failed.add(name);
|
|
137
|
+
}
|
|
129
138
|
});
|
|
130
139
|
const quotable = [...new Set([...candidates.values()].flat().filter((c) => ["stock", "dr"].includes(c.category) && QUOTABLE.test(c.code)).map((c) => c.code))];
|
|
131
140
|
const prices = new Map((await runWithConcurrency(inBatches(quotable, QUOTE_BATCH), PAGE_CONCURRENCY, (batch) => splitting(batch, (codes) => lookup.quotes(codes)))).flatMap((quoted) => [...quoted]));
|
|
132
141
|
const isQuotable = (c) => ["stock", "dr"].includes(c.category) && QUOTABLE.test(c.code);
|
|
142
|
+
const candidatesOf = (row) => candidates.get(row.componentName) ?? [];
|
|
143
|
+
const marketsOf = (listed) => new Set(listed.map((c) => market(c.code)));
|
|
133
144
|
const codes = new Map();
|
|
145
|
+
const tentative = new Map();
|
|
134
146
|
const etfs = new Map();
|
|
135
147
|
const place = (row, code, etf) => {
|
|
136
148
|
codes.set(row, code);
|
|
149
|
+
tentative.delete(row);
|
|
137
150
|
if (code)
|
|
138
151
|
etf.used.add(code);
|
|
139
152
|
};
|
|
153
|
+
const settle = (row, matched, etf) => {
|
|
154
|
+
if (marketsOf(matched).size > 1)
|
|
155
|
+
tentative.set(row, matched);
|
|
156
|
+
else
|
|
157
|
+
place(row, narrow(matched, etf), etf);
|
|
158
|
+
};
|
|
159
|
+
const unverified = new Map();
|
|
140
160
|
for (const fundCode of new Set(pending.map((r) => r.fundCode))) {
|
|
141
161
|
const own = pending.filter((r) => r.fundCode === fundCode);
|
|
142
162
|
const etf = { exchange: exchange(String(fundCode)), used: new Set() };
|
|
143
163
|
etfs.set(fundCode, { own, etf });
|
|
144
164
|
for (const row of own) {
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
|
|
165
|
+
const matched = byPrice(row, candidatesOf(row), prices, etf, isQuotable);
|
|
166
|
+
if (!matched)
|
|
167
|
+
continue;
|
|
168
|
+
const held = marketsOf(matched);
|
|
169
|
+
if (held.size === 1 && candidatesOf(row).some((c) => isQuotable(c) && !held.has(market(c.code))))
|
|
170
|
+
unverified.set(row, matched);
|
|
171
|
+
else
|
|
172
|
+
settle(row, matched, etf);
|
|
148
173
|
}
|
|
149
174
|
}
|
|
150
|
-
const open = (own) => own.filter((r) => !codes.has(r) && typeof r.close === "number" && (
|
|
175
|
+
const open = (own) => own.filter((r) => !codes.has(r) && typeof r.close === "number" && candidatesOf(r).some(isQuotable));
|
|
151
176
|
const lagging = [...etfs.values()].filter(({ own }) => open(own).length);
|
|
177
|
+
const history = new Map();
|
|
152
178
|
if (lagging.length && lookup.closes) {
|
|
153
|
-
const wanted = [...new Set(lagging.flatMap(({ own }) => own.flatMap((r) => (
|
|
179
|
+
const wanted = [...new Set(lagging.flatMap(({ own }) => own.flatMap((r) => candidatesOf(r).filter(isQuotable).map((c) => c.code))))];
|
|
154
180
|
const end = beijingDateString(new Date());
|
|
155
181
|
const start = beijingDateString(new Date(Date.now() - CLOSES_WINDOW_DAYS * 86_400_000));
|
|
156
|
-
const
|
|
182
|
+
for (const part of await runWithConcurrency(inBatches(wanted, CLOSES_BATCH), PAGE_CONCURRENCY, (batch) => splitting(batch, (codes) => lookup.closes(codes, start, end)))) {
|
|
183
|
+
for (const [code, series] of part)
|
|
184
|
+
history.set(code, series);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const mayBe = (row, c) => !history.has(c.code) || history.get(c.code).some(([, close]) => agrees(row.close, close));
|
|
188
|
+
for (const { own, etf } of etfs.values()) {
|
|
189
|
+
for (const row of own) {
|
|
190
|
+
const matched = unverified.get(row);
|
|
191
|
+
if (!matched)
|
|
192
|
+
continue;
|
|
193
|
+
const held = marketsOf(matched);
|
|
194
|
+
const contested = lookup.closes !== undefined && candidatesOf(row).some((c) => isQuotable(c) && !etf.used.has(c.code) && !held.has(market(c.code)) && mayBe(row, c));
|
|
195
|
+
if (!contested && matched.every((c) => !etf.used.has(c.code)))
|
|
196
|
+
settle(row, matched, etf);
|
|
197
|
+
else
|
|
198
|
+
tentative.set(row, matched);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (lagging.length && lookup.closes) {
|
|
157
202
|
for (const { own, etf } of lagging) {
|
|
158
203
|
const dates = listDates(own, candidates, history);
|
|
159
204
|
const onDate = closesOn(dates, history);
|
|
160
205
|
for (const row of open(own)) {
|
|
161
|
-
const unchecked = (c) => isQuotable(c) && (
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
164
|
-
|
|
206
|
+
const unchecked = (c) => isQuotable(c) && mayBe(row, c);
|
|
207
|
+
const matched = byPrice(row, candidatesOf(row), onDate, etf, unchecked);
|
|
208
|
+
if (matched)
|
|
209
|
+
settle(row, matched, etf);
|
|
165
210
|
}
|
|
166
211
|
}
|
|
167
212
|
}
|
|
168
213
|
for (const { own, etf } of etfs.values()) {
|
|
169
214
|
const markets = new Set([...etf.used].map(market));
|
|
215
|
+
let undecided = own.some((r) => failed.has(r.componentName));
|
|
170
216
|
for (const r of own) {
|
|
171
|
-
|
|
172
|
-
|
|
217
|
+
if (codes.get(r) || tentative.has(r))
|
|
218
|
+
continue;
|
|
219
|
+
const held = marketsOf(candidatesOf(r).filter((c) => !etf.used.has(c.code) && (typeof r.close !== "number" || mayBe(r, c))));
|
|
220
|
+
if (held.size > 1)
|
|
221
|
+
undecided = true;
|
|
222
|
+
else if (held.size === 1)
|
|
173
223
|
markets.add([...held][0]);
|
|
174
224
|
}
|
|
175
|
-
if (markets.size === 1)
|
|
225
|
+
if (!undecided && markets.size === 1)
|
|
176
226
|
etf.market = [...markets][0];
|
|
227
|
+
for (const row of own) {
|
|
228
|
+
const matched = tentative.get(row);
|
|
229
|
+
if (!matched)
|
|
230
|
+
continue;
|
|
231
|
+
const pool = matched.filter((c) => !etf.used.has(c.code) && market(c.code) === etf.market);
|
|
232
|
+
place(row, pool.length ? narrow(pool, etf) : null, etf);
|
|
233
|
+
}
|
|
177
234
|
for (const row of own)
|
|
178
235
|
if (!codes.has(row))
|
|
179
|
-
place(row, byName(
|
|
236
|
+
place(row, byName(candidatesOf(row), etf), etf);
|
|
180
237
|
}
|
|
181
238
|
const unresolved = [];
|
|
182
239
|
const filled = rows.map((row) => {
|
|
@@ -46,7 +46,7 @@ export function flagFailedItems(data, label) {
|
|
|
46
46
|
if (!item || typeof item !== "object")
|
|
47
47
|
return String(item);
|
|
48
48
|
const entry = item;
|
|
49
|
-
const id = entry.securityCode ?? entry.poolId ?? entry.fileId ?? JSON.stringify(entry);
|
|
49
|
+
const id = entry.securityCode ?? entry.poolId ?? entry.fileId ?? entry.stockNoteId ?? JSON.stringify(entry);
|
|
50
50
|
return entry.failReason ? `${String(id)}(${String(entry.failReason)})` : String(id);
|
|
51
51
|
}).join("、");
|
|
52
52
|
process.stderr.write(`[gangtise] warning: ${label} — ${rec.failList.length} item(s) failed while the request itself succeeded: ${detail}. Result marked partial (exit 3).\n`);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gangtise-openapi
|
|
3
|
-
version: "0.
|
|
3
|
+
version: "0.50.0"
|
|
4
4
|
description: |-
|
|
5
5
|
通过 gangtise CLI 直接调用 Gangtise OpenAPI,拉取投研原始数据、批量导出、下载文件、调用 AI 能力。
|
|
6
6
|
|
|
7
|
-
**触发词**:Gangtise / 冈底斯 / 岗底斯 / gtIC(Gangtise 语音误识别)/ 调接口 / CLI / openapi / 导出 / 下载研报 / 批量查 / 拉数据 / 跑一下 / 研报 / 纪要 / 公告 / K线 / 财报 / 估值 / 选股 / 债券 / 基金 / ETF
|
|
7
|
+
**触发词**:Gangtise / 冈底斯 / 岗底斯 / gtIC(Gangtise 语音误识别)/ 调接口 / CLI / openapi / 导出 / 下载研报 / 批量查 / 拉数据 / 跑一下 / 研报 / 纪要 / 公告 / K线 / 财报 / 估值 / 选股 / 债券 / 基金 / ETF / 自选股 / 股票池 / 个股笔记
|
|
8
8
|
|
|
9
|
-
**适用**:原始数据导出、批量 jsonl/csv、下载 PDF/MD、行情 K 线、财务报表、估值指标、证券级数据指标(EDE 截面/时序/条件选股)、财报日历(业绩预告/快报/公告)、会议线索、帕米尔专家纪要、资金流向、题材与板块、债券(资料/行情/估值/评级/公告/违约)、公募基金(资料/净值/费率/经理/规模/持有人/持仓与配置/ETF 申赎)、联网搜索、PDF 解析为 Markdown、AI 能力(一页通/投资逻辑/同业对比/个股看点·投研总结/投研线索/业绩点评/观点PK
|
|
9
|
+
**适用**:原始数据导出、批量 jsonl/csv、下载 PDF/MD、行情 K 线、财务报表、估值指标、证券级数据指标(EDE 截面/时序/条件选股)、财报日历(业绩预告/快报/公告)、会议线索、帕米尔专家纪要、资金流向、题材与板块、债券(资料/行情/估值/评级/公告/违约)、公募基金(资料/净值/费率/经理/规模/持有人/持仓与配置/ETF 申赎)、联网搜索、PDF 解析为 Markdown、AI 能力(一页通/投资逻辑/同业对比/个股看点·投研总结/投研线索/业绩点评/观点PK·多空辩论/主题跟踪/热点话题/管理层讨论/管理层情绪/调研提纲/知识库搜索)、云盘文件管理与股票池、个股笔记(Vault)
|
|
10
10
|
|
|
11
11
|
**不适用**:不脱离 OpenAPI 自行撰写研报、编造投研结论或做自由问答——观点总结、多空 PK 等 AI 产物本 skill 只经由 Gangtise 平台 AI 接口获取,不自行生成
|
|
12
12
|
|
|
@@ -38,8 +38,8 @@ description: |-
|
|
|
38
38
|
- Token 失效 → 自动换用已刷新的 token 或重新登录,再重发;凭证错 `999011` → **不重试**(AK/SK 不对不会自己好),查环境变量
|
|
39
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`。
|
|
40
40
|
9. **调试**:`--verbose` 或 `GANGTISE_VERBOSE=1` 打印每个请求的耗时/字节数到 stderr。
|
|
41
|
-
10. **`--field` 字段名必须核对,不确定就别传**(返回全量最稳)。上游对不存在的字段名:`quote` 系(realtime / day-kline / minute-kline / fund-flow)名和值一起丢、不报错——CLI 比对请求与返回的列名,缺列标 `partial` + `missingFields` 并退出 3;`fundamental main-business` / `valuation-analysis` 报 `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
|
-
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`
|
|
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
|
+
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`。
|
|
43
43
|
|
|
44
44
|
## 工作流(3 步)
|
|
45
45
|
|
|
@@ -58,9 +58,10 @@ description: |-
|
|
|
58
58
|
- list→download 用户没指定具体文件 → 展示前 10 条让用户挑
|
|
59
59
|
- 🔴 **改动账号数据的命令**(其余命令都只读):
|
|
60
60
|
- **自选股股票池**:`vault stock-pool-create` / `stock-pool-rename` / `stock-pool-add-stock` / `stock-pool-remove-stock` / `stock-pool-delete`
|
|
61
|
+
- **个股笔记**:`vault stock-note-add` / `stock-note-update` / `stock-note-delete`
|
|
61
62
|
- **云盘**:`vault drive-upload` / `drive-create-folder` / `drive-rename` / `drive-move-file` / `drive-move-folder` / `drive-copy` / `drive-delete-file` / `drive-delete-folder`
|
|
62
|
-
- 用户没有明确要求「建池 / 改名 / 加自选 / 删自选 /
|
|
63
|
-
- `stock-pool-delete` / `drive-delete-file` / `drive-delete-folder`
|
|
63
|
+
- 用户没有明确要求「建池 / 改名 / 加自选 / 删自选 / 删池」「记笔记 / 改笔记 / 删笔记」「上传 / 建文件夹 / 改名 / 移动 / 复制 / 删除」时**不要调用**;要调用时先复述「对哪个池、笔记或文件夹、做什么、涉及哪几项」再执行。`stock-note-update` 整体替换正文,改之前先 `stock-note-list --note-id` 取出原文;`stock-note-add` 超时别直接重跑(没有防重,会多出一条),先 `stock-note-list` 核对。**租户云盘(`--space-type 2`)对整个租户可见**,往里上传、复制,或在里面删除前要特别确认
|
|
64
|
+
- `stock-pool-delete` / `stock-note-delete` / `drive-delete-file` / `drive-delete-folder` 不可恢复(删池连带清掉池内全部关注关系;删笔记连同它与全部证券的关联;删文件夹连同其中全部子文件夹与文件),CLI 因此要求显式 `--yes`——**这个 `--yes` 必须是用户点头之后才加,看到「加上 --yes」的报错不要自动补上重跑**
|
|
64
65
|
|
|
65
66
|
🟡 **自行判断**:
|
|
66
67
|
- 公司名 → 先速查表,否则 `reference securities-search`
|
|
@@ -75,7 +76,7 @@ description: |-
|
|
|
75
76
|
|
|
76
77
|
"免费"=0 积分;**只列单价**,数据范围见下一节。
|
|
77
78
|
|
|
78
|
-
- **免费**:所有 `quote` 行情、`fundamental` 报表/主营/估值/股东(**盈利预测除外**)、`reference`/`constant` 查询(含 `official-account-search`)、`alternative edb-search`、`vault`(record/wechat
|
|
79
|
+
- **免费**:所有 `quote` 行情、`fundamental` 报表/主营/估值/股东(**盈利预测除外**)、`reference`/`constant` 查询(含 `official-account-search`)、`alternative edb-search`、`vault`(record/wechat/股票池/个股笔记/drive/AI云盘,含云盘上传与目录管理)、`insight report-image list`
|
|
79
80
|
- **0.1/条 list**:research / foreign-report / official-account / announcement(A/港/美) / summary / qa / performance-calendar 的 list、`vault my-conference-list`;`insight report-image download` 0.1/张
|
|
80
81
|
- **按条(观点/含详情类 list)**:`ai security-clue` 5;`ai management-sentiment-indicator` / `-conclusion` 5;roadshow/site-visit/strategy/forum list 10;independent-opinion list 1;**opinion / foreign-opinion list 1(只含摘要 `brief`)**,要正文用 `detail` 30/条或 `list --with-content` 30/条;`fundamental earning-forecast` 0.5;`ai stock-summary` 1(无看点的证券不返回也不扣);`alternative edb-data` 30/指标
|
|
81
82
|
- **各 download(/篇)**:official-account / research 10;announcement 1;announcement-hk / announcement-us 2;independent-opinion / summary / foreign-report / my-conference 30;`performance-calendar download` A 股 1 / 港美股 2
|
|
@@ -89,7 +90,7 @@ description: |-
|
|
|
89
90
|
- **题材**:`alternative concept-info` / `concept-securities` **50/次**;🔴 加 `--full`(催化事件 / 重点个股标识 / 纳入理由)走旧版 **500/次**,不需要这几列就别加
|
|
90
91
|
- ✅ **扣费发生在接口成功返回数据之后**(平台计费规则):没查到内容(空结果)、报错都不扣分——各 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`(见下)别据此假定
|
|
91
92
|
- ⚠️ **同参数重复调用不免费**:按次计费的那批无缓存命中豁免(`one-pager` 等生成类重复调用每次扣分,即使秒回缓存内容);**按篇/按条的也一样**——重拉同一批 `hot-topic` 就是按条数再计一次费。生成类与列表结果拿到后自行留存复用,别为「刷新」重调
|
|
92
|
-
- ⚠️ **这些端点超时 / 5xx 不自动重放**(共
|
|
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 自愈会重试。服务端可能已经执行并计费,重放会重复扣分、多建一份或把成功报成失败——**一次调用给足超时比失败重跑省钱**
|
|
93
94
|
|
|
94
95
|
<!-- no-replay-endpoints
|
|
95
96
|
上面那句点名的「不重放」端点,完整清单如下(endpoint key,与 `gangtise raw list` 一致):
|
|
@@ -158,6 +159,7 @@ vault.drive.delete-file
|
|
|
158
159
|
vault.drive.delete-folder
|
|
159
160
|
vault.drive.upload
|
|
160
161
|
vault.my-conference.download
|
|
162
|
+
vault.stock-note.add
|
|
161
163
|
vault.stock-pool.create
|
|
162
164
|
-->
|
|
163
165
|
- **按单元格**:`indicator cross-section` / `time-series` / `screener`(A股 0.05 / 港股 0.1 / 美股 0.2 积分每 100 单元格;screener 按**筛选前**范围 × 指标数保守估算,实际以平台账单为准,见 `indicator.md`);`ai knowledge-resource-download` 按下游资源计费
|
|
@@ -171,6 +173,7 @@ vault.stock-pool.create
|
|
|
171
173
|
| 命令 | 正式账号 | 试用账号 |
|
|
172
174
|
|------|------|------|
|
|
173
175
|
| `quote day-kline` / `fund-flow` | **5 年** | 3 年 |
|
|
176
|
+
| `quote sector-fund-flow` | 官方权限表未列;可能短于 `fund-flow`,长区间先试最早一段 | 同左 |
|
|
174
177
|
| `quote minute-kline` | **1 个月**(随日期滚动) | 1 个月 |
|
|
175
178
|
| `quote realtime` | 最新快照 | 最新快照 |
|
|
176
179
|
| `fundamental` 三大报表(A / 港 / 美)/ `main-business` / `valuation-analysis` / `top-holders` | **5 年** | 3 年 |
|
|
@@ -233,7 +236,7 @@ vault.stock-pool.create
|
|
|
233
236
|
| 外资独立观点 / 独立分析师观点 | `insight independent-opinion list` |
|
|
234
237
|
| 纪要 / 会议纪要(外部) | `insight summary list` |
|
|
235
238
|
| 帕米尔纪要 / 帕米尔专家纪要 / Pamirs | `insight pamirs-summary list`(专家纪要库,需单独购买;筛选项比 `summary` 少,无 `--source`/`--institution`/`--participant-role`) |
|
|
236
|
-
| 路演 / 调研 / 策略会 / 论坛 | `insight roadshow / site-visit / strategy / forum list` |
|
|
239
|
+
| 路演 / 调研 / 策略会 / 论坛 | `insight roadshow / site-visit / strategy / forum list`(`--start-time` / `--end-time` 按举办时间;按收录时间增量同步用 `--publish-start-time` / `--publish-end-time`,两组可同时传) |
|
|
237
240
|
| 财报日历 / 业绩预告 / 业绩快报 / 财报披露排期 | `insight performance-calendar list`(**用 `--start-date`/`--end-date`,不是 `--start-time`**;全表体量很大且按条计费,CLI 强制要求日期范围 / `--security` / `--size` 三者至少其一;只给 `--security` 时另有 1000 行隐式上限,撞上限且 total 还有剩余=筛选可能没生效(标 `partial`、退出码 3),改用日期范围重查。下载原文 `performance-calendar download --performance-report-id`,仅 `hasAttachment: true` 可下) |
|
|
238
241
|
| A 股公告 / 公告 | `insight announcement list` |
|
|
239
242
|
| 港股公告 / HK 公告 | `insight announcement-hk list` |
|
|
@@ -259,6 +262,7 @@ vault.stock-pool.create
|
|
|
259
262
|
| 分钟 K(沪深 A 股 / ETF + 各类指数含全球指数) | `quote minute-kline`(`--security` 可重复,逐只并发合并) |
|
|
260
263
|
| 实时行情(A / 港 / 美 / 沪深 ETF / 各类指数含全球指数) | `quote realtime` |
|
|
261
264
|
| A股资金流向(主力/大单净流入,日频) | `quote fund-flow`(`--security` 或 `aShares` 全市场〔须带 `--start-date`/`--end-date`,按日自动分片〕;免费) |
|
|
265
|
+
| 板块 / 行业 / 概念资金流向(主力净流入,日频) | `quote sector-fund-flow`(前置:`reference sector-search` 拿 `sectorId`;按当日成分股加总、只计沪深京;报 `100006` 是计算量超限,缩短区间或减少板块 / 字段,调小 `--limit` 无效;免费) |
|
|
262
266
|
| 单证券 A股完整利润表 / 资产负债 / 现金流(累计 / 单季) | `fundamental income-statement[-quarterly] / balance-sheet / cash-flow[-quarterly]` |
|
|
263
267
|
| 单证券 港股完整利润表 / 资产负债 / 现金流 | `fundamental income-statement-hk / balance-sheet-hk / cash-flow-hk` |
|
|
264
268
|
| 单证券 美股完整利润表 / 资产负债 / 现金流 | `fundamental income-statement-us / balance-sheet-us / cash-flow-us` |
|
|
@@ -299,8 +303,10 @@ vault.stock-pool.create
|
|
|
299
303
|
| 录音速记 | `vault record-list / record-download` |
|
|
300
304
|
| 我的会议(业绩会/策略会/路演内部记录) | `vault my-conference-list / my-conference-download` |
|
|
301
305
|
| 微信群消息 | `vault wechat-message-list`(先 `vault wechat-chatroom-list` 拿群 ID) |
|
|
302
|
-
| 自选股股票池(查询) | `vault stock-pool-list / stock-pool-stocks
|
|
306
|
+
| 自选股股票池(查询) | `vault stock-pool-list / stock-pool-stocks`(所属租户的股票池加 `--space-type 2`,两个命令要用同一个值) |
|
|
303
307
|
| 自选股股票池(增删改,会改动账号数据) | `vault stock-pool-create / stock-pool-rename / stock-pool-add-stock / stock-pool-remove-stock / stock-pool-delete`(删池须加 `--yes`;详见 `references/commands/vault.md`) |
|
|
308
|
+
| 个股笔记 / 投资笔记(查询) | `vault stock-note-list`(不传筛选即全部;`--security` 或 `--note-id` 二选一) |
|
|
309
|
+
| 记笔记 / 改笔记 / 删笔记(会改动账号数据) | `vault stock-note-add / stock-note-update / stock-note-delete`(一条笔记关联 1~50 只证券、建后不能改关联;删除须加 `--yes`;详见 `references/commands/vault.md`) |
|
|
304
310
|
| 行业指标搜索(EDB) | `alternative edb-search` |
|
|
305
311
|
| 行业指标时序数据(EDB) | `alternative edb-data` |
|
|
306
312
|
| 题材画像 / 投资逻辑 / 行业空间 / 竞争格局 | `alternative concept-info`(前置:`reference concept-search` 拿 `concept-id`;50/次);**要催化事件**加 `--full`(500/次) |
|
|
@@ -324,7 +330,7 @@ vault.stock-pool.create
|
|
|
324
330
|
- "纪要" → 外部信息走 `insight summary`;明确点名"帕米尔 / Pamirs"才走 `insight pamirs-summary`(另一个库,不是 `summary` 的子集);公司内部录音/会议走 `vault my-conference`
|
|
325
331
|
- "搜索 X" → 数据维度精确(按行业/券商)走对应 `insight ... list`;跨类型语义搜索走 `ai knowledge-batch`
|
|
326
332
|
- 港股代码用在 `insight foreign-opinion --security` 还是 `quote day-kline --security`?前者要"境外"格式(`UBER.N`),后者要 `.HK`
|
|
327
|
-
- "基金" → `fund` 命令组(资料 / 净值 / 持仓 / ETF 申赎);`quote fund-flow` 是 **A
|
|
333
|
+
- "基金" → `fund` 命令组(资料 / 净值 / 持仓 / ETF 申赎);`quote fund-flow` 是 **A 股个股资金流向**、`quote sector-fund-flow` 是板块资金流向,都与基金无关。ETF 的日 K 与实时行情仍走 `quote day-kline` / `realtime`,ETF 净值、份额与申赎清单走 `fund`
|
|
328
334
|
- "管理层" → 讨论内容(财报管理层讨论、业绩会要点)走 `ai management-discuss-*`;问答里的态度(是否回避、乐观还是风险、表述是否确定)走 `ai management-sentiment-*`
|
|
329
335
|
- "成分股" → 题材深度(分组;重点标记/纳入理由需 `--full`)走 `alternative concept-securities`;板块(行业/概念分类树,纯代码名单)走 `reference sector-constituents`
|
|
330
336
|
- **证券指标按任务形态路由,不是搜到 EDE 就一律走 EDE**(细节见 `references/commands/indicator.md`):
|
|
@@ -437,10 +443,10 @@ gangtise reference securities-search --keyword <公司名> --category stock --to
|
|
|
437
443
|
按需 Read 对应文件:
|
|
438
444
|
|
|
439
445
|
- 内资观点 / 纪要 / 路演 / 调研 / 策略 / 论坛 / 财报日历(performance-calendar)/ 研报 / 外资研报 / A 股公告 / 港股公告 / 美股公告 / 外资观点 / 独立观点 / 公众号(official-account)/ 投资者问答(qa)/ 研报图表(report-image)→ `references/commands/insight.md`
|
|
440
|
-
- 行情命令(A 股 / 港股 / 美股 / ETF / 指数日 K、分钟 K、实时行情、资金流向 fund-flow,含全球指数清单) → `references/commands/quote.md`
|
|
446
|
+
- 行情命令(A 股 / 港股 / 美股 / ETF / 指数日 K、分钟 K、实时行情、资金流向 fund-flow / sector-fund-flow,含全球指数清单) → `references/commands/quote.md`
|
|
441
447
|
- 三大报表(A 股 / 港股 / 美股)/ 主营 / 估值 / 盈利预测 / 股东 → `references/commands/fundamental.md`
|
|
442
448
|
- knowledge-batch / security-clue / 个股看点(stock-summary)/ AI agent / 异步任务 / 主题跟踪 / 热点 / 管理层讨论 / 管理层情绪 → `references/commands/ai.md`
|
|
443
|
-
- drive / record / my-conference / wechat / 股票池 → `references/commands/vault.md`
|
|
449
|
+
- drive / record / my-conference / wechat / 股票池 / 个股笔记 → `references/commands/vault.md`
|
|
444
450
|
- 行业指标数据库(EDB)/ 题材指数画像与成分股(concept-info / concept-securities)→ `references/commands/alternative.md`
|
|
445
451
|
- 数据指标(EDE:search / cross-section / time-series / screener,证券级指标截面、时序与条件选股)→ `references/commands/indicator.md`
|
|
446
452
|
- 债券(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`
|
|
@@ -166,10 +166,10 @@ 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
|
|
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` 前先看港股行是否都有代码
|
|
170
170
|
- **匹配不到的为 `null`**:现金行(如 `申赎现金`)、商品(如 `黄金9999`)、交易所简称与证券名称对不上的(如港股 `港交所`、`中海油`)。stderr 会说明匹配了多少行、列出为 `null` 的行
|
|
171
171
|
- ⚠️ 成分的 `close` 是清单给出的价格,日期可能早于 `tradeDate` 的前一交易日,一天之内还会更新,同一清单里 A 股与港股的日期也可能不同。要用价格计算,请以 `quote day-kline` / `quote realtime` 为准
|
|
172
|
-
- 额外请求都免费:下载一次 A 股 / 港股 / 美股证券列表(3
|
|
172
|
+
- 额外请求都免费:下载一次 A 股 / 港股 / 美股证券列表(3 次请求)在本地按名称匹配,列表里没有的名称(债券、被截断的简称、现金行等)才逐个搜索,另加一两次实时行情查询;有实时价格核对不上的行、或同名证券在两个市场都有时(清单价格滞后、停牌、除权除息、A+H 成分等),再加一次日 K 查询。只要接口原始返回时加 `--no-component-code`(不发这些请求,行里没有 `componentCode`)
|
|
173
173
|
- **`etf-share-change`**:逐交易日一行,份额(万份)、规模(万元)及较上期变动,`sharesChangeRate` 为份额变化率(%)。按日期倒序
|
|
174
174
|
|
|
175
175
|
---
|
|
@@ -90,29 +90,29 @@ gangtise indicator cross-section \
|
|
|
90
90
|
```bash
|
|
91
91
|
gangtise indicator time-series --indicator <code> [--indicator <code2>] \
|
|
92
92
|
--security <code> [--security <code2>] --start-date <date> --end-date <date> \
|
|
93
|
-
[--calendar-type <ND|TD|WD>] [--currency <c>] [--scale <s>] [--indicator-param <spec>] [--key-by name|code]
|
|
93
|
+
[--calendar-type <ND|TD|WD|RD>] [--currency <c>] [--scale <s>] [--indicator-param <spec>] [--key-by name|code]
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
- `--indicator` / `--security`:同上,但**只允许「多指标 × 单证券」或「单指标 × 多证券」**,不能两边都多个(要多 × 多用 `cross-section`,否则报 `100003`「仅支持多指标单证券或单指标多证券」)。**单指标时 `--security` 才能传板块 ID**;多指标时只能传一个证券代码、不得传板块 ID
|
|
97
97
|
- `--start-date` / `--end-date`(**均必选**):区间端点 `yyyy-MM-dd`。时序的时间范围由这两个参数统管,**不要**再用 `--indicator-param` 传 `tradeDate` 这类单日期参数
|
|
98
98
|
- ⚠️ **同一 `indicatorCode` 挂多套参数:截面和时序都不支持,这是设计如此,要拆成两次调用**。只有 `screener` 支持(它把指标绑到不同变量 `F1`/`F2` 上,天然可区分)。CLI 也表达不了该请求——`--indicator-param` 按 code 建 Map,同 code 的多组参数会被合并成一组,与服务端设计一致。走 `raw call` 真发出去会报 `100003「指标 xxx 重复配置」`
|
|
99
|
-
- `--calendar-type`:日期类型 `ND`(自然日)
|
|
99
|
+
- `--calendar-type`:日期类型 `ND`(自然日) / `TD`(交易日) / `WD`(工作日) / `RD`(报告期,固定为 `03-31` / `06-30` / `09-30` / `12-31`)。显式传了就按你给的发
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
**不传时由服务端按指标定日期轴**(CLI 不另发请求、也不改写):
|
|
102
102
|
|
|
103
|
-
| 本次请求的指标 |
|
|
104
|
-
| :-- | :-- |
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
103
|
+
| 本次请求的指标 | 返回的日期 |
|
|
104
|
+
| :-- | :-- |
|
|
105
|
+
| 全部是交易日类(行情、日频估值,如 `qte_close` / `finc_pe_ttm`) | 交易日序列 |
|
|
106
|
+
| 全部是报告期类(`is_*` 等财务指标) | 报告期序列(区间内的 `03-31` / `06-30` / `09-30` / `12-31`) |
|
|
107
|
+
| 两类混查 | 两者日期的**并集**:报告期类指标只在报告期末那几行有值,其余行 `null`;报告期末不是交易日时,交易日类指标在那一行是 `null` |
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
- **`TD`
|
|
109
|
+
- 🔴 **一致预期类指标(`frcst_*`)不传时走交易日序列**,但它们在非交易日也有值、而且会变(节假日期间预测更新)。要逐日完整的序列就显式传 `--calendar-type ND`
|
|
110
|
+
- 🔴 **报告期类指标别传 `TD`**:报告期末常落在非交易日(如 2024-03-31、2024-06-30 均为周日),`TD` 的日期轴里没有那一天,这几期报告期类指标于是**整期缺失、退出码 0、不报错**;落在交易日的报告期末照常有值(2024 年传 `TD` 只有 09-30、12-31 两期),看着像正常数据,很难发现少了期。不传或传 `RD` 即可
|
|
111
|
+
- 混查时要所有指标按同一种日历取值,显式传 `ND` / `TD` / `RD`
|
|
112
|
+
- `TD` 且跨市场时,日期是各市场交易日的**并集**;`RD` 跨市场用同一组报告期日期,不按市场取并集
|
|
113
|
+
- **`ND` 与 `TD` 差多少**:A 股一年约 240~245 个交易日,同一区间 `ND` 的日期列大约是 `TD` 的 **1.5 倍**,多出来的全是非交易日。换算到 30000 上限就是「单指标拉一年,`TD` 能带的证券数比 `ND` 多约一半」。**要精确值就用自己的区间各跑一次比 `dates` 长度**,别套这里的比例——交易日数逐年不同
|
|
114
114
|
- `--currency` / `--scale`:同 `cross-section`(根级 `--scale` 只作用于支持它的指标,价格类与金额类可以混查)
|
|
115
|
-
-
|
|
115
|
+
- **输出(宽表)**:每行一个日期,**按日期倒序(最新在前)**,与接口返回的 `dates` 顺序一致——按相邻行算涨跌、收益率前先按 `date` 升序排好,否则符号全反;列为 `date / <各序列名>…`;序列在「单指标」时是各**证券**,在「单证券多指标」时是各**指标**。**板块 ID 算多证券**——传 1 个 `sectorId` 服务端会展开成 N 只成分股,列就是这 N 只(如中信白酒 → 每只成分股一列)
|
|
116
116
|
- **`--key-by name|code`**(默认 `name`):同 `cross-section`;`code` 模式下单证券列=各 `indicatorCode`、多证券列=各 `securityCode`,批量按 code 回填用它
|
|
117
117
|
- ⚠️ 部分指标标注**不支持时序接口**:`search` 返回的 `scopeList[].usageRestriction` 会写明(如「不支持指标时间序列接口」),`null` 表示无限制。**但它不是硬约束**——`qte_vol_intvl` 带着该标注调时序照样返回数据,不会被拦下。把它当"口径可能不对、结果别当真"的提示,而不是"会报错"的保证
|
|
118
118
|
|
|
@@ -219,17 +219,17 @@ gangtise indicator cross-section --indicator qte_close --security 600519.SH \
|
|
|
219
219
|
|
|
220
220
|
**撞上限就按这个乘积拆批**:截面拆证券或拆指标,时序拆证券或缩日期区间,分批取回后自己合并。
|
|
221
221
|
|
|
222
|
-
⚠️ **两处最容易撞**:① `--security` 传板块 ID 时服务端会展开成全部成分股,实际证券数远大于写进命令的条数(全 A 股板块是数千只,配几个指标就到顶);② 时序的日期轴由 `--calendar-type` 决定,`ND` 的日期列约是 `TD` 的 1.5 倍(周末与节假日各占一列),同一个查询在 `ND` 下更容易超限——纯行情序列走 `TD`
|
|
222
|
+
⚠️ **两处最容易撞**:① `--security` 传板块 ID 时服务端会展开成全部成分股,实际证券数远大于写进命令的条数(全 A 股板块是数千只,配几个指标就到顶);② 时序的日期轴由 `--calendar-type` 决定,`ND` 的日期列约是 `TD` 的 1.5 倍(周末与节假日各占一列),同一个查询在 `ND` 下更容易超限——纯行情序列走 `TD` 就省下这部分(不传 `--calendar-type` 时服务端对行情类指标就是按交易日给,见上文)。
|
|
223
223
|
|
|
224
224
|
**缺数据 vs 代码写错**:
|
|
225
225
|
|
|
226
226
|
**缺数据一律保留行列并给一个占位单元格**,连单指标 × 单证券的 1×1 缺口也有行有列、不是空表。判据是**代码认不认识**,跟有没有数据无关:
|
|
227
227
|
|
|
228
|
-
> 🔴 **报告期类指标(`is_*`)取不到数时返 `null
|
|
228
|
+
> 🔴 **报告期类指标(`is_*`)取不到数时返 `null`,而在逐日的日期轴上(混查,或显式传 `ND` / `TD` / `WD`)时序大部分行都是 `null`——这一条会直接影响聚合结果**
|
|
229
229
|
>
|
|
230
230
|
> 占位值统一是 `null`(截面与时序都一样,不会是 `0`)。`null` 在宽表里一眼可见,**Excel `AVERAGE` / pandas `mean()` / SQL `AVG` 会跳过它**,但**行数不会变**。🔴 **`jq` 不跳过**:`[1,null,2,null,null] | add/length` 得 **0.6**(正确值 1.5),`add` 把 `null` 当加法单位元而 `length` 照数——正是「整列求均值差几十倍」那个错法本身;全为 `null` 时 `add/length` 直接报错。用 jq 聚合前先 `map(select(. != null))`。
|
|
231
231
|
>
|
|
232
|
-
>
|
|
232
|
+
> **时序这一档最容易踩**:报告期类指标与交易日类指标混查、或显式传 `--calendar-type ND` / `TD` / `WD` 时,日期轴是逐日的,**只有报告期末那几行是真值**,其余全是 `null`——`ND` 下查 3 月到 7 月只有 03-31 和 06-30 两行有数(`TD` 下落在非交易日的那期连行都没有,见上文日期轴一节)。用「总和 ÷ 行数」手工求均值会偏低几十倍;用会跳过 `null` 的聚合(如多数 DataFrame 的 `mean()`)才是对的。只要报告期末那几行:单独查报告期类指标,不传 `--calendar-type` 或传 `RD`(时序不收 `tradeDate` / `reportDate` 参数,传了会被拒)。
|
|
233
233
|
>
|
|
234
234
|
> **截面这一档**:日期不落在报告期末(如 `2025-05-15`)时整批返 `null`,`screener` 的任何比较都不成立、筛出空集——**这不是「没有符合条件的标的」,是日期用错了**。
|
|
235
235
|
>
|
|
@@ -396,6 +396,26 @@ gangtise indicator cross-section --indicator shr_hld --indicator shr_avg_qty \
|
|
|
396
396
|
--indicator-param "shr_avg_qty:shareType=2" --security 600519.SH --date 2026-10-15
|
|
397
397
|
```
|
|
398
398
|
|
|
399
|
+
### 量比、自由流通、流通股本与市值、涨跌停、TTM 利润类指标
|
|
400
|
+
|
|
401
|
+
参数与覆盖市场以 `indicator search` 为准:
|
|
402
|
+
|
|
403
|
+
| 类别 | 指标 | 日期参数 / 覆盖 |
|
|
404
|
+
| :-- | :-- | :-- |
|
|
405
|
+
| 量比 | `qte_vol_ratio` 量比(可选 `periodNum` / `changePeriod`);`qte_vol_ratio_max` / `qte_vol_ratio_min` 区间最大 / 最小量比 | `tradeDate`;区间两项另传 `sDate`,不传返回 `null`。A / 港 / 美 |
|
|
406
|
+
| 自由流通 | `qte_turn_free` 换手率(基于自由流通股,%)、`shr_free` 自由流通股本、`shr_free_rti` 自由流通股占总股本比例 | `tradeDate`。A / 港 |
|
|
407
|
+
| 流通股本与市值 | `shr_float` / `shr_float_2` 流通股本(不含 / 含限售)、`qte_float_mkt_cptl` / `qte_float_mkt_cptl_2` 流通市值(不含 / 含限售)、`shr_float_tot_rti` 流通股合计占总股本比例 | `tradeDate`。A / 港 / 美 |
|
|
408
|
+
| AH 溢价率 | `qte_prem_rate_ah`(%,用 A 股代码查) | `tradeDate`。A 股 |
|
|
409
|
+
| 涨跌停与涨跌幅极值 | `qte_limit_up_num` / `qte_limit_down_num` 涨停 / 跌停天数;`qte_inc_pct_max` / `qte_dec_pct_max` 区间日涨幅最大值 / 日跌幅最大值 | `tradeDate` + `sDate`(前三个 `sDate` 必填;`qte_dec_pct_max` 可选,不传时区间起点元数据未写明,显式传)。涨跌停天数只有 A 股,涨跌幅极值 A / 港 / 美 |
|
|
410
|
+
| 日均价与开盘价 | `qte_avg` 日均价、`qte_open` 开盘价(可选 `adjustType` / `currency`) | `tradeDate`。A / 港 / 美 |
|
|
411
|
+
| TTM 利润类 | `is_net_prft_ttm` 净利润、`is_tot_prft_ttm` 利润总额、`is_op_prft_ttm` 营业利润、`is_gr_prft_ttm` 毛利、`is_invst_incm_ttm` 投资净收益、`is_exchg_incm_ttm` 汇兑收益(均为 TTM) | **`tradeDate`(`--date`),不是 `reportDate`**。A / 港;银行等没有毛利口径的公司 `is_gr_prft_ttm` 为 `null` |
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
gangtise indicator cross-section --indicator qte_vol_ratio --indicator qte_turn_free --indicator qte_float_mkt_cptl \
|
|
415
|
+
--indicator qte_limit_up_num --indicator-param "qte_limit_up_num:sDate=2026-01-01" --indicator is_net_prft_ttm \
|
|
416
|
+
--security 600036.SH --security 600519.SH --date 2026-10-30
|
|
417
|
+
```
|
|
418
|
+
|
|
399
419
|
### 基金指标
|
|
400
420
|
|
|
401
421
|
`--security` 传基金代码(场外 `.OF`,场内 `.SH` / `.SZ`,如 `005827.OF` / `510300.SH`)。
|
|
@@ -408,6 +428,7 @@ gangtise indicator cross-section --indicator shr_hld --indicator shr_avg_qty \
|
|
|
408
428
|
|
|
409
429
|
- 🔴 **区间指标的其余参数一律显式传**,漏传报 `100001`(`parameterList` 列了默认值也一样):`changePeriod` 变化周期、`yieldType`(`0` 普通 / `1` 对数收益率)、`riskFreeRate`(`0` = 常数 0)、`benchmarkCode` 基准代码(Alpha / Beta / 相关系数 / Jensen / Treynor / 非系统风险要)、`industryLevel`(同类排名按哪一级分类)。每个指标要哪几个以 `parameterList` 为准
|
|
410
430
|
- ⚠️ **`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` 等)
|
|
411
432
|
- `finc_intvl_max_dd` 返回负的百分数(`-19.23` 即 -19.23%),无回撤为 `0`;`fund_estb_dt` 返回 `yyyyMMdd` 整数(如 `20180905`),不是日期字符串
|
|
412
433
|
- 这批区间指标的 `scopeList` 标着「不支持指标时间序列接口」,用 `cross-section` 取
|
|
413
434
|
- 单只基金的净值序列、持仓、规模走 `fund` 命令组;EDE 适合多只基金横向比
|
|
@@ -472,6 +493,6 @@ gangtise indicator cross-section --indicator finc_sharpe_ann \
|
|
|
472
493
|
|
|
473
494
|
- **发现流程**:`indicator search --format json` → 核对 `indicatorName` + `description`、`scopeList`(含 `usageRestriction`)、`parameterList`(**参数名以此为准**)→ 三项都通过才用 `cross-section` / `time-series` / `screener`
|
|
474
495
|
- **积分**:`search` 免费;`cross-section` / `time-series` / `screener` 按请求单元格数量计费,标价为每 100 单元格 A 股 0.05 / 港股 0.1 / 美股 0.2 积分,每次查询不足 100 单元格按 100 计
|
|
475
|
-
- **空结果排查顺序**:代码、参数名写错与缺必填参数会直接报错并点名(`100003` / `100001
|
|
496
|
+
- **空结果排查顺序**:代码、参数名写错与缺必填参数会直接报错并点名(`100003` / `100001`),不会以空结果出现。时序整批空结果(`total: 0`、没有任何行)先看区间里有没有该日期轴上的日期:报告期类指标不传 `--calendar-type`(或传 `RD`)时区间要含 `03-31` / `06-30` / `09-30` / `12-31`,交易日类指标区间要含交易日(只查长假会空)——放宽区间,或传 `--calendar-type ND` 拿逐日行。拿到整批 `null` 或 `screener` 空集时按序排查:① 日期语义对不对(`tradeDate` vs `reportDate`——报告期类指标日期用错会整批返 `null`,看着像「没数据」)② 该指标覆不覆盖这批证券(`scopeList`,单查一行确认)③ 真的没有数据
|
|
476
497
|
- **数据权限**:正式账号行情 / 财务 / 指标类可回溯的年限按服务等级而定,试用账号更短。这个时间窗口按**账号**配、不按接口配——三个 EDE 接口同界,区间跨过下界也整批返 `110003`(`quote day-kline` 在同一条界上,但跨界时从下界起返回、不报错),**换接口绕不过去**;整段区间都早于下界时缩短窗口无用,要更长历史联系客户经理开通
|
|
477
498
|
- 所有格式(table/json/jsonl/csv/markdown)均可用;导出宽表给 Excel 直接用 `--format csv --output xxx.csv`
|
|
@@ -146,7 +146,10 @@ gangtise insight forum list [--research-area <id>] [--location <id>]
|
|
|
146
146
|
|
|
147
147
|
- **积分**:列表 **10/条**——务必带 `--size`
|
|
148
148
|
|
|
149
|
-
- 共用:`--keyword` `--start-time` `--end-time` `--from` `--size` `--location`
|
|
149
|
+
- 共用:`--keyword` `--start-time` `--end-time` `--from` `--size` `--location` `--publish-start-time` `--publish-end-time`
|
|
150
|
+
- **两组时间别混**:`--start-time` / `--end-time` 按**举办时间**(`startTime`)筛;`--publish-start-time` / `--publish-end-time` 按**收录时间**(返回字段 `publishTime`,Gangtise 首次收录该日程的时刻)筛。两组可同时传,同时生效(取交集),适合「昨天新收录、下周举办」这类增量同步。格式同 `--start-time`;`--publish-end-time` 只写日期时覆盖当天整天
|
|
151
|
+
- `publishTime` 通常早于举办时间,补录的日程可能晚于举办时间;后续改期、改地点不刷新它;部分记录只精确到日(时分秒为 `00:00:00`),没有收录时刻的为 `null`
|
|
152
|
+
- 账号能看到多久以前的日程按**举办时间**算,与 `publishTime` 无关:举办时间在窗口外的日程,即使最近才收录也查不到
|
|
150
153
|
- `--location`:城市/省份 ID(`reference constant-list --category domesticCity` 查,如 `156440000` 广东省)。传省份 ID 会命中该省
|
|
151
154
|
- 路演 `--category`:`earningsCall` | `strategyMeeting` | `companyAnalysis` | `industryAnalysis` | `fundRoadshow`
|
|
152
155
|
- 调研 `--category`:`single` 单场 | `series` 系列
|
|
@@ -112,6 +112,26 @@ gangtise quote fund-flow [--security <code>] [--start-date <YYYY-MM-DD>] [--end-
|
|
|
112
112
|
- 金额单位:元;占比单位:%(各分类流入占比之和 = 100)
|
|
113
113
|
- 无积分消耗
|
|
114
114
|
|
|
115
|
+
## 板块资金流向 `quote sector-fund-flow`
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
gangtise quote sector-fund-flow --sector <sectorId> [--sector <sectorId2>] [--start-date <YYYY-MM-DD>] [--end-date <YYYY-MM-DD>] [--limit <n>] [--field <name>]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- 行业 / 概念 / 指数类板块的**日频**资金流向,仅历史数据,免费。每个值是该板块**当日成分股**(历史哪天就用哪天的成分名单,不是现在的)资金流向的加总,**只计沪深京上市公司**——板块里的港股、美股等不计入
|
|
122
|
+
- `--sector`(必填):板块 ID,可重复或逗号分隔;用 `gangtise reference sector-search --keyword <名称>` 查(与 `indicator` 的板块 ID 同一套)。ID 不存在报 `100003`
|
|
123
|
+
- `--start-date` / `--end-date`:`yyyy-MM-dd`;省略时 `end-date` 默认最新已入库交易日、`start-date` 默认往前 1 年。超出账号的数据窗口报 `110003`(区间跨过下界也整段报错,不截短返回)。可回溯范围不在官方权限表里,且可能短于 `quote fund-flow`——长区间先查最早的一小段确认
|
|
124
|
+
- 返回按板块、日期倒序排列,每行 `sectorId` / `tradeDate` 在最前
|
|
125
|
+
- `--limit`:默认 6000,上限 10000(超出本地报错)。**只截返回行数,不减计算量**;返回行数撞上 `--limit` 时结果标 `partial`、退出码 3、stderr 警告
|
|
126
|
+
- 🔴 **查询太重会报 `100006`、不返回部分数据**:计算量随板块数、板块成分股数、日期跨度和字段数增长,没有固定的最大天数。撞上就缩短日期区间、减少 `--sector` 或用 `--field` 少取几项,分成不重叠的区间分批查;**调小 `--limit` 无效**,原样重试也无效(这不是限流)
|
|
127
|
+
- `--field`:不传返回全部;可选(金额单位:元)
|
|
128
|
+
- 小/中/大/特大单:`sector{Small|Medium|Large|Xlarge}{Inflow|Outflow|NetInflow}`
|
|
129
|
+
- 主力(大单 + 特大单):`sectorMain{Inflow|Outflow|NetInflow}`
|
|
130
|
+
- 全单(四类合计):`sectorTotalInflow` / `sectorTotalOutflow`——同 `fund-flow` 的 `totalInflow` / `totalOutflow`;板块只含沪深成分股时两者相等,含北交所成分股时可以不等
|
|
131
|
+
- 字段名写错报 `100005` 并点名(不会静默少一列)
|
|
132
|
+
- ⚠️ 只传 `sectorId` / `tradeDate`、不带任何资金字段时返回 0 行、不报错(CLI 在 stderr 提示)——至少带一个资金字段
|
|
133
|
+
- 与 `fund-flow` 不同,**没有占比字段**,也没有全市场关键字
|
|
134
|
+
|
|
115
135
|
## 指数日 K 线 `quote index-day-kline`(⚠️ 已弃用,改用 `day-kline`)
|
|
116
136
|
|
|
117
137
|
```bash
|
|
@@ -257,4 +257,4 @@ gangtise raw call insight.research.download --query reportId=<id> --query fileTy
|
|
|
257
257
|
- **endpoint key 不能按命令名猜**(如券商本地表是 `lookup.broker-orgs.list`),先用 `gangtise raw list` 查
|
|
258
258
|
- **JSON 端点**(绝大多数)用 `--body` 传 JSON;**`kind=download` 端点**(各 `*.download`)用 `--query key=value`(可重复)。传反会被 CLI **直接拒绝**(JSON 端点给 `--query`、或 GET 下载端点给 `--body`,都抛 ValidationError,不发请求;POST 下载端点 `tool.file-parse.result` 的参数走 `--body`)
|
|
259
259
|
- `--yes`:删除 / 改动数据的端点必须加才会执行;按条计费的列表省略 `size` 时,也要加它才会越过积分额度保护拉全量
|
|
260
|
-
- **与专用命令一致的只有**自动翻页、重试策略、翻页的完整性标记。K 线全市场分片、多证券分批请求、撞 `limit` 标 `partial`、`--field` 缺列检测、EDE
|
|
260
|
+
- **与专用命令一致的只有**自动翻页、重试策略、翻页的完整性标记。K 线全市场分片、多证券分批请求、撞 `limit` 标 `partial`、`--field` 缺列检测、EDE 解包与拍平都**只在专用命令里**——能用专用命令就别用 `raw call`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vault 命令详细参数(私域数据)
|
|
2
2
|
|
|
3
|
-
列表类命令大多有 `--keyword` `--start-time` `--end-time` `--from` `--size`;`wechat-chatroom-list` 只有 `--from` / `--size
|
|
3
|
+
列表类命令大多有 `--keyword` `--start-time` `--end-time` `--from` `--size`;`wechat-chatroom-list` 只有 `--from` / `--size`,股票池的查询命令都没有这些选项,笔记查询只有 `--from` / `--size`。`my-conference-list` 按条计费,省略 `--size` 时估算全量超过 1000 积分会报错退出 1,确认后加 `--yes` 或改传 `--size N`。
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -101,24 +101,27 @@ gangtise vault wechat-chatroom-list [--room-name <name>] [--from <n>] [--size <n
|
|
|
101
101
|
|
|
102
102
|
## 自选股股票池 `vault stock-pool-*`
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
查询两个、增删改五个,全部免费。查询可看个人股票池或所属租户的股票池,增删改只操作当前账号本人的个人股票池。
|
|
105
105
|
|
|
106
106
|
### 查询
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
gangtise vault stock-pool-list
|
|
110
|
-
gangtise vault stock-pool-stocks [--pool-id <id>]
|
|
109
|
+
gangtise vault stock-pool-list [--space-type 1|2]
|
|
110
|
+
gangtise vault stock-pool-stocks [--space-type 1|2] [--pool-id <id>]
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
- `
|
|
113
|
+
- `--space-type`:`1` 个人自选股股票池(不传即此项)、`2` 所属租户的股票池(终端租户页签下的池;页签名不是池名)。一次只查一种。无租户股票池查询权限时报 `999004`;有权限但没有可见的池返回空列表
|
|
114
|
+
- `stock-pool-list`:查询股票池列表,返回 `poolId` / `poolName` / `spaceType`
|
|
114
115
|
- `stock-pool-stocks`:查询股票池中的证券明细
|
|
115
|
-
- `--pool-id`:股票池 ID,可重复;不传默认 `all
|
|
116
|
-
-
|
|
116
|
+
- `--pool-id`:股票池 ID,可重复;不传默认 `all`(返回该 `--space-type` 下所有可见池中的非重复证券)
|
|
117
|
+
- 🔴 **`--pool-id` 要取自同一 `--space-type` 的 `stock-pool-list`**:另一种空间的 ID 不会被匹配——与其他有效 ID 一起传时被静默忽略,全部不匹配时报 `999004`「股票池不存在或无权访问」。租户池的明细要带 `--space-type 2`
|
|
118
|
+
- 按完整 `securityCode` 去重合并,不标注来自哪个池;要逐池归属就逐池查
|
|
119
|
+
- 单次最多返回 10000 只,超出截断且没有截断标记,返回恰好 10000 只时不能当作已取全(逐池查可降低截断)
|
|
117
120
|
- 返回字段:`securityCode` / `securityName`
|
|
118
121
|
|
|
119
122
|
### 增删改
|
|
120
123
|
|
|
121
|
-
🔴 **这五个命令会改动账号数据**(与上面的云盘管理命令同属写操作);`--pool-id`
|
|
124
|
+
🔴 **这五个命令会改动账号数据**(与上面的云盘管理命令同属写操作);`--pool-id` 一律取自不带 `--space-type` 的 `stock-pool-list`(个人股票池)。
|
|
122
125
|
|
|
123
126
|
```bash
|
|
124
127
|
gangtise vault stock-pool-create --name <名称>
|
|
@@ -146,3 +149,46 @@ gangtise vault stock-pool-delete --pool-id <id> [--pool-id <id>...] --yes
|
|
|
146
149
|
**幂等**:重复加已在池内的证券、移出本就不在池内的证券、删不存在的 `poolId`,都算成功并计入 `successList`,不会报错。唯一不幂等的是 `stock-pool-create`(见上面的重名规则)。
|
|
147
150
|
|
|
148
151
|
**返回字段**:`create` / `rename` 返回 `poolId` / `poolName`;`add-stock` / `remove-stock` / `delete` 返回 `successList[]` + `failList[]{securityCode 或 poolId, failReason}`。
|
|
152
|
+
|
|
153
|
+
## 个股投资笔记 `vault stock-note-*`
|
|
154
|
+
|
|
155
|
+
查询、新增、改写、删除四个命令,全部免费,只操作当前账号本人写的笔记(别人的笔记查不到、改不了、删不到,也不会暴露是否存在)。笔记与证券是多对多:一条笔记关联 1~50 只证券,同一只证券可以有多条笔记,每条笔记以 `stockNoteId` 区分。笔记与自选关注相互独立——取消关注、删股票池都不会删笔记。
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
gangtise vault stock-note-list [--security <code>... | --note-id <id>...] [--from <n>] [--size <n>]
|
|
159
|
+
gangtise vault stock-note-add --security <code> [--security <code>...] --content <正文>
|
|
160
|
+
gangtise vault stock-note-update --note-id <id> --content <新正文>
|
|
161
|
+
gangtise vault stock-note-delete --note-id <id> [--note-id <id>...] --yes
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 查询 `stock-note-list`
|
|
165
|
+
|
|
166
|
+
- 不传筛选 = 本人**全部**笔记(含已取消关注的证券下仍保留的笔记);`--security` 按证券筛,笔记关联的证券里**含其中任一只**即命中;`--note-id` 按笔记 ID 精确查。`--security` 与 `--note-id` 二选一,同传本地报错
|
|
167
|
+
- `--security` / `--note-id` 各最多 100 个;代码大小写、首尾空格不影响匹配,但港股要 5 位(`00700.HK`,`700.HK` 不会补零)、美股要用交易所后缀(`AAPL.O`,`AAPL.US` 不会转换)。**代码写错、不存在或类型不支持时整次报 `120001`**,不会当成「这只票没有笔记」返回空;有效代码没有笔记才是空结果
|
|
168
|
+
- 不存在或不属于本人的笔记 ID 被直接过滤,不计入 `total`、不报错
|
|
169
|
+
- 自动翻页,省略 `--size` 取全部;按 `createTime` 倒序(同秒按 ID 倒序),同时命中多只证券的笔记只出现一次。翻页期间有增删时偏移会变,不保证跨页一致
|
|
170
|
+
- 返回字段:`stockNoteId` / `securityList`(该笔记**完整**的关联证券,按代码升序,不只是你筛的那几只)/ `content`(纯文本原样,保留换行;Markdown 只是文字)/ `createTime` / `updateTime`(北京时间,精确到秒;正文没变的提交不刷新 `updateTime`)
|
|
171
|
+
- 默认输出 json(正文常含换行,表格不便阅读)
|
|
172
|
+
|
|
173
|
+
### 新增 `stock-note-add`
|
|
174
|
+
|
|
175
|
+
- `--security`:1~50 只(按规范化去重后计数),可重复或逗号分隔。可关联 A 股、港股、美股(`.O` / `.N` 等)、ETF、交易所指数、概念指数(`.GT`)、中信行业指数(`.CI`)、全球指数(如 `SPX.SPI`),可混传;**申万行业指数(`.SWI`)不支持**。任一只无效则整条不建,报 `120001` 并点名
|
|
176
|
+
- `--content`:纯文本,不能为空或全是空白,最长 10000 个字符(按 Unicode 码点计,首尾空白和换行都算);原样保存,不裁剪
|
|
177
|
+
- 返回 `stockNoteId` 与实际关联的 `securityList`(规范化代码、升序)
|
|
178
|
+
- 🔴 **关联的证券建好后不能改**:要换关联范围就新增一条、核对无误后再删旧的(两步不是原子操作,中间会短暂同时存在两条)
|
|
179
|
+
- 🔴 **超时或 5xx 不会自动重发,也不要直接重跑**:服务端没有防重机制,同样的请求再提交一次就是第二条笔记。超时后先 `stock-note-list --security <code>` 看是否已经写入
|
|
180
|
+
|
|
181
|
+
### 改写 `stock-note-update`
|
|
182
|
+
|
|
183
|
+
- `--note-id` 取自 `stock-note-list`;`--content` **整体替换**旧正文(不是追加),规则同新增
|
|
184
|
+
- 只改正文,关联证券不变;一条笔记关联多只证券时,改动在每只证券下都可见
|
|
185
|
+
- 成功返回 `{}`;`updateTime` 从查询里看。不存在或不属于本人返回 `130002`「笔记不存在或无权操作」
|
|
186
|
+
- 没有版本控制,并发改写以最后提交的为准
|
|
187
|
+
|
|
188
|
+
### 删除 `stock-note-delete`
|
|
189
|
+
|
|
190
|
+
- **必须显式加 `--yes`**(不加直接报错退出,不发请求);删除的是整条笔记连同它与全部证券的关联,**不可恢复**。`raw call vault.stock-note.delete` 同样要 `--yes`
|
|
191
|
+
- `--note-id` 可重复或逗号分隔,一次最多 100 个;**只接受明确的 ID,没有 `all`**——批量删先 `stock-note-list` 拿 ID 核对
|
|
192
|
+
- 幂等:已删掉的、不存在的、不属于本人的 ID 都进 `successList`(不会删到别人的笔记),重复执行仍算成功
|
|
193
|
+
- 部分失败同股票池写命令:服务端仍返回成功信封、把失败项放进 `failList`,CLI 在 stderr 列出、标 `partial`、**退出码 3**;拿到结果后只需对 `failList` 里的 ID 重试
|
|
194
|
+
- 返回字段:`successList[]` + `failList[]{stockNoteId, failReason}`
|