tickflow-assist 0.3.6 → 0.3.8
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 +11 -42
- package/dist/analysis/types/composite-analysis.d.ts +27 -0
- package/dist/background/realtime-monitor.worker.d.ts +1 -1
- package/dist/background/realtime-monitor.worker.js +3 -4
- package/dist/bootstrap.js +24 -4
- package/dist/config/tickflow-access.d.ts +2 -1
- package/dist/config/tickflow-access.js +10 -3
- package/dist/dev/run-monitor-loop.js +0 -1
- package/dist/dev/tickflow-assist-cli.js +4 -3
- package/dist/dev/validate-mx-search.js +10 -2
- package/dist/plugin-commands.js +27 -0
- package/dist/plugin.js +4 -6
- package/dist/prompts/analysis/kline-analysis-user-prompt.js +2 -1
- package/dist/prompts/analysis/post-close-review-user-prompt.js +40 -1
- package/dist/prompts/analysis/pre-market-brief-prompt.d.ts +3 -1
- package/dist/prompts/analysis/pre-market-brief-prompt.js +8 -3
- package/dist/services/industry-peer-service.d.ts +9 -0
- package/dist/services/industry-peer-service.js +152 -0
- package/dist/services/jin10-flash-monitor-service.js +2 -1
- package/dist/services/monitor-service.d.ts +1 -1
- package/dist/services/monitor-service.js +21 -26
- package/dist/services/mx-search-service.d.ts +8 -1
- package/dist/services/mx-search-service.js +400 -10
- package/dist/services/post-close-review-service.d.ts +11 -4
- package/dist/services/post-close-review-service.js +113 -10
- package/dist/services/pre-market-brief-service.js +500 -42
- package/dist/services/tickflow-client.d.ts +4 -1
- package/dist/services/tickflow-client.js +32 -0
- package/dist/services/tickflow-universe-service.d.ts +26 -0
- package/dist/services/tickflow-universe-service.js +213 -0
- package/dist/services/watchlist-profile-service.d.ts +4 -1
- package/dist/services/watchlist-profile-service.js +58 -29
- package/dist/services/watchlist-service.d.ts +5 -1
- package/dist/services/watchlist-service.js +9 -4
- package/dist/storage/repositories/universe-membership-repo.d.ts +11 -0
- package/dist/storage/repositories/universe-membership-repo.js +38 -0
- package/dist/storage/repositories/universe-repo.d.ts +17 -0
- package/dist/storage/repositories/universe-repo.js +62 -0
- package/dist/storage/schemas.d.ts +2 -0
- package/dist/storage/schemas.js +13 -0
- package/dist/tools/add-stock.tool.d.ts +2 -1
- package/dist/tools/add-stock.tool.js +10 -1
- package/dist/tools/eastmoney-watchlist.tool.d.ts +31 -0
- package/dist/tools/eastmoney-watchlist.tool.js +294 -0
- package/dist/tools/mx-data.tool.d.ts +8 -0
- package/dist/tools/mx-data.tool.js +94 -0
- package/dist/tools/mx-select-stock.tool.js +6 -2
- package/dist/tools/query-database.tool.js +6 -0
- package/dist/tools/refresh-watchlist-profiles.tool.d.ts +2 -1
- package/dist/tools/refresh-watchlist-profiles.tool.js +11 -1
- package/dist/tools/screen-stock-candidates.tool.d.ts +34 -0
- package/dist/tools/screen-stock-candidates.tool.js +477 -0
- package/dist/tools/test-alert.tool.js +56 -19
- package/dist/types/mx-data.d.ts +23 -0
- package/dist/types/mx-data.js +1 -0
- package/dist/types/mx-select-stock.d.ts +1 -0
- package/dist/types/mx-self-select.d.ts +30 -0
- package/dist/types/mx-self-select.js +1 -0
- package/dist/types/tickflow.d.ts +12 -0
- package/dist/utils/tickflow-quote.d.ts +5 -0
- package/dist/utils/tickflow-quote.js +31 -0
- package/openclaw.plugin.json +83 -6
- package/package.json +6 -6
- package/skills/stock-analysis/SKILL.md +39 -20
- package/skills/usage-help/SKILL.md +33 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
const MAX_PEER_MOVERS = 3;
|
|
2
|
+
export class IndustryPeerService {
|
|
3
|
+
universeService;
|
|
4
|
+
quoteService;
|
|
5
|
+
constructor(universeService, quoteService) {
|
|
6
|
+
this.universeService = universeService;
|
|
7
|
+
this.quoteService = quoteService;
|
|
8
|
+
}
|
|
9
|
+
async buildContext(symbol) {
|
|
10
|
+
if (!this.universeService) {
|
|
11
|
+
return buildUnavailableContext("当前 TickFlow API Key Level 不支持标的池,已跳过申万三级同业表现。");
|
|
12
|
+
}
|
|
13
|
+
const industryProfile = await this.universeService.resolveIndustryProfile(symbol);
|
|
14
|
+
if (!industryProfile?.sw3UniverseId || !industryProfile.sw3Name) {
|
|
15
|
+
return buildUnavailableContext("未获取到可用的申万3级行业映射。");
|
|
16
|
+
}
|
|
17
|
+
const peerSymbols = await this.universeService.listUniverseSymbols(industryProfile.sw3UniverseId);
|
|
18
|
+
if (peerSymbols.length === 0) {
|
|
19
|
+
return buildUnavailableContext(`申万3级 ${industryProfile.sw3Name} 暂无可用成分股。`, industryProfile);
|
|
20
|
+
}
|
|
21
|
+
const quotes = await this.quoteService.fetchQuotes(peerSymbols);
|
|
22
|
+
const snapshots = quotes
|
|
23
|
+
.map(toPeerQuoteSnapshot)
|
|
24
|
+
.filter((item) => item != null)
|
|
25
|
+
.sort((left, right) => right.changePct - left.changePct || left.symbol.localeCompare(right.symbol));
|
|
26
|
+
if (snapshots.length === 0) {
|
|
27
|
+
return buildUnavailableContext(`申万3级 ${industryProfile.sw3Name} 暂未返回有效行情。`, industryProfile);
|
|
28
|
+
}
|
|
29
|
+
const targetIndex = snapshots.findIndex((item) => item.symbol === symbol);
|
|
30
|
+
const target = targetIndex >= 0 ? snapshots[targetIndex] : null;
|
|
31
|
+
const others = snapshots.filter((item) => item.symbol !== symbol);
|
|
32
|
+
const advanceCount = others.filter((item) => item.changePct > 0.0001).length;
|
|
33
|
+
const declineCount = others.filter((item) => item.changePct < -0.0001).length;
|
|
34
|
+
const flatCount = Math.max(0, others.length - advanceCount - declineCount);
|
|
35
|
+
const changeValues = others.map((item) => item.changePct);
|
|
36
|
+
const averageChangePct = changeValues.length > 0 ? average(changeValues) : null;
|
|
37
|
+
const medianChangePct = changeValues.length > 0 ? median(changeValues) : null;
|
|
38
|
+
const leaders = others.slice(0, MAX_PEER_MOVERS).map(toPeerMover);
|
|
39
|
+
const laggards = [...others]
|
|
40
|
+
.sort((left, right) => left.changePct - right.changePct || left.symbol.localeCompare(right.symbol))
|
|
41
|
+
.slice(0, MAX_PEER_MOVERS)
|
|
42
|
+
.map(toPeerMover);
|
|
43
|
+
const targetRank = targetIndex >= 0 ? targetIndex + 1 : null;
|
|
44
|
+
const targetPercentile = targetRank != null && snapshots.length > 1
|
|
45
|
+
? 1 - ((targetRank - 1) / (snapshots.length - 1))
|
|
46
|
+
: targetRank != null ? 1 : null;
|
|
47
|
+
return {
|
|
48
|
+
available: true,
|
|
49
|
+
summary: buildSummary({
|
|
50
|
+
industryName: industryProfile.sw3Name,
|
|
51
|
+
peerCount: snapshots.length,
|
|
52
|
+
otherStockCount: others.length,
|
|
53
|
+
advanceCount,
|
|
54
|
+
declineCount,
|
|
55
|
+
flatCount,
|
|
56
|
+
averageChangePct,
|
|
57
|
+
medianChangePct,
|
|
58
|
+
target,
|
|
59
|
+
targetRank,
|
|
60
|
+
}),
|
|
61
|
+
sw1Name: industryProfile.sw1Name,
|
|
62
|
+
sw2Name: industryProfile.sw2Name,
|
|
63
|
+
sw3Name: industryProfile.sw3Name,
|
|
64
|
+
sw3UniverseId: industryProfile.sw3UniverseId,
|
|
65
|
+
peerCount: snapshots.length,
|
|
66
|
+
otherStockCount: others.length,
|
|
67
|
+
advanceCount,
|
|
68
|
+
declineCount,
|
|
69
|
+
flatCount,
|
|
70
|
+
averageChangePct,
|
|
71
|
+
medianChangePct,
|
|
72
|
+
targetChangePct: target?.changePct ?? null,
|
|
73
|
+
targetRank,
|
|
74
|
+
targetPercentile,
|
|
75
|
+
leaders,
|
|
76
|
+
laggards,
|
|
77
|
+
note: null,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function toPeerQuoteSnapshot(quote) {
|
|
82
|
+
const prevClose = Number(quote.prev_close ?? 0);
|
|
83
|
+
const lastPrice = Number(quote.last_price ?? 0);
|
|
84
|
+
if (!Number.isFinite(prevClose) || !Number.isFinite(lastPrice) || prevClose <= 0) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
symbol: String(quote.symbol ?? "").trim(),
|
|
89
|
+
name: String(quote.name ?? quote.ext?.name ?? quote.symbol ?? "").trim(),
|
|
90
|
+
changePct: ((lastPrice - prevClose) / prevClose) * 100,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function toPeerMover(item) {
|
|
94
|
+
return {
|
|
95
|
+
symbol: item.symbol,
|
|
96
|
+
name: item.name || item.symbol,
|
|
97
|
+
changePct: item.changePct,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function buildSummary(input) {
|
|
101
|
+
const parts = [
|
|
102
|
+
`申万3级 ${input.industryName} 共 ${input.peerCount} 只`,
|
|
103
|
+
`除本股外上涨 ${input.advanceCount} / 下跌 ${input.declineCount} / 平 ${input.flatCount}`,
|
|
104
|
+
];
|
|
105
|
+
if (input.averageChangePct != null) {
|
|
106
|
+
parts.push(`均值 ${formatSignedPct(input.averageChangePct)}`);
|
|
107
|
+
}
|
|
108
|
+
if (input.medianChangePct != null) {
|
|
109
|
+
parts.push(`中位数 ${formatSignedPct(input.medianChangePct)}`);
|
|
110
|
+
}
|
|
111
|
+
if (input.target && input.targetRank != null) {
|
|
112
|
+
parts.push(`本股 ${formatSignedPct(input.target.changePct)},位列 ${input.targetRank}/${input.peerCount}`);
|
|
113
|
+
}
|
|
114
|
+
return parts.join(";");
|
|
115
|
+
}
|
|
116
|
+
function buildUnavailableContext(note, profile) {
|
|
117
|
+
return {
|
|
118
|
+
available: false,
|
|
119
|
+
summary: note,
|
|
120
|
+
sw1Name: profile?.sw1Name ?? null,
|
|
121
|
+
sw2Name: profile?.sw2Name ?? null,
|
|
122
|
+
sw3Name: profile?.sw3Name ?? null,
|
|
123
|
+
sw3UniverseId: profile?.sw3UniverseId ?? null,
|
|
124
|
+
peerCount: 0,
|
|
125
|
+
otherStockCount: 0,
|
|
126
|
+
advanceCount: 0,
|
|
127
|
+
declineCount: 0,
|
|
128
|
+
flatCount: 0,
|
|
129
|
+
averageChangePct: null,
|
|
130
|
+
medianChangePct: null,
|
|
131
|
+
targetChangePct: null,
|
|
132
|
+
targetRank: null,
|
|
133
|
+
targetPercentile: null,
|
|
134
|
+
leaders: [],
|
|
135
|
+
laggards: [],
|
|
136
|
+
note,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function average(values) {
|
|
140
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
141
|
+
}
|
|
142
|
+
function median(values) {
|
|
143
|
+
const sorted = [...values].sort((left, right) => left - right);
|
|
144
|
+
const middle = Math.floor(sorted.length / 2);
|
|
145
|
+
if (sorted.length % 2 === 0) {
|
|
146
|
+
return (sorted[middle - 1] + sorted[middle]) / 2;
|
|
147
|
+
}
|
|
148
|
+
return sorted[middle] ?? 0;
|
|
149
|
+
}
|
|
150
|
+
function formatSignedPct(value) {
|
|
151
|
+
return `${value >= 0 ? "+" : ""}${value.toFixed(2)}%`;
|
|
152
|
+
}
|
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { parseFlashAlertDecision } from "../analysis/parsers/flash-alert-decision.parser.js";
|
|
5
5
|
import { FLASH_MONITOR_ALERT_SYSTEM_PROMPT, buildFlashMonitorAlertUserPrompt, } from "../prompts/analysis/index.js";
|
|
6
6
|
import { chinaHour, chinaToday, formatChinaDateTime } from "../utils/china-time.js";
|
|
7
|
+
import { extractSectorKeywords } from "./watchlist-profile-service.js";
|
|
7
8
|
const DEFAULT_STATE = {
|
|
8
9
|
initialized: false,
|
|
9
10
|
lastSeenKey: null,
|
|
@@ -446,7 +447,7 @@ function buildDirectKeywords(item) {
|
|
|
446
447
|
}
|
|
447
448
|
function buildBoardKeywords(item) {
|
|
448
449
|
return uniqueStrings([
|
|
449
|
-
item.sector
|
|
450
|
+
...extractSectorKeywords(item.sector),
|
|
450
451
|
...item.themes,
|
|
451
452
|
]).filter((keyword) => isUsefulBoardKeyword(keyword));
|
|
452
453
|
}
|
|
@@ -34,7 +34,7 @@ export declare class MonitorService {
|
|
|
34
34
|
bindManagedServiceRuntime(): Promise<void>;
|
|
35
35
|
markStopped(): Promise<void>;
|
|
36
36
|
getStatusReport(): Promise<string>;
|
|
37
|
-
runMonitorOnce(): Promise<number>;
|
|
37
|
+
runMonitorOnce(runtimeHost?: "plugin_service" | "fallback_process"): Promise<number>;
|
|
38
38
|
private maybeSendSessionNotification;
|
|
39
39
|
private buildQuoteLines;
|
|
40
40
|
private buildKeyLevelsLines;
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { basenameOrUndefined, buildAlertMessageHash, truncateDiagnosticText, } from "../utils/alert-diagnostic-log.js";
|
|
4
4
|
import { formatChinaDateTime } from "../utils/china-time.js";
|
|
5
5
|
import { calculateProfitPct, formatCostPrice } from "../utils/cost-price.js";
|
|
6
|
+
import { resolveTickFlowQuoteChangePct } from "../utils/tickflow-quote.js";
|
|
6
7
|
const DEFAULT_STATE = {
|
|
7
8
|
running: false,
|
|
8
9
|
startedAt: null,
|
|
@@ -23,6 +24,7 @@ const DEFAULT_STATE = {
|
|
|
23
24
|
const INTRADAY_PERIOD = "1m";
|
|
24
25
|
const MONITOR_RUN_LOCK_MIN_STALE_MS = 90_000;
|
|
25
26
|
const ALERT_CLAIM_MIN_STALE_MS = 90_000;
|
|
27
|
+
const SYSTEM_SESSION_ALERT_SYMBOL = "__system_session__";
|
|
26
28
|
export class MonitorService {
|
|
27
29
|
baseDir;
|
|
28
30
|
requestInterval;
|
|
@@ -182,12 +184,13 @@ export class MonitorService {
|
|
|
182
184
|
lines.push(...(await this.buildKeyLevelsLines(watchlist)));
|
|
183
185
|
return lines.join("\n");
|
|
184
186
|
}
|
|
185
|
-
async runMonitorOnce() {
|
|
187
|
+
async runMonitorOnce(runtimeHost) {
|
|
186
188
|
const runLease = await this.tryAcquireRunLease();
|
|
187
189
|
if (!runLease) {
|
|
188
190
|
return 0;
|
|
189
191
|
}
|
|
190
192
|
try {
|
|
193
|
+
await this.recordHeartbeat(runtimeHost);
|
|
191
194
|
await this.alertMediaService.maybeCleanupExpired();
|
|
192
195
|
const phase = await this.tradingCalendarService.getTradingPhase();
|
|
193
196
|
let alertCount = await this.maybeSendSessionNotification(phase);
|
|
@@ -258,12 +261,14 @@ export class MonitorService {
|
|
|
258
261
|
return 0;
|
|
259
262
|
}
|
|
260
263
|
const watchlistCount = (await this.watchlistService.list()).length;
|
|
261
|
-
const
|
|
264
|
+
const message = this.alertService.formatSystemNotification(event.title, [
|
|
262
265
|
`时间: ${now}`,
|
|
263
266
|
`阶段: ${event.phaseText}`,
|
|
264
267
|
`关注列表: ${watchlistCount}只`,
|
|
265
|
-
])
|
|
266
|
-
|
|
268
|
+
]);
|
|
269
|
+
const ok = await this.trySendAlert(SYSTEM_SESSION_ALERT_SYMBOL, event.id, message);
|
|
270
|
+
if (ok
|
|
271
|
+
|| await this.alertLogRepository.isSentThisSession(SYSTEM_SESSION_ALERT_SYMBOL, event.id, getSessionKey())) {
|
|
267
272
|
nextState.sessionNotificationsSent.push(event.id);
|
|
268
273
|
}
|
|
269
274
|
await this.writeState(nextState);
|
|
@@ -309,7 +314,8 @@ export class MonitorService {
|
|
|
309
314
|
}
|
|
310
315
|
async buildAlertLine() {
|
|
311
316
|
const today = formatChinaDateTime().slice(0, 10);
|
|
312
|
-
const alerts = await this.alertLogRepository.listByNaturalDate(today)
|
|
317
|
+
const alerts = (await this.alertLogRepository.listByNaturalDate(today))
|
|
318
|
+
.filter((entry) => entry.symbol !== SYSTEM_SESSION_ALERT_SYMBOL);
|
|
313
319
|
if (alerts.length === 0) {
|
|
314
320
|
return "今日告警: 无";
|
|
315
321
|
}
|
|
@@ -737,13 +743,7 @@ function formatTradingPhase(phase) {
|
|
|
737
743
|
}
|
|
738
744
|
function formatQuoteLine(item, quote) {
|
|
739
745
|
const lastPrice = Number(quote.last_price ?? 0);
|
|
740
|
-
const
|
|
741
|
-
const tickflowChangePct = quote.ext?.change_pct;
|
|
742
|
-
const changePct = tickflowChangePct != null
|
|
743
|
-
? Number(tickflowChangePct) * 100
|
|
744
|
-
: prevClose > 0
|
|
745
|
-
? ((lastPrice - prevClose) / prevClose) * 100
|
|
746
|
-
: null;
|
|
746
|
+
const changePct = resolveTickFlowQuoteChangePct(quote);
|
|
747
747
|
const quoteTime = formatQuoteTimestamp(quote.timestamp);
|
|
748
748
|
const profitPct = calculateProfitPct(lastPrice, item.costPrice);
|
|
749
749
|
let line = `• ${item.name}(${item.symbol}) ${lastPrice.toFixed(2)}`;
|
|
@@ -778,7 +778,8 @@ function resolveSessionNotification(previousPhase, currentPhase, hhmm, sent) {
|
|
|
778
778
|
if (!hasSent("morning_start")
|
|
779
779
|
&& currentPhase === "trading"
|
|
780
780
|
&& hhmm <= "11:30"
|
|
781
|
-
&& ((previousPhase === "pre_market")
|
|
781
|
+
&& ((previousPhase === "pre_market")
|
|
782
|
+
|| (previousPhase !== "trading" && isWithinWindow(hhmm, "09:30", "09:40")))) {
|
|
782
783
|
return {
|
|
783
784
|
id: "morning_start",
|
|
784
785
|
title: "🔔 开始上午盯盘",
|
|
@@ -787,7 +788,8 @@ function resolveSessionNotification(previousPhase, currentPhase, hhmm, sent) {
|
|
|
787
788
|
}
|
|
788
789
|
if (!hasSent("morning_end")
|
|
789
790
|
&& currentPhase === "lunch_break"
|
|
790
|
-
&& ((previousPhase === "trading")
|
|
791
|
+
&& ((previousPhase === "trading")
|
|
792
|
+
|| (previousPhase !== "lunch_break" && isWithinWindow(hhmm, "11:30", "11:40")))) {
|
|
791
793
|
return {
|
|
792
794
|
id: "morning_end",
|
|
793
795
|
title: "🔔 上午盯盘结束",
|
|
@@ -797,7 +799,8 @@ function resolveSessionNotification(previousPhase, currentPhase, hhmm, sent) {
|
|
|
797
799
|
if (!hasSent("afternoon_start")
|
|
798
800
|
&& currentPhase === "trading"
|
|
799
801
|
&& hhmm >= "13:00"
|
|
800
|
-
&& ((previousPhase === "lunch_break")
|
|
802
|
+
&& ((previousPhase === "lunch_break")
|
|
803
|
+
|| (previousPhase !== "trading" && isWithinWindow(hhmm, "13:00", "13:10")))) {
|
|
801
804
|
return {
|
|
802
805
|
id: "afternoon_start",
|
|
803
806
|
title: "🔔 开始下午盯盘",
|
|
@@ -806,7 +809,8 @@ function resolveSessionNotification(previousPhase, currentPhase, hhmm, sent) {
|
|
|
806
809
|
}
|
|
807
810
|
if (!hasSent("day_end")
|
|
808
811
|
&& currentPhase === "closed"
|
|
809
|
-
&& ((previousPhase === "trading")
|
|
812
|
+
&& ((previousPhase === "trading")
|
|
813
|
+
|| (previousPhase !== "closed" && isWithinWindow(hhmm, "15:00", "15:10")))) {
|
|
810
814
|
return {
|
|
811
815
|
id: "day_end",
|
|
812
816
|
title: "🔔 今日盯盘结束",
|
|
@@ -1007,14 +1011,5 @@ function resolveAlertImageLabel(ruleName, fallbackTitle) {
|
|
|
1007
1011
|
}
|
|
1008
1012
|
}
|
|
1009
1013
|
function getQuoteChangePct(quote) {
|
|
1010
|
-
|
|
1011
|
-
if (tickflowChangePct != null && Number.isFinite(Number(tickflowChangePct))) {
|
|
1012
|
-
return Number(tickflowChangePct) * 100;
|
|
1013
|
-
}
|
|
1014
|
-
const lastPrice = Number(quote.last_price ?? 0);
|
|
1015
|
-
const prevClose = Number(quote.prev_close ?? 0);
|
|
1016
|
-
if (!(prevClose > 0)) {
|
|
1017
|
-
return null;
|
|
1018
|
-
}
|
|
1019
|
-
return ((lastPrice - prevClose) / prevClose) * 100;
|
|
1014
|
+
return resolveTickFlowQuoteChangePct(quote);
|
|
1020
1015
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { MxSearchDocument } from "../types/mx-search.js";
|
|
2
|
+
import type { MxDataResult } from "../types/mx-data.js";
|
|
3
|
+
import type { MxSelfSelectManageResult, MxSelfSelectResult } from "../types/mx-self-select.js";
|
|
2
4
|
import type { MxSelectStockResult } from "../types/mx-select-stock.js";
|
|
3
5
|
export declare class MxSearchServiceError extends Error {
|
|
4
6
|
constructor(message: string);
|
|
@@ -8,15 +10,20 @@ export declare class MxApiService {
|
|
|
8
10
|
private readonly apiKey;
|
|
9
11
|
constructor(apiBaseUrl: string, apiKey: string);
|
|
10
12
|
isConfigured(): boolean;
|
|
11
|
-
getConfigurationError(): string | null;
|
|
13
|
+
getConfigurationError(featureName?: string): string | null;
|
|
12
14
|
search(query: string): Promise<MxSearchDocument[]>;
|
|
13
15
|
selectStocks(input: {
|
|
14
16
|
keyword: string;
|
|
15
17
|
pageNo?: number;
|
|
16
18
|
pageSize?: number;
|
|
17
19
|
}): Promise<MxSelectStockResult>;
|
|
20
|
+
queryData(toolQuery: string): Promise<MxDataResult>;
|
|
21
|
+
getSelfSelectWatchlist(): Promise<MxSelfSelectResult>;
|
|
22
|
+
manageSelfSelect(query: string): Promise<MxSelfSelectManageResult>;
|
|
18
23
|
private postJson;
|
|
19
24
|
}
|
|
20
25
|
export declare class MxSearchService extends MxApiService {
|
|
21
26
|
}
|
|
22
27
|
export declare function normalizeMxSearchDocuments(value: unknown): MxSearchDocument[];
|
|
28
|
+
export declare function normalizeMxSelectStockResult(value: unknown): MxSelectStockResult;
|
|
29
|
+
export declare function normalizeMxDataResult(value: unknown): MxDataResult;
|