tickflow-assist 0.2.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.
Files changed (246) hide show
  1. package/README.md +151 -0
  2. package/day_future.txt +8797 -0
  3. package/dist/analysis/orchestrators/composite-analysis.orchestrator.d.ts +35 -0
  4. package/dist/analysis/orchestrators/composite-analysis.orchestrator.js +232 -0
  5. package/dist/analysis/parsers/json-block.parser.d.ts +1 -0
  6. package/dist/analysis/parsers/json-block.parser.js +13 -0
  7. package/dist/analysis/parsers/key-levels.parser.d.ts +5 -0
  8. package/dist/analysis/parsers/key-levels.parser.js +61 -0
  9. package/dist/analysis/parsers/post-close-review.parser.d.ts +2 -0
  10. package/dist/analysis/parsers/post-close-review.parser.js +79 -0
  11. package/dist/analysis/parsers/watchlist-profile.parser.d.ts +6 -0
  12. package/dist/analysis/parsers/watchlist-profile.parser.js +93 -0
  13. package/dist/analysis/providers/financial-analysis.provider.d.ts +12 -0
  14. package/dist/analysis/providers/financial-analysis.provider.js +85 -0
  15. package/dist/analysis/providers/market-analysis.provider.d.ts +27 -0
  16. package/dist/analysis/providers/market-analysis.provider.js +187 -0
  17. package/dist/analysis/providers/news-analysis.provider.d.ts +9 -0
  18. package/dist/analysis/providers/news-analysis.provider.js +60 -0
  19. package/dist/analysis/tasks/analysis-step-task.d.ts +11 -0
  20. package/dist/analysis/tasks/analysis-step-task.js +1 -0
  21. package/dist/analysis/tasks/analysis-task.d.ts +13 -0
  22. package/dist/analysis/tasks/analysis-task.js +1 -0
  23. package/dist/analysis/tasks/composite-stock-analysis.task.d.ts +17 -0
  24. package/dist/analysis/tasks/composite-stock-analysis.task.js +47 -0
  25. package/dist/analysis/tasks/financial-fundamental-lite.task.d.ts +10 -0
  26. package/dist/analysis/tasks/financial-fundamental-lite.task.js +21 -0
  27. package/dist/analysis/tasks/financial-fundamental.task.d.ts +12 -0
  28. package/dist/analysis/tasks/financial-fundamental.task.js +64 -0
  29. package/dist/analysis/tasks/kline-technical-signal.task.d.ts +10 -0
  30. package/dist/analysis/tasks/kline-technical-signal.task.js +41 -0
  31. package/dist/analysis/tasks/kline-technical.task.d.ts +32 -0
  32. package/dist/analysis/tasks/kline-technical.task.js +61 -0
  33. package/dist/analysis/tasks/news-catalyst.task.d.ts +11 -0
  34. package/dist/analysis/tasks/news-catalyst.task.js +62 -0
  35. package/dist/analysis/tasks/post-close-review.task.d.ts +12 -0
  36. package/dist/analysis/tasks/post-close-review.task.js +35 -0
  37. package/dist/analysis/types/composite-analysis.d.ts +123 -0
  38. package/dist/analysis/types/composite-analysis.js +1 -0
  39. package/dist/background/daily-update.worker.d.ts +50 -0
  40. package/dist/background/daily-update.worker.js +546 -0
  41. package/dist/background/realtime-monitor.worker.d.ts +8 -0
  42. package/dist/background/realtime-monitor.worker.js +28 -0
  43. package/dist/bootstrap.d.ts +45 -0
  44. package/dist/bootstrap.js +214 -0
  45. package/dist/config/normalize.d.ts +4 -0
  46. package/dist/config/normalize.js +99 -0
  47. package/dist/config/schema.d.ts +23 -0
  48. package/dist/config/schema.js +18 -0
  49. package/dist/config/tickflow-access.d.ts +4 -0
  50. package/dist/config/tickflow-access.js +28 -0
  51. package/dist/constants/market-indexes.d.ts +5 -0
  52. package/dist/constants/market-indexes.js +4 -0
  53. package/dist/dev/run-daily-update-loop.d.ts +1 -0
  54. package/dist/dev/run-daily-update-loop.js +48 -0
  55. package/dist/dev/run-monitor-loop.d.ts +1 -0
  56. package/dist/dev/run-monitor-loop.js +60 -0
  57. package/dist/dev/run-tool.d.ts +1 -0
  58. package/dist/dev/run-tool.js +49 -0
  59. package/dist/dev/tickflow-assist-cli.d.ts +2 -0
  60. package/dist/dev/tickflow-assist-cli.js +525 -0
  61. package/dist/dev/validate-mx-search.d.ts +1 -0
  62. package/dist/dev/validate-mx-search.js +212 -0
  63. package/dist/plugin-commands.d.ts +3 -0
  64. package/dist/plugin-commands.js +229 -0
  65. package/dist/plugin.d.ts +8 -0
  66. package/dist/plugin.js +151 -0
  67. package/dist/prompts/analysis/common-system-prompt.d.ts +1 -0
  68. package/dist/prompts/analysis/common-system-prompt.js +44 -0
  69. package/dist/prompts/analysis/composite-analysis-user-prompt.d.ts +11 -0
  70. package/dist/prompts/analysis/composite-analysis-user-prompt.js +102 -0
  71. package/dist/prompts/analysis/financial-analysis-user-prompt.d.ts +7 -0
  72. package/dist/prompts/analysis/financial-analysis-user-prompt.js +106 -0
  73. package/dist/prompts/analysis/financial-lite-analysis-user-prompt.d.ts +7 -0
  74. package/dist/prompts/analysis/financial-lite-analysis-user-prompt.js +59 -0
  75. package/dist/prompts/analysis/index.d.ts +8 -0
  76. package/dist/prompts/analysis/index.js +8 -0
  77. package/dist/prompts/analysis/kline-analysis-user-prompt.d.ts +13 -0
  78. package/dist/prompts/analysis/kline-analysis-user-prompt.js +215 -0
  79. package/dist/prompts/analysis/news-analysis-user-prompt.d.ts +8 -0
  80. package/dist/prompts/analysis/news-analysis-user-prompt.js +57 -0
  81. package/dist/prompts/analysis/post-close-review-user-prompt.d.ts +3 -0
  82. package/dist/prompts/analysis/post-close-review-user-prompt.js +129 -0
  83. package/dist/prompts/analysis/watchlist-profile-extraction-prompt.d.ts +7 -0
  84. package/dist/prompts/analysis/watchlist-profile-extraction-prompt.js +52 -0
  85. package/dist/prompts/analysis-system-prompt.d.ts +1 -0
  86. package/dist/prompts/analysis-system-prompt.js +1 -0
  87. package/dist/prompts/analysis-user-prompt.d.ts +1 -0
  88. package/dist/prompts/analysis-user-prompt.js +1 -0
  89. package/dist/runtime/daily-update-process.d.ts +3 -0
  90. package/dist/runtime/daily-update-process.js +24 -0
  91. package/dist/runtime/monitor-process.d.ts +3 -0
  92. package/dist/runtime/monitor-process.js +24 -0
  93. package/dist/runtime/plugin-api.d.ts +22 -0
  94. package/dist/runtime/plugin-api.js +2 -0
  95. package/dist/runtime/process-config.d.ts +8 -0
  96. package/dist/runtime/process-config.js +35 -0
  97. package/dist/services/alert-service.d.ts +45 -0
  98. package/dist/services/alert-service.js +198 -0
  99. package/dist/services/analysis-service.d.ts +20 -0
  100. package/dist/services/analysis-service.js +73 -0
  101. package/dist/services/analysis-view-service.d.ts +23 -0
  102. package/dist/services/analysis-view-service.js +343 -0
  103. package/dist/services/financial-lite-service.d.ts +23 -0
  104. package/dist/services/financial-lite-service.js +201 -0
  105. package/dist/services/financial-service.d.ts +20 -0
  106. package/dist/services/financial-service.js +47 -0
  107. package/dist/services/indicator-service.d.ts +9 -0
  108. package/dist/services/indicator-service.js +67 -0
  109. package/dist/services/instrument-service.d.ts +6 -0
  110. package/dist/services/instrument-service.js +21 -0
  111. package/dist/services/key-level-service.d.ts +2 -0
  112. package/dist/services/key-level-service.js +2 -0
  113. package/dist/services/key-levels-backtest-service.d.ts +71 -0
  114. package/dist/services/key-levels-backtest-service.js +427 -0
  115. package/dist/services/kline-service.d.ts +19 -0
  116. package/dist/services/kline-service.js +91 -0
  117. package/dist/services/monitor-service.d.ts +44 -0
  118. package/dist/services/monitor-service.js +598 -0
  119. package/dist/services/mx-search-service.d.ts +22 -0
  120. package/dist/services/mx-search-service.js +286 -0
  121. package/dist/services/post-close-review-service.d.ts +31 -0
  122. package/dist/services/post-close-review-service.js +402 -0
  123. package/dist/services/quote-service.d.ts +7 -0
  124. package/dist/services/quote-service.js +9 -0
  125. package/dist/services/review-memory-service.d.ts +7 -0
  126. package/dist/services/review-memory-service.js +76 -0
  127. package/dist/services/tickflow-client.d.ts +43 -0
  128. package/dist/services/tickflow-client.js +126 -0
  129. package/dist/services/trading-calendar-service.d.ts +20 -0
  130. package/dist/services/trading-calendar-service.js +102 -0
  131. package/dist/services/update-service.d.ts +21 -0
  132. package/dist/services/update-service.js +130 -0
  133. package/dist/services/watchlist-profile-service.d.ts +20 -0
  134. package/dist/services/watchlist-profile-service.js +76 -0
  135. package/dist/services/watchlist-service.d.ts +43 -0
  136. package/dist/services/watchlist-service.js +204 -0
  137. package/dist/storage/db.d.ts +23 -0
  138. package/dist/storage/db.js +70 -0
  139. package/dist/storage/repositories/alert-log-repo.d.ts +15 -0
  140. package/dist/storage/repositories/alert-log-repo.js +54 -0
  141. package/dist/storage/repositories/analysis-log-repo.d.ts +8 -0
  142. package/dist/storage/repositories/analysis-log-repo.js +48 -0
  143. package/dist/storage/repositories/composite-analysis-repo.d.ts +9 -0
  144. package/dist/storage/repositories/composite-analysis-repo.js +116 -0
  145. package/dist/storage/repositories/financial-analysis-repo.d.ts +9 -0
  146. package/dist/storage/repositories/financial-analysis-repo.js +107 -0
  147. package/dist/storage/repositories/indicators-repo.d.ts +8 -0
  148. package/dist/storage/repositories/indicators-repo.js +98 -0
  149. package/dist/storage/repositories/intraday-klines-repo.d.ts +9 -0
  150. package/dist/storage/repositories/intraday-klines-repo.js +102 -0
  151. package/dist/storage/repositories/key-levels-history-repo.d.ts +9 -0
  152. package/dist/storage/repositories/key-levels-history-repo.js +91 -0
  153. package/dist/storage/repositories/key-levels-repo.d.ts +9 -0
  154. package/dist/storage/repositories/key-levels-repo.js +83 -0
  155. package/dist/storage/repositories/klines-repo.d.ts +8 -0
  156. package/dist/storage/repositories/klines-repo.js +60 -0
  157. package/dist/storage/repositories/news-analysis-repo.d.ts +9 -0
  158. package/dist/storage/repositories/news-analysis-repo.js +107 -0
  159. package/dist/storage/repositories/technical-analysis-repo.d.ts +9 -0
  160. package/dist/storage/repositories/technical-analysis-repo.js +80 -0
  161. package/dist/storage/repositories/watchlist-repo.d.ts +10 -0
  162. package/dist/storage/repositories/watchlist-repo.js +124 -0
  163. package/dist/storage/schemas.d.ts +13 -0
  164. package/dist/storage/schemas.js +177 -0
  165. package/dist/tools/add-stock.tool.d.ts +13 -0
  166. package/dist/tools/add-stock.tool.js +123 -0
  167. package/dist/tools/analyze.tool.d.ts +8 -0
  168. package/dist/tools/analyze.tool.js +24 -0
  169. package/dist/tools/backtest-key-levels.tool.d.ts +8 -0
  170. package/dist/tools/backtest-key-levels.tool.js +43 -0
  171. package/dist/tools/daily-update-status.tool.d.ts +6 -0
  172. package/dist/tools/daily-update-status.tool.js +9 -0
  173. package/dist/tools/fetch-financials.tool.d.ts +8 -0
  174. package/dist/tools/fetch-financials.tool.js +224 -0
  175. package/dist/tools/fetch-intraday-klines.tool.d.ts +11 -0
  176. package/dist/tools/fetch-intraday-klines.tool.js +58 -0
  177. package/dist/tools/fetch-klines.tool.d.ts +11 -0
  178. package/dist/tools/fetch-klines.tool.js +61 -0
  179. package/dist/tools/list-watchlist.tool.d.ts +6 -0
  180. package/dist/tools/list-watchlist.tool.js +22 -0
  181. package/dist/tools/monitor-status.tool.d.ts +6 -0
  182. package/dist/tools/monitor-status.tool.js +9 -0
  183. package/dist/tools/mx-search.tool.d.ts +8 -0
  184. package/dist/tools/mx-search.tool.js +77 -0
  185. package/dist/tools/mx-select-stock.tool.d.ts +8 -0
  186. package/dist/tools/mx-select-stock.tool.js +118 -0
  187. package/dist/tools/query-database.tool.d.ts +8 -0
  188. package/dist/tools/query-database.tool.js +283 -0
  189. package/dist/tools/refresh-watchlist-names.tool.d.ts +7 -0
  190. package/dist/tools/refresh-watchlist-names.tool.js +17 -0
  191. package/dist/tools/refresh-watchlist-profiles.tool.d.ts +9 -0
  192. package/dist/tools/refresh-watchlist-profiles.tool.js +67 -0
  193. package/dist/tools/remove-stock.tool.d.ts +9 -0
  194. package/dist/tools/remove-stock.tool.js +27 -0
  195. package/dist/tools/start-daily-update.tool.d.ts +10 -0
  196. package/dist/tools/start-daily-update.tool.js +23 -0
  197. package/dist/tools/start-monitor.tool.d.ts +9 -0
  198. package/dist/tools/start-monitor.tool.js +52 -0
  199. package/dist/tools/stop-daily-update.tool.d.ts +9 -0
  200. package/dist/tools/stop-daily-update.tool.js +20 -0
  201. package/dist/tools/stop-monitor.tool.d.ts +9 -0
  202. package/dist/tools/stop-monitor.tool.js +44 -0
  203. package/dist/tools/test-alert.tool.d.ts +7 -0
  204. package/dist/tools/test-alert.tool.js +21 -0
  205. package/dist/tools/update-all.tool.d.ts +9 -0
  206. package/dist/tools/update-all.tool.js +17 -0
  207. package/dist/tools/view-analysis.tool.d.ts +8 -0
  208. package/dist/tools/view-analysis.tool.js +95 -0
  209. package/dist/types/daily-update.d.ts +26 -0
  210. package/dist/types/daily-update.js +1 -0
  211. package/dist/types/domain.d.ts +140 -0
  212. package/dist/types/domain.js +1 -0
  213. package/dist/types/indicator.d.ts +43 -0
  214. package/dist/types/indicator.js +1 -0
  215. package/dist/types/monitor.d.ts +17 -0
  216. package/dist/types/monitor.js +1 -0
  217. package/dist/types/mx-search.d.ts +14 -0
  218. package/dist/types/mx-search.js +1 -0
  219. package/dist/types/mx-select-stock.d.ts +28 -0
  220. package/dist/types/mx-select-stock.js +1 -0
  221. package/dist/types/tickflow.d.ts +133 -0
  222. package/dist/types/tickflow.js +1 -0
  223. package/dist/utils/abortable-sleep.d.ts +1 -0
  224. package/dist/utils/abortable-sleep.js +20 -0
  225. package/dist/utils/china-time.d.ts +3 -0
  226. package/dist/utils/china-time.js +18 -0
  227. package/dist/utils/cost-price.d.ts +3 -0
  228. package/dist/utils/cost-price.js +18 -0
  229. package/dist/utils/format.d.ts +1 -0
  230. package/dist/utils/format.js +3 -0
  231. package/dist/utils/process.d.ts +5 -0
  232. package/dist/utils/process.js +1 -0
  233. package/dist/utils/symbol.d.ts +1 -0
  234. package/dist/utils/symbol.js +13 -0
  235. package/docs/installation.md +391 -0
  236. package/docs/usage.md +244 -0
  237. package/openclaw.plugin.json +116 -0
  238. package/package.json +57 -0
  239. package/python/indicator_runner.py +31 -0
  240. package/python/indicators.py +148 -0
  241. package/python/pyproject.toml +9 -0
  242. package/python/requirements.txt +3 -0
  243. package/python/uv.lock +366 -0
  244. package/skills/database-query/SKILL.md +58 -0
  245. package/skills/stock-analysis/SKILL.md +106 -0
  246. package/skills/usage-help/SKILL.md +102 -0
@@ -0,0 +1,102 @@
1
+ import { formatCostPrice } from "../../utils/cost-price.js";
2
+ export const COMPOSITE_ANALYSIS_SYSTEM_PROMPT = `
3
+ 你是一位A股综合分析师,需要基于技术面、基本面和资讯面三类输入形成统一结论。
4
+
5
+ 输出要求:
6
+ 1. 先输出一段 100-150 字的核心摘要,不要在正文中混入 JSON。
7
+ 2. 摘要后按以下小节分段展开,每节 2-4 句,使用清晰标题:
8
+ - 技术面与关键位
9
+ - 基本面结论
10
+ - 资讯催化与风险
11
+ - 共振/冲突与交易判断
12
+ 3. 分段内容必须明确说明技术面、基本面、资讯面之间是相互印证还是互相冲突,并给出短线交易或持仓判断。
13
+ 4. 最后输出 \`\`\`json 代码块,结构必须为:
14
+ {
15
+ "current_price": 0.0,
16
+ "stop_loss": 0.0,
17
+ "breakthrough": 0.0,
18
+ "support": 0.0,
19
+ "cost_level": 0.0,
20
+ "resistance": 0.0,
21
+ "take_profit": 0.0,
22
+ "gap": 0.0,
23
+ "target": 0.0,
24
+ "round_number": 0.0,
25
+ "score": 5
26
+ }
27
+
28
+ 规则:
29
+ - score 为最终综合评分(1-10整数)。
30
+ - current_price 必须使用提供的最新可用价格。
31
+ - 若技术面与基本面/资讯面冲突,正文必须明确指出冲突来源与影响方向。
32
+ - 综合结论必须使用A股交易语境,必要时说明涨跌停、T+1、公告催化、题材轮动、监管风险对短线判断的影响。
33
+ - 若提供了历史复盘经验,必须说明当前信号与历史经验是相互印证、需要修正,还是构成反例;但历史经验只能校准,不得覆盖当前证据。
34
+ - 不要凭空捏造未提供的数据。
35
+ `;
36
+ export function buildCompositeAnalysisUserPrompt(params) {
37
+ const latestClose = params.market.klines[params.market.klines.length - 1]?.close ?? 0;
38
+ const latestRealtimePrice = params.market.realtimeQuote?.last_price ?? latestClose;
39
+ return [
40
+ `请综合分析 ${params.market.companyName}(${params.market.symbol})。`,
41
+ `用户成本价: ${formatCostPrice(params.market.watchlistItem?.costPrice ?? null)}`,
42
+ `最新收盘价: ${latestClose.toFixed(2)}`,
43
+ `最新实时价: ${latestRealtimePrice.toFixed(2)}`,
44
+ "",
45
+ "## 技术面子结论正文",
46
+ extractNarrative(params.technicalResult.analysisText),
47
+ "",
48
+ "## 基本面子结论正文",
49
+ params.financial.available
50
+ ? extractNarrative(params.financialResult.analysisText)
51
+ : "未获取到有效财务数据,本轮综合分析不纳入基本面打分。",
52
+ "",
53
+ "## 资讯面子结论正文",
54
+ params.news.available
55
+ ? extractNarrative(params.newsResult.analysisText)
56
+ : "未获取到有效资讯数据,本轮综合分析不纳入资讯面打分。",
57
+ "",
58
+ "## 子结论结构化摘要",
59
+ `技术面关键位: ${formatLevels(params.technicalResult)}`,
60
+ `基本面评分/倾向: ${params.financialResult.score ?? "-"} / ${params.financialResult.bias}`,
61
+ `资讯面评分/倾向: ${params.newsResult.score ?? "-"} / ${params.newsResult.bias}`,
62
+ `基本面优势: ${joinList(params.financialResult.strengths)}`,
63
+ `基本面风险: ${joinList(params.financialResult.risks)}`,
64
+ `资讯催化: ${joinList(params.newsResult.catalysts)}`,
65
+ `资讯风险: ${joinList(params.newsResult.risks)}`,
66
+ "",
67
+ ...buildReviewMemoryLines(params.market.reviewMemory),
68
+ "请先输出 100-150 字核心摘要,再按“技术面与关键位 / 基本面结论 / 资讯催化与风险 / 共振或冲突与交易判断”分段展开。若给出了历史复盘经验,需要明确写出当前判断与历史经验是一致、修正还是反例。最后输出最终关键价位 JSON。",
69
+ ].join("\n");
70
+ }
71
+ function buildReviewMemoryLines(reviewMemory) {
72
+ if (!reviewMemory.available || !reviewMemory.summary.trim()) {
73
+ return [];
74
+ }
75
+ return [
76
+ "## 历史复盘经验(仅作校准)",
77
+ reviewMemory.summary,
78
+ ];
79
+ }
80
+ function formatLevels(result) {
81
+ if (!result.levels) {
82
+ return "暂无结构化关键位";
83
+ }
84
+ return [
85
+ `current=${formatMaybePrice(result.levels.current_price)}`,
86
+ `support=${formatMaybePrice(result.levels.support)}`,
87
+ `resistance=${formatMaybePrice(result.levels.resistance)}`,
88
+ `breakthrough=${formatMaybePrice(result.levels.breakthrough)}`,
89
+ `stop_loss=${formatMaybePrice(result.levels.stop_loss)}`,
90
+ `take_profit=${formatMaybePrice(result.levels.take_profit)}`,
91
+ `score=${result.levels.score}`,
92
+ ].join(", ");
93
+ }
94
+ function formatMaybePrice(value) {
95
+ return value == null ? "-" : value.toFixed(2);
96
+ }
97
+ function joinList(items) {
98
+ return items.length > 0 ? items.join(";") : "无";
99
+ }
100
+ function extractNarrative(text) {
101
+ return text.replace(/```json\s*[\s\S]*?\s*```/gi, "").trim();
102
+ }
@@ -0,0 +1,7 @@
1
+ import type { FinancialSnapshot } from "../../services/financial-service.js";
2
+ export declare const FINANCIAL_ANALYSIS_SYSTEM_PROMPT = "\n\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684A\u80A1\u57FA\u672C\u9762\u5206\u6790\u5E08\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u4EC5\u57FA\u4E8E\u63D0\u4F9B\u7684\u8D22\u52A1\u6570\u636E\uFF0C\u8BC4\u4F30\u516C\u53F8\u7684\u76C8\u5229\u80FD\u529B\u3001\u6210\u957F\u6027\u3001\u73B0\u91D1\u8D28\u91CF\u4E0E\u507F\u503A\u538B\u529B\u3002\n\n\u8F93\u51FA\u8981\u6C42\uFF1A\n1. \u5148\u7ED9\u51FA\u4E00\u6BB5 80-120 \u5B57\u4E2D\u6587\u6838\u5FC3\u7ED3\u8BBA\uFF0C\u4E0D\u8981\u5728\u6B63\u6587\u4E2D\u6DF7\u5165 JSON\u3002\n2. \u6838\u5FC3\u7ED3\u8BBA\u540E\u6309\u4EE5\u4E0B\u5C0F\u8282\u5206\u6BB5\u5C55\u5F00\uFF0C\u6BCF\u8282 1-3 \u53E5\uFF1A\n- \u76C8\u5229\u8D28\u91CF\u4E0E\u6210\u957F\u6027\n- \u73B0\u91D1\u6D41\u8D28\u91CF\n- \u8D44\u4EA7\u8D1F\u503A\u7ED3\u6784\u4E0E\u507F\u503A\u538B\u529B\n3. \u5206\u6BB5\u5185\u5BB9\u5FC5\u987B\u5C3D\u91CF\u5F15\u7528\u5DF2\u63D0\u4F9B\u7684\u8D22\u52A1\u6307\u6807\u3001\u540C\u6BD4\u53D8\u5316\u6216\u62A5\u8868\u9879\u76EE\uFF0C\u4E0D\u8981\u7A7A\u6CDB\u8868\u8FF0\u3002\n4. \u6700\u540E\u8F93\u51FA ```json \u4EE3\u7801\u5757\uFF0C\u7ED3\u6784\u5982\u4E0B\uFF1A\n{\n \"score\": 5,\n \"bias\": \"neutral\",\n \"strengths\": [\"...\"],\n \"risks\": [\"...\"],\n \"watch_items\": [\"...\"]\n}\n\n\u89C4\u5219\uFF1A\n- score \u4E3A 1-10 \u7684\u6574\u6570\u3002\n- bias \u53EA\u80FD\u662F positive / neutral / negative\u3002\n- strengths / risks / watch_items \u5404\u8F93\u51FA 1-3 \u6761\u3002\n- \u4E0D\u8981\u81C6\u9020\u6CA1\u6709\u63D0\u4F9B\u7684\u6570\u636E\uFF0C\u4E0D\u8981\u5F15\u7528\u5E02\u573A\u4EF7\u683C\u4E0EK\u7EBF\u4FE1\u606F\u3002\n";
3
+ export declare function buildFinancialAnalysisUserPrompt(params: {
4
+ symbol: string;
5
+ companyName: string;
6
+ snapshot: FinancialSnapshot;
7
+ }): string;
@@ -0,0 +1,106 @@
1
+ export const FINANCIAL_ANALYSIS_SYSTEM_PROMPT = `
2
+ 你是一位专业的A股基本面分析师。你的任务是仅基于提供的财务数据,评估公司的盈利能力、成长性、现金质量与偿债压力。
3
+
4
+ 输出要求:
5
+ 1. 先给出一段 80-120 字中文核心结论,不要在正文中混入 JSON。
6
+ 2. 核心结论后按以下小节分段展开,每节 1-3 句:
7
+ - 盈利质量与成长性
8
+ - 现金流质量
9
+ - 资产负债结构与偿债压力
10
+ 3. 分段内容必须尽量引用已提供的财务指标、同比变化或报表项目,不要空泛表述。
11
+ 4. 最后输出 \`\`\`json 代码块,结构如下:
12
+ {
13
+ "score": 5,
14
+ "bias": "neutral",
15
+ "strengths": ["..."],
16
+ "risks": ["..."],
17
+ "watch_items": ["..."]
18
+ }
19
+
20
+ 规则:
21
+ - score 为 1-10 的整数。
22
+ - bias 只能是 positive / neutral / negative。
23
+ - strengths / risks / watch_items 各输出 1-3 条。
24
+ - 不要臆造没有提供的数据,不要引用市场价格与K线信息。
25
+ `;
26
+ export function buildFinancialAnalysisUserPrompt(params) {
27
+ const income = params.snapshot.income.slice(0, 2);
28
+ const metrics = params.snapshot.metrics.slice(0, 2);
29
+ const cashFlow = params.snapshot.cashFlow.slice(0, 2);
30
+ const balanceSheet = params.snapshot.balanceSheet.slice(0, 2);
31
+ return [
32
+ `请分析 ${params.companyName}(${params.symbol})的最新财务质量。`,
33
+ "",
34
+ "## 利润表",
35
+ ...renderRows(income, [
36
+ "period_end",
37
+ "announce_date",
38
+ "revenue",
39
+ "operating_profit",
40
+ "net_income",
41
+ "net_income_attributable",
42
+ "basic_eps",
43
+ ]),
44
+ "",
45
+ "## 核心财务指标",
46
+ ...renderRows(metrics, [
47
+ "period_end",
48
+ "announce_date",
49
+ "roe",
50
+ "roa",
51
+ "gross_margin",
52
+ "net_margin",
53
+ "revenue_yoy",
54
+ "net_income_yoy",
55
+ "debt_to_asset_ratio",
56
+ "operating_cash_to_revenue",
57
+ "ocfps",
58
+ ]),
59
+ "",
60
+ "## 现金流量表",
61
+ ...renderRows(cashFlow, [
62
+ "period_end",
63
+ "announce_date",
64
+ "net_operating_cash_flow",
65
+ "net_investing_cash_flow",
66
+ "net_financing_cash_flow",
67
+ "net_cash_change",
68
+ "capex",
69
+ ]),
70
+ "",
71
+ "## 资产负债表",
72
+ ...renderRows(balanceSheet, [
73
+ "period_end",
74
+ "announce_date",
75
+ "total_assets",
76
+ "total_liabilities",
77
+ "total_equity",
78
+ "cash_and_equivalents",
79
+ "total_current_assets",
80
+ "total_current_liabilities",
81
+ "short_term_borrowing",
82
+ "long_term_borrowing",
83
+ ]),
84
+ "",
85
+ "请重点判断:盈利能力是否稳健、同比趋势是否改善、经营现金流是否支撑利润、资产负债结构是否健康。",
86
+ ].join("\n");
87
+ }
88
+ function renderRows(rows, keys) {
89
+ if (rows.length === 0) {
90
+ return ["- 暂无数据"];
91
+ }
92
+ return rows.map((row, index) => {
93
+ const record = row;
94
+ const parts = keys.map((key) => `${key}=${formatValue(record[key])}`);
95
+ return `- 第 ${index + 1} 期: ${parts.join(" | ")}`;
96
+ });
97
+ }
98
+ function formatValue(value) {
99
+ if (value == null || value === "") {
100
+ return "-";
101
+ }
102
+ if (typeof value === "number") {
103
+ return Number.isFinite(value) ? value.toFixed(4) : "-";
104
+ }
105
+ return String(value);
106
+ }
@@ -0,0 +1,7 @@
1
+ import type { FinancialLiteSnapshot } from "../../services/financial-lite-service.js";
2
+ export declare const FINANCIAL_LITE_ANALYSIS_SYSTEM_PROMPT = "\n\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684A\u80A1\u57FA\u672C\u9762\u5206\u6790\u5E08\u3002\u5F53\u524D\u662F financial-lite \u6A21\u5F0F\uFF0C\u53EA\u80FD\u57FA\u4E8E\u5C11\u91CF\u6838\u5FC3\u8D22\u52A1\u6307\u6807\u505A\u7C97\u7C92\u5EA6\u5224\u65AD\uFF0C\u4E0D\u80FD\u628A\u5B83\u5F53\u6210\u5B8C\u6574\u8D22\u62A5\u5206\u6790\u3002\n\n\u8F93\u51FA\u8981\u6C42\uFF1A\n1. \u5148\u7ED9\u51FA\u4E00\u6BB5 80-120 \u5B57\u4E2D\u6587\u6838\u5FC3\u7ED3\u8BBA\uFF0C\u4E0D\u8981\u5728\u6B63\u6587\u4E2D\u6DF7\u5165 JSON\u3002\n2. \u6838\u5FC3\u7ED3\u8BBA\u540E\u6309\u4EE5\u4E0B\u5C0F\u8282\u5206\u6BB5\u5C55\u5F00\uFF0C\u6BCF\u8282 1-3 \u53E5\uFF1A\n- \u76C8\u5229\u80FD\u529B\u4E0E\u6210\u957F\u6027\n- \u6760\u6746\u4E0E\u507F\u503A\u538B\u529B\n- \u73B0\u91D1\u6D41\u4FE1\u53F7\u6216\u8986\u76D6\u4E0D\u8DB3\u8BF4\u660E\n3. \u5982\u679C\u6307\u6807\u8986\u76D6\u4E0D\u8DB3\uFF0C\u5FC5\u987B\u660E\u786E\u6307\u51FA\u201C\u5F53\u524D\u4E3A lite \u6307\u6807\u62D6\u5E95\u6A21\u5F0F\uFF0C\u7ED3\u8BBA\u7F6E\u4FE1\u5EA6\u6709\u9650\u201D\uFF0C\u5E76\u8BF4\u660E\u7F3A\u4E86\u54EA\u4E9B\u5173\u952E\u7EF4\u5EA6\u3002\n4. \u5206\u6BB5\u5185\u5BB9\u53EA\u5141\u8BB8\u57FA\u4E8E\u5DF2\u63D0\u4F9B\u6307\u6807\u63A8\u65AD\uFF0C\u4E0D\u8981\u628A\u7F3A\u5931\u6307\u6807\u76F4\u63A5\u5F53\u6210\u8D1F\u9762\u4E8B\u5B9E\u3002\n5. \u6700\u540E\u8F93\u51FA ```json \u4EE3\u7801\u5757\uFF0C\u7ED3\u6784\u5982\u4E0B\uFF1A\n{\n \"score\": 5,\n \"bias\": \"neutral\",\n \"strengths\": [\"...\"],\n \"risks\": [\"...\"],\n \"watch_items\": [\"...\"]\n}\n\n\u89C4\u5219\uFF1A\n- score \u4E3A 1-10 \u7684\u6574\u6570\u3002\n- bias \u53EA\u80FD\u662F positive / neutral / negative\u3002\n- strengths / risks / watch_items \u5404\u8F93\u51FA 1-3 \u6761\u3002\n- \u4E0D\u8981\u81C6\u9020\u4E0D\u5B58\u5728\u7684\u8D22\u62A5\u5B57\u6BB5\uFF0C\u4E0D\u8981\u628A\u7F3A\u5931\u6307\u6807\u5F53\u6210\u8D1F\u9762\u4E8B\u5B9E\u3002\n- \u4E0D\u8981\u5F15\u7528\u5E02\u573A\u4EF7\u683C\u4E0EK\u7EBF\u4FE1\u606F\u3002\n";
3
+ export declare function buildFinancialLiteAnalysisUserPrompt(params: {
4
+ symbol: string;
5
+ companyName: string;
6
+ snapshot: FinancialLiteSnapshot;
7
+ }): string;
@@ -0,0 +1,59 @@
1
+ export const FINANCIAL_LITE_ANALYSIS_SYSTEM_PROMPT = `
2
+ 你是一位专业的A股基本面分析师。当前是 financial-lite 模式,只能基于少量核心财务指标做粗粒度判断,不能把它当成完整财报分析。
3
+
4
+ 输出要求:
5
+ 1. 先给出一段 80-120 字中文核心结论,不要在正文中混入 JSON。
6
+ 2. 核心结论后按以下小节分段展开,每节 1-3 句:
7
+ - 盈利能力与成长性
8
+ - 杠杆与偿债压力
9
+ - 现金流信号或覆盖不足说明
10
+ 3. 如果指标覆盖不足,必须明确指出“当前为 lite 指标拖底模式,结论置信度有限”,并说明缺了哪些关键维度。
11
+ 4. 分段内容只允许基于已提供指标推断,不要把缺失指标直接当成负面事实。
12
+ 5. 最后输出 \`\`\`json 代码块,结构如下:
13
+ {
14
+ "score": 5,
15
+ "bias": "neutral",
16
+ "strengths": ["..."],
17
+ "risks": ["..."],
18
+ "watch_items": ["..."]
19
+ }
20
+
21
+ 规则:
22
+ - score 为 1-10 的整数。
23
+ - bias 只能是 positive / neutral / negative。
24
+ - strengths / risks / watch_items 各输出 1-3 条。
25
+ - 不要臆造不存在的财报字段,不要把缺失指标当成负面事实。
26
+ - 不要引用市场价格与K线信息。
27
+ `;
28
+ export function buildFinancialLiteAnalysisUserPrompt(params) {
29
+ return [
30
+ `请基于 lite 基本面指标分析 ${params.companyName}(${params.symbol})。`,
31
+ `数据来源: mx_select_stock`,
32
+ `检索问句: ${params.snapshot.query}`,
33
+ `指标日期: ${params.snapshot.asOf ?? "-"}`,
34
+ `解析说明: ${params.snapshot.parserText ?? "-"}`,
35
+ "",
36
+ "## 可用核心指标",
37
+ ...renderMetrics(params.snapshot.metrics),
38
+ "",
39
+ "请基于这些指标评估盈利能力、成长性、杠杆压力与现金质量;若缺少关键指标,请在正文中明确说明覆盖有限。",
40
+ ].join("\n");
41
+ }
42
+ function renderMetrics(metrics) {
43
+ if (metrics.length === 0) {
44
+ return ["- 暂无可用指标"];
45
+ }
46
+ return metrics.map((metric) => {
47
+ const suffix = [metric.unit, metric.asOf].filter(Boolean).join(" | ");
48
+ return `- ${metric.label}=${formatValue(metric.value)}${suffix ? ` (${suffix})` : ""}`;
49
+ });
50
+ }
51
+ function formatValue(value) {
52
+ if (value == null) {
53
+ return "-";
54
+ }
55
+ if (typeof value === "number") {
56
+ return Number.isFinite(value) ? value.toFixed(4) : "-";
57
+ }
58
+ return value;
59
+ }
@@ -0,0 +1,8 @@
1
+ export { ANALYSIS_COMMON_SYSTEM_PROMPT } from "./common-system-prompt.js";
2
+ export { buildKlineAnalysisUserPrompt } from "./kline-analysis-user-prompt.js";
3
+ export { FINANCIAL_ANALYSIS_SYSTEM_PROMPT, buildFinancialAnalysisUserPrompt, } from "./financial-analysis-user-prompt.js";
4
+ export { FINANCIAL_LITE_ANALYSIS_SYSTEM_PROMPT, buildFinancialLiteAnalysisUserPrompt, } from "./financial-lite-analysis-user-prompt.js";
5
+ export { NEWS_ANALYSIS_SYSTEM_PROMPT, buildNewsAnalysisUserPrompt, } from "./news-analysis-user-prompt.js";
6
+ export { COMPOSITE_ANALYSIS_SYSTEM_PROMPT, buildCompositeAnalysisUserPrompt, } from "./composite-analysis-user-prompt.js";
7
+ export { POST_CLOSE_REVIEW_SYSTEM_PROMPT, buildPostCloseReviewUserPrompt, } from "./post-close-review-user-prompt.js";
8
+ export { WATCHLIST_PROFILE_EXTRACTION_SYSTEM_PROMPT, buildWatchlistProfileExtractionUserPrompt, } from "./watchlist-profile-extraction-prompt.js";
@@ -0,0 +1,8 @@
1
+ export { ANALYSIS_COMMON_SYSTEM_PROMPT } from "./common-system-prompt.js";
2
+ export { buildKlineAnalysisUserPrompt } from "./kline-analysis-user-prompt.js";
3
+ export { FINANCIAL_ANALYSIS_SYSTEM_PROMPT, buildFinancialAnalysisUserPrompt, } from "./financial-analysis-user-prompt.js";
4
+ export { FINANCIAL_LITE_ANALYSIS_SYSTEM_PROMPT, buildFinancialLiteAnalysisUserPrompt, } from "./financial-lite-analysis-user-prompt.js";
5
+ export { NEWS_ANALYSIS_SYSTEM_PROMPT, buildNewsAnalysisUserPrompt, } from "./news-analysis-user-prompt.js";
6
+ export { COMPOSITE_ANALYSIS_SYSTEM_PROMPT, buildCompositeAnalysisUserPrompt, } from "./composite-analysis-user-prompt.js";
7
+ export { POST_CLOSE_REVIEW_SYSTEM_PROMPT, buildPostCloseReviewUserPrompt, } from "./post-close-review-user-prompt.js";
8
+ export { WATCHLIST_PROFILE_EXTRACTION_SYSTEM_PROMPT, buildWatchlistProfileExtractionUserPrompt, } from "./watchlist-profile-extraction-prompt.js";
@@ -0,0 +1,13 @@
1
+ import type { IndicatorRow } from "../../types/indicator.js";
2
+ import type { TickFlowIntradayKlineRow, TickFlowKlineRow, TickFlowQuote } from "../../types/tickflow.js";
3
+ import type { ReviewMemoryContext } from "../../analysis/types/composite-analysis.js";
4
+ export declare function buildKlineAnalysisUserPrompt(params: {
5
+ symbol: string;
6
+ costPrice: number | null;
7
+ klines: TickFlowKlineRow[];
8
+ indicators: IndicatorRow[];
9
+ intradayKlines: TickFlowIntradayKlineRow[];
10
+ intradayIndicators: IndicatorRow[];
11
+ realtimeQuote: TickFlowQuote | null;
12
+ reviewMemory?: ReviewMemoryContext | null;
13
+ }): string;
@@ -0,0 +1,215 @@
1
+ import { formatCostPrice } from "../../utils/cost-price.js";
2
+ export function buildKlineAnalysisUserPrompt(params) {
3
+ const recentK = params.klines.slice(-30);
4
+ const recentIndicators = params.indicators.slice(-10);
5
+ const latest = params.indicators[params.indicators.length - 1];
6
+ const latestClose = params.klines[params.klines.length - 1]?.close ?? 0;
7
+ const latestRealtimePrice = params.realtimeQuote?.last_price ?? latestClose;
8
+ const latestIntradayIndicator = params.intradayIndicators[params.intradayIndicators.length - 1];
9
+ const klineLines = [
10
+ "## 日K线数据(最近30个交易日)",
11
+ "",
12
+ "```csv",
13
+ "日期,开盘,最高,最低,收盘,成交量,成交额",
14
+ ...recentK.map((row) => [
15
+ row.trade_date,
16
+ fmt(row.open),
17
+ fmt(row.high),
18
+ fmt(row.low),
19
+ fmt(row.close),
20
+ fmtInteger(row.volume),
21
+ fmtInteger(row.amount),
22
+ ].join(",")),
23
+ "```",
24
+ ];
25
+ const indicatorLines = [
26
+ "## 技术指标(最近10个交易日)",
27
+ "",
28
+ "```csv",
29
+ "日期,MA5,MA10,MA20,MA60,MACD,Signal,RSI6,RSI12,KDJ_K,KDJ_D,KDJ_J,CCI,ADX",
30
+ ...recentIndicators.map((row) => [
31
+ row.trade_date,
32
+ fmt(row.ma5),
33
+ fmt(row.ma10),
34
+ fmt(row.ma20),
35
+ fmt(row.ma60),
36
+ fmt(row.macd, 4),
37
+ fmt(row.macd_signal, 4),
38
+ fmt(row.rsi_6),
39
+ fmt(row.rsi_12),
40
+ fmt(row.kdj_k),
41
+ fmt(row.kdj_d),
42
+ fmt(row.kdj_j),
43
+ fmt(row.cci),
44
+ fmt(row.adx),
45
+ ].join(",")),
46
+ "```",
47
+ ];
48
+ const latestLines = latest
49
+ ? [
50
+ "## 最新指标状态",
51
+ "",
52
+ `- MACD: DIF=${fmt(latest.macd, 4)}, DEA=${fmt(latest.macd_signal, 4)}, 柱状=${fmt(latest.macd_hist, 4)}`,
53
+ `- KDJ: K=${fmt(latest.kdj_k)}, D=${fmt(latest.kdj_d)}, J=${fmt(latest.kdj_j)}`,
54
+ `- RSI: RSI6=${fmt(latest.rsi_6)}, RSI12=${fmt(latest.rsi_12)}, RSI24=${fmt(latest.rsi_24)}`,
55
+ `- CCI: ${fmt(latest.cci)}`,
56
+ `- BIAS: 6日=${fmt(latest.bias_6)}, 12日=${fmt(latest.bias_12)}, 24日=${fmt(latest.bias_24)}`,
57
+ `- DMI: +DI=${fmt(latest.plus_di)}, -DI=${fmt(latest.minus_di)}, ADX=${fmt(latest.adx)}`,
58
+ `- BOLL: 上轨=${fmt(latest.boll_upper)}, 中轨=${fmt(latest.boll_mid)}, 下轨=${fmt(latest.boll_lower)}`,
59
+ ]
60
+ : [];
61
+ const realtimeLines = buildRealtimeLines(params.realtimeQuote);
62
+ const reviewMemoryLines = buildReviewMemoryLines(params.reviewMemory);
63
+ const intradaySummaryLines = buildIntradaySummaryLines(params.intradayKlines, latestIntradayIndicator, params.realtimeQuote);
64
+ const intradayKlineLines = buildIntradayKlineLines(params.intradayKlines);
65
+ const intradayIndicatorLines = buildIntradayIndicatorLines(params.intradayIndicators);
66
+ return [
67
+ "请结合日线、日内分钟线、分钟指标和实时行情分析以下股票的技术面,并补充日内走势判断,给出关键价位。",
68
+ "",
69
+ `**股票代码**: ${params.symbol}`,
70
+ `**用户成本价**: ${formatCostPrice(params.costPrice, " 元")}`,
71
+ `**最新收盘价**: ${latestClose.toFixed(2)} 元`,
72
+ `**最新实时价**: ${latestRealtimePrice.toFixed(2)} 元`,
73
+ "",
74
+ ...realtimeLines,
75
+ "",
76
+ ...klineLines,
77
+ "",
78
+ ...indicatorLines,
79
+ "",
80
+ ...latestLines,
81
+ "",
82
+ ...reviewMemoryLines,
83
+ ...intradaySummaryLines,
84
+ "",
85
+ ...intradayKlineLines,
86
+ "",
87
+ ...intradayIndicatorLines,
88
+ "",
89
+ "请先给出日线趋势判断,再补充明确的日内走势判断(例如震荡上行、冲高回落、弱势横盘、尾盘转强等)。若历史复盘经验提示近期假突破、支撑失效或止损先到偏多,需要明确判断当前是否仍在重复该模式;但若当前实时走势与历史经验冲突,以当前数据为主。最后输出完整关键价位数据。",
90
+ ].join("\n");
91
+ }
92
+ function buildReviewMemoryLines(reviewMemory) {
93
+ if (!reviewMemory?.available || !reviewMemory.summary.trim()) {
94
+ return [];
95
+ }
96
+ return [
97
+ "## 历史复盘经验(仅作校准)",
98
+ reviewMemory.summary,
99
+ ];
100
+ }
101
+ function fmt(value, digits = 2) {
102
+ if (value == null || Number.isNaN(value)) {
103
+ return "-";
104
+ }
105
+ return stripTrailingZeros(value.toFixed(digits));
106
+ }
107
+ function fmtPercent(value, digits = 2) {
108
+ return value == null || Number.isNaN(value) ? "-" : `${fmt(value, digits)}%`;
109
+ }
110
+ function fmtInteger(value) {
111
+ if (value == null || Number.isNaN(value)) {
112
+ return "-";
113
+ }
114
+ return String(Math.trunc(value));
115
+ }
116
+ function buildRealtimeLines(quote) {
117
+ if (!quote) {
118
+ return ["## 实时行情", "", "- 暂无实时行情数据"];
119
+ }
120
+ return [
121
+ "## 实时行情",
122
+ "",
123
+ `- 最新价: ${fmt(quote.last_price)}`,
124
+ `- 前收: ${fmt(quote.prev_close)}`,
125
+ `- 涨跌幅: ${fmtPercent(quote.ext?.change_pct)}`,
126
+ `- 成交量: ${Math.trunc(Number(quote.volume ?? 0))}`,
127
+ `- 行情时间: ${formatTimestamp(quote.timestamp)}`,
128
+ ];
129
+ }
130
+ function buildIntradaySummaryLines(rows, latestIndicator, quote) {
131
+ if (rows.length === 0) {
132
+ return ["## 今日分钟线概览", "", "- 今日暂无分钟K线数据"];
133
+ }
134
+ const first = rows[0];
135
+ const last = rows[rows.length - 1];
136
+ const sessionHigh = Math.max(...rows.map((row) => row.high));
137
+ const sessionLow = Math.min(...rows.map((row) => row.low));
138
+ const sessionVolume = rows.reduce((sum, row) => sum + row.volume, 0);
139
+ const prevClose = quote?.prev_close ?? last.prev_close ?? first.prev_close;
140
+ const sessionChangePct = prevClose > 0 ? ((last.close - prevClose) / prevClose) * 100 : null;
141
+ const lines = [
142
+ "## 今日分钟线概览",
143
+ "",
144
+ `- 周期: ${last.period}`,
145
+ `- 根数: ${rows.length}`,
146
+ `- 区间: ${first.trade_time} ~ ${last.trade_time}`,
147
+ `- 日内开盘/最高/最低/最新: ${fmt(first.open)} / ${fmt(sessionHigh)} / ${fmt(sessionLow)} / ${fmt(last.close)}`,
148
+ `- 相对前收涨跌幅: ${fmtPercent(sessionChangePct)}`,
149
+ `- 日内累计成交量: ${Math.trunc(sessionVolume)}`,
150
+ ];
151
+ if (latestIndicator) {
152
+ lines.push(`- 分钟指标: MA5=${fmt(latestIndicator.ma5)} | MA10=${fmt(latestIndicator.ma10)} | MACD=${fmt(latestIndicator.macd, 4)} | RSI6=${fmt(latestIndicator.rsi_6)} | KDJ_K=${fmt(latestIndicator.kdj_k)}`);
153
+ }
154
+ return lines;
155
+ }
156
+ function buildIntradayKlineLines(rows) {
157
+ if (rows.length === 0) {
158
+ return ["## 今日分钟K线", "", "- 暂无分钟K线数据"];
159
+ }
160
+ return [
161
+ `## 今日分钟K线(全部 ${rows.length} 根)`,
162
+ "",
163
+ "```csv",
164
+ "时间,开盘,最高,最低,收盘,成交量,成交额",
165
+ ...rows.map((row) => [
166
+ row.trade_time,
167
+ fmt(row.open),
168
+ fmt(row.high),
169
+ fmt(row.low),
170
+ fmt(row.close),
171
+ fmtInteger(row.volume),
172
+ fmtInteger(row.amount),
173
+ ].join(",")),
174
+ "```",
175
+ ];
176
+ }
177
+ function buildIntradayIndicatorLines(rows) {
178
+ if (rows.length === 0) {
179
+ return ["## 今日分钟指标", "", "- 暂无分钟指标数据"];
180
+ }
181
+ return [
182
+ `## 今日分钟指标(全部 ${rows.length} 条)`,
183
+ "",
184
+ "```csv",
185
+ "时间,MA5,MA10,MA20,MACD,Signal,RSI6,KDJ_K,KDJ_D,KDJ_J",
186
+ ...rows.map((row) => [
187
+ row.trade_time ?? "-",
188
+ fmt(row.ma5),
189
+ fmt(row.ma10),
190
+ fmt(row.ma20),
191
+ fmt(row.macd, 4),
192
+ fmt(row.macd_signal, 4),
193
+ fmt(row.rsi_6),
194
+ fmt(row.kdj_k),
195
+ fmt(row.kdj_d),
196
+ fmt(row.kdj_j),
197
+ ].join(",")),
198
+ "```",
199
+ ];
200
+ }
201
+ function stripTrailingZeros(value) {
202
+ return value.replace(/(?:\.0+|(\.\d*?[1-9])0+)$/, "$1");
203
+ }
204
+ function formatTimestamp(timestamp) {
205
+ return new Intl.DateTimeFormat("sv-SE", {
206
+ timeZone: "Asia/Shanghai",
207
+ year: "numeric",
208
+ month: "2-digit",
209
+ day: "2-digit",
210
+ hour: "2-digit",
211
+ minute: "2-digit",
212
+ second: "2-digit",
213
+ hour12: false,
214
+ }).format(new Date(timestamp));
215
+ }
@@ -0,0 +1,8 @@
1
+ import type { MxSearchDocument } from "../../types/mx-search.js";
2
+ export declare const NEWS_ANALYSIS_SYSTEM_PROMPT = "\n\u4F60\u662F\u4E00\u4F4D\u4E13\u4E1A\u7684A\u80A1\u8D44\u8BAF\u5206\u6790\u5E08\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u4EC5\u57FA\u4E8E\u63D0\u4F9B\u7684\u65B0\u95FB\u3001\u516C\u544A\u3001\u7814\u62A5\u548C\u4E8B\u4EF6\u4FE1\u606F\uFF0C\u63D0\u70BC\u77ED\u671F\u50AC\u5316\u3001\u98CE\u9669\u70B9\u4E0E\u4FE1\u606F\u9762\u503E\u5411\u3002\n\n\u8F93\u51FA\u8981\u6C42\uFF1A\n1. \u5148\u7ED9\u51FA\u4E00\u6BB5 80-120 \u5B57\u4E2D\u6587\u6838\u5FC3\u7ED3\u8BBA\uFF0C\u4E0D\u8981\u5728\u6B63\u6587\u4E2D\u6DF7\u5165 JSON\u3002\n2. \u6838\u5FC3\u7ED3\u8BBA\u540E\u6309\u4EE5\u4E0B\u5C0F\u8282\u5206\u6BB5\u5C55\u5F00\uFF0C\u6BCF\u8282 1-3 \u53E5\uFF1A\n- \u4E3B\u8981\u50AC\u5316\n- \u4E3B\u8981\u98CE\u9669\n- \u540E\u7EED\u8DDF\u8E2A\u70B9\n3. \u5206\u6BB5\u5185\u5BB9\u4F18\u5148\u5F15\u7528\u8F83\u65B0\u3001\u8F83\u9AD8\u76F8\u5173\u7684\u8D44\u8BAF\uFF0C\u4E0D\u8981\u6CDB\u5316\u590D\u8FF0\u4F4E\u76F8\u5173\u5185\u5BB9\u3002\n4. \u6700\u540E\u8F93\u51FA ```json \u4EE3\u7801\u5757\uFF0C\u7ED3\u6784\u5982\u4E0B\uFF1A\n{\n \"score\": 5,\n \"bias\": \"neutral\",\n \"catalysts\": [\"...\"],\n \"risks\": [\"...\"],\n \"watch_items\": [\"...\"]\n}\n\n\u89C4\u5219\uFF1A\n- score \u4E3A 1-10 \u7684\u6574\u6570\uFF0C\u4EE3\u8868\u8D44\u8BAF\u9762\u5BF9\u80A1\u4EF7\u7684\u652F\u6301\u5F3A\u5F31\u3002\n- bias \u53EA\u80FD\u662F positive / neutral / negative\u3002\n- catalysts / risks / watch_items \u5404\u8F93\u51FA 1-3 \u6761\u3002\n- \u4F18\u5148\u63D0\u53D6\u9AD8\u76F8\u5173\u3001\u8F83\u65B0\u7684\u4FE1\u606F\uFF0C\u4E0D\u8981\u590D\u8FF0\u65E0\u5173\u514D\u8D23\u58F0\u660E\u3002\n- A\u80A1\u8BED\u5883\u4E0B\uFF0C\u516C\u544A\u3001\u4E1A\u7EE9\u9884\u544A/\u5FEB\u62A5\u3001\u76D1\u7BA1\u95EE\u8BE2/\u5904\u7F5A\u3001\u80A1\u4E1C\u589E\u51CF\u6301\u3001\u4E2D\u6807\u8BA2\u5355\u3001\u8D44\u4EA7\u91CD\u7EC4\u3001\u9898\u6750\u50AC\u5316\u7684\u4F18\u5148\u7EA7\u5E94\u9AD8\u4E8E\u6CDB\u5A92\u4F53\u89E3\u8BFB\u3002\n- \u82E5\u8D44\u8BAF\u53EA\u53CD\u6620\u60C5\u7EEA\u6216\u9898\u6750\u7092\u4F5C\uFF0C\u6CA1\u6709\u5F62\u6210\u786C\u50AC\u5316\uFF0C\u5FC5\u987B\u660E\u786E\u6307\u51FA\u6301\u7EED\u6027\u98CE\u9669\u3002\n";
3
+ export declare function buildNewsAnalysisUserPrompt(params: {
4
+ symbol: string;
5
+ companyName: string;
6
+ query: string;
7
+ documents: MxSearchDocument[];
8
+ }): string;
@@ -0,0 +1,57 @@
1
+ export const NEWS_ANALYSIS_SYSTEM_PROMPT = `
2
+ 你是一位专业的A股资讯分析师。你的任务是仅基于提供的新闻、公告、研报和事件信息,提炼短期催化、风险点与信息面倾向。
3
+
4
+ 输出要求:
5
+ 1. 先给出一段 80-120 字中文核心结论,不要在正文中混入 JSON。
6
+ 2. 核心结论后按以下小节分段展开,每节 1-3 句:
7
+ - 主要催化
8
+ - 主要风险
9
+ - 后续跟踪点
10
+ 3. 分段内容优先引用较新、较高相关的资讯,不要泛化复述低相关内容。
11
+ 4. 最后输出 \`\`\`json 代码块,结构如下:
12
+ {
13
+ "score": 5,
14
+ "bias": "neutral",
15
+ "catalysts": ["..."],
16
+ "risks": ["..."],
17
+ "watch_items": ["..."]
18
+ }
19
+
20
+ 规则:
21
+ - score 为 1-10 的整数,代表资讯面对股价的支持强弱。
22
+ - bias 只能是 positive / neutral / negative。
23
+ - catalysts / risks / watch_items 各输出 1-3 条。
24
+ - 优先提取高相关、较新的信息,不要复述无关免责声明。
25
+ - A股语境下,公告、业绩预告/快报、监管问询/处罚、股东增减持、中标订单、资产重组、题材催化的优先级应高于泛媒体解读。
26
+ - 若资讯只反映情绪或题材炒作,没有形成硬催化,必须明确指出持续性风险。
27
+ `;
28
+ export function buildNewsAnalysisUserPrompt(params) {
29
+ return [
30
+ `请分析 ${params.companyName}(${params.symbol})最近资讯的信息面影响。`,
31
+ `检索问句: ${params.query}`,
32
+ "",
33
+ "## 检索结果",
34
+ ...renderDocuments(params.documents),
35
+ "",
36
+ "请重点判断:短期催化、核心风险、是否存在一致性乐观/悲观预期,以及接下来需要继续核实的点。",
37
+ ].join("\n");
38
+ }
39
+ function renderDocuments(documents) {
40
+ if (documents.length === 0) {
41
+ return ["- 暂无资讯结果"];
42
+ }
43
+ return documents.map((document, index) => {
44
+ const source = document.source ? ` | 来源=${document.source}` : "";
45
+ const time = document.publishedAt ? ` | 时间=${document.publishedAt}` : "";
46
+ return [
47
+ `- 第 ${index + 1} 条: ${document.title}${time}${source}`,
48
+ ` 正文摘要=${truncate(document.trunk, 900)}`,
49
+ ].join("\n");
50
+ });
51
+ }
52
+ function truncate(text, maxLength) {
53
+ if (text.length <= maxLength) {
54
+ return text;
55
+ }
56
+ return `${text.slice(0, maxLength)}...`;
57
+ }
@@ -0,0 +1,3 @@
1
+ import type { PostCloseReviewInput } from "../../analysis/types/composite-analysis.js";
2
+ export declare const POST_CLOSE_REVIEW_SYSTEM_PROMPT = "\n\u4F60\u662F\u4E00\u4F4DA\u80A1\u6536\u76D8\u590D\u76D8\u5206\u6790\u5E08\uFF0C\u9700\u8981\u5728\u6536\u76D8\u540E\u540C\u65F6\u5B8C\u6210\u201C\u6628\u65E5\u5173\u952E\u4F4D\u9A8C\u8BC1 + \u4ECA\u65E5\u76D8\u9762\u590D\u76D8 + \u660E\u65E5\u5173\u952E\u4F4D\u5904\u7406\u51B3\u5B9A\u201D\u3002\n\n\u8F93\u51FA\u8981\u6C42\uFF1A\n1. \u6B63\u6587\u6309\u4EE5\u4E0B\u6807\u9898\u8F93\u51FA\uFF0C\u6BCF\u8282 2-4 \u53E5\uFF1A\n- \u6628\u65E5\u5173\u952E\u4F4D\u9A8C\u8BC1\n- \u4ECA\u65E5\u76D8\u9762\n- \u5927\u76D8\u4E0E\u677F\u5757\n- \u65B0\u95FB\u4E0E\u516C\u544A\n- \u660E\u65E5\u5173\u952E\u4F4D\u5904\u7406\n- \u64CD\u4F5C\u5EFA\u8BAE\n2. \u201C\u6628\u65E5\u5173\u952E\u4F4D\u9A8C\u8BC1\u201D\u5FC5\u987B\u4E25\u683C\u4F9D\u636E\u8F93\u5165\u91CC\u7ED9\u51FA\u7684\u9A8C\u8BC1\u7ED3\u679C\uFF0C\u4E0D\u5F97\u6539\u5199\u6210\u4E0E\u6570\u636E\u51B2\u7A81\u7684\u7ED3\u8BBA\u3002\n3. \u201C\u660E\u65E5\u5173\u952E\u4F4D\u5904\u7406\u201D\u5FC5\u987B\u660E\u786E\u7ED9\u51FA\u56DB\u9009\u4E00\u7ED3\u8BBA\uFF1Akeep / adjust / recompute / invalidate\u3002\n4. \u6700\u540E\u8F93\u51FA\u4E00\u4E2A ```json \u4EE3\u7801\u5757\uFF0C\u7ED3\u6784\u5FC5\u987B\u4E3A\uFF1A\n{\n \"session_summary\": \"\",\n \"market_sector_summary\": \"\",\n \"news_summary\": \"\",\n \"decision\": \"keep|adjust|recompute|invalidate\",\n \"decision_reason\": \"\",\n \"action_advice\": \"\",\n \"market_bias\": \"tailwind|neutral|headwind\",\n \"sector_bias\": \"tailwind|neutral|headwind\",\n \"news_impact\": \"supportive|neutral|disruptive\",\n \"levels\": {\n \"current_price\": 0.0,\n \"stop_loss\": 0.0,\n \"breakthrough\": 0.0,\n \"support\": 0.0,\n \"cost_level\": 0.0,\n \"resistance\": 0.0,\n \"take_profit\": 0.0,\n \"gap\": 0.0,\n \"target\": 0.0,\n \"round_number\": 0.0,\n \"score\": 5\n }\n}\n\n\u89C4\u5219\uFF1A\n- \u82E5 decision=invalidate\uFF0Clevels \u53EF\u4EE5\u4E3A null\uFF1B\u5426\u5219 levels \u5FC5\u987B\u5B8C\u6574\u7ED9\u51FA\u3002\n- current_price \u5FC5\u987B\u4F7F\u7528\u63D0\u4F9B\u7684\u6700\u65B0\u6536\u76D8\u4EF7\u6216\u6700\u65B0\u5B9E\u65F6\u4EF7\u3002\n- \u82E5\u5927\u76D8\u987A\u98CE\u4F46\u884C\u4E1A\u5206\u7C7B/\u6982\u5FF5\u677F\u5757\u504F\u9006\u98CE\uFF0C\u5FC5\u987B\u660E\u786E\u6307\u51FA\u51B2\u7A81\uFF0C\u4E0D\u5F97\u7B3C\u7EDF\u7ED9\u591A\u5934\u7ED3\u8BBA\u3002\n- \u82E5\u65B0\u95FB\u53EA\u662F\u566A\u97F3\uFF0C\u4E5F\u8981\u660E\u786E\u5199\u201C\u672A\u6784\u6210\u4E3B\u8981\u89E3\u91CA\u201D\u6216\u7C7B\u4F3C\u8868\u8FF0\u3002\n- \u4E0D\u8981\u51ED\u7A7A\u7F16\u9020\u6982\u5FF5\u677F\u5757\u3001\u6307\u6570\u8868\u73B0\u6216\u516C\u544A\u5185\u5BB9\u3002\n";
3
+ export declare function buildPostCloseReviewUserPrompt(input: PostCloseReviewInput): string;