From 41d19b5a368700fc5ea6ba6c03f27d640580a8a7 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Thu, 30 Apr 2026 22:52:35 +0800 Subject: [PATCH] 1 --- frontend/src/app/(auth)/chat/page.tsx | 28 +---- frontend/src/app/(auth)/dashboard/page.tsx | 65 ++++++----- frontend/src/app/(auth)/diagnose/page.tsx | 1 - .../src/app/(auth)/recommendations/page.tsx | 63 +++++------ frontend/src/app/(auth)/sectors/page.tsx | 101 ++++++++---------- frontend/src/app/(auth)/stock/[code]/page.tsx | 4 +- frontend/src/app/(auth)/strategy/page.tsx | 73 ++++--------- frontend/src/app/(auth)/watchlists/page.tsx | 4 - frontend/src/components/market-temp.tsx | 1 - frontend/src/components/sector-heatmap.tsx | 7 +- frontend/src/components/stock-card.tsx | 6 +- 11 files changed, 127 insertions(+), 226 deletions(-) diff --git a/frontend/src/app/(auth)/chat/page.tsx b/frontend/src/app/(auth)/chat/page.tsx index c9305013..f0394e5a 100644 --- a/frontend/src/app/(auth)/chat/page.tsx +++ b/frontend/src/app/(auth)/chat/page.tsx @@ -20,15 +20,15 @@ const QUICK_QUESTIONS = [ const CHAT_SCENES = [ { title: "问今日打法", - description: "把今日结论翻译成人话,说明现在该进攻、试错还是防守。", + description: "进攻 / 试错 / 防守", }, { title: "问推荐池", - description: "追问某只推荐股为什么进池、什么条件下能看、什么条件下放弃。", + description: "进池原因 / 触发 / 放弃", }, { title: "问自选股", - description: "围绕你自己的观察池、候选池和持仓池做连续追问。", + description: "观察池 / 候选池 / 持仓池", }, ]; @@ -111,9 +111,6 @@ export default function ChatPage() { Combat Chat

AI 作战问答

-

- 这里的价值不在聊天,而在于把今日作战结论、推荐池和你的自选股串起来,支持继续追问。 -

@@ -129,17 +126,6 @@ export default function ChatPage() { ))}
- -
-
- 使用原则 -
-
-

优先问系统已经有的数据和结论,不要把它当成泛财经陪聊。

-

连续追问同一只股票或同一条主线,比重新开一个宽泛问题更有效。

-

它会读取你的自选股上下文,所以很适合问“我该先看哪几只”。

-
-
@@ -177,10 +163,7 @@ export default function ChatPage() { -

先用它来拆解系统已经给出的结论

-

- 这不是泛用 AI 问答框。更好的用法是直接追问今天该怎么打、推荐池为什么这样分层、你的自选股哪些该提级或降级。 -

+

追问作战结论

@@ -260,9 +243,6 @@ export default function ChatPage() { 发送
-
- 这里只适合围绕系统数据追问,不适合作为无上下文的泛财经问答。 -
diff --git a/frontend/src/app/(auth)/dashboard/page.tsx b/frontend/src/app/(auth)/dashboard/page.tsx index 29c27766..ab51864b 100644 --- a/frontend/src/app/(auth)/dashboard/page.tsx +++ b/frontend/src/app/(auth)/dashboard/page.tsx @@ -214,7 +214,6 @@ export default function DashboardPage() { )} -

先看结论,再看动作,再看焦点标的。

@@ -305,13 +304,13 @@ function DecisionHero({ ) : null}

{summary.headline}

-

+

{summary.detail}

- - + +
@@ -368,7 +367,6 @@ function FocusPanel({

焦点标的

-

首页只保留最该处理的少量标的。

@@ -382,7 +380,7 @@ function FocusPanel({ focusQueue.map((rec) => ) ) : (
- 今天没有需要处理的焦点标的。 + 暂无焦点标的。
)}
@@ -409,7 +407,6 @@ function MarketSnapshot({

市场证据

-

只保留对今天决策有用的信息。

温度 {Math.round(marketTemperature?.temperature ?? 0)} @@ -714,34 +711,34 @@ function buildMarketSummary( const temp = marketTemperature?.temperature ?? board?.metrics.temperature ?? 0; const allowTrading = strategyProfile?.allow_trading ?? actionableCount > 0; const headline = !allowTrading - ? "今天不主动出手,先防守观察" + ? "防守观察" : board?.market_regime ?? - (temp >= 70 ? "市场偏强,可以围绕主线进攻" : - temp >= 50 ? "市场可做,但只做确认机会" : - temp >= 30 ? "市场分化,轻仓试错" : - "市场偏弱,以观察为主"); + (temp >= 70 ? "主线进攻" : + temp >= 50 ? "确认机会" : + temp >= 30 ? "轻仓试错" : + "偏弱观察"); const detail = strategyProfile?.decision_note ?? board?.summary ?? (scanStatus?.is_trading - ? "当前使用盘中实时数据判断市场,重点在节奏、仓位和主线强弱,而不是静态分数。" - : "当前以收盘后数据为主,适合复盘主线、更新候选池和准备下一交易日。"); + ? "盘中实时:看节奏、仓位、主线强弱。" + : "收盘快照:复盘主线,准备下一交易日。"); const canDo = [ !allowTrading - ? "今天只做观察和等待,不把普通异动抬升为买入机会。" + ? "观察等待。" : actionableCount > 0 - ? `优先只看 ${actionableCount} 只可操作标的,避免在杂波里分散注意力。` - : "没有明确可操作标的时,只保留观察,不主动开新仓。", - watchCount > 0 ? `重点关注 ${watchCount} 只等待确认的标的,等放量、回流或分歧转一致。` : "把注意力放在最强板块前排,而不是平均分配给所有候选。", - board?.position_suggestion ?? (strategyProfile?.max_position_pct ? `总仓位上限先按 ${strategyProfile.max_position_pct}% 控制。` : temp >= 50 ? "仓位可以试错,但不要脱离主线。" : "控制仓位,等待更强确认。"), + ? `只看 ${actionableCount} 只可操作标的。` + : "无可操作标的,保留观察。", + watchCount > 0 ? `关注 ${watchCount} 只确认信号。` : "盯最强板块前排。", + board?.position_suggestion ?? (strategyProfile?.max_position_pct ? `仓位上限 ${strategyProfile.max_position_pct}%。` : temp >= 50 ? "围绕主线试错。" : "控制仓位。"), ]; const cannotDo = [ board?.avoid_rules?.[0] ?? "不要追后排、跟风和没有板块支撑的个股。", - board?.avoid_rules?.[1] ?? (temp < 50 ? "不要因为个别异动就误判成全面回暖。" : "不要把盘中脉冲当成全天主线。"), - !allowTrading || temp < 40 ? "不要扩大仓位做逆势试错。" : "不要脱离纪律随意切换题材。", + board?.avoid_rules?.[1] ?? (temp < 50 ? "不把个别异动当回暖。" : "不把盘中脉冲当主线。"), + !allowTrading || temp < 40 ? "不逆势加仓。" : "不随意切换题材。", ]; return { @@ -772,28 +769,28 @@ function buildActionGuides( const priority = [ !allowTrading - ? "先等市场重新给出清晰主线和承接,不主动寻找执行票。" + ? "等待清晰主线和承接。" : actionable[0] - ? `先盯 ${actionable[0].name}${actionable[0].trigger_condition ? `,触发条件是 ${actionable[0].trigger_condition}` : " 的确认信号"}。` + ? `盯 ${actionable[0].name}${actionable[0].trigger_condition ? `:${actionable[0].trigger_condition}` : " 的确认信号"}。` : focusSectors[0] - ? `主看 ${focusSectors[0]} 前排是否继续强化,再决定是否参与。` - : "先观察龙头强度和市场承接,等待更清晰信号。", + ? `看 ${focusSectors[0]} 前排强度。` + : "等待更清晰信号。", focusSectors[1] - ? `把 ${focusSectors.slice(0, 2).join("、")} 作为主线池,不要同时追太多方向。` - : "今天只围绕一条最强主线做决策,避免来回切换。", - !allowTrading ? "今天优先保守观察,不做预判型交易。" : temp >= 50 ? "优先做分歧后的回流和确认,不做无量冲高。" : "优先保守观察,只有最强确认才考虑出手。", + ? `主线池:${focusSectors.slice(0, 2).join("、")}。` + : "只围绕最强主线。", + !allowTrading ? "保守观察。" : temp >= 50 ? "做回流确认,不做无量冲高。" : "只看最强确认。", ]; const watchItems = [ watch[0] - ? `${watch[0].name} 处于等待确认阶段,先看量能、板块回流和前排承接。` + ? `${watch[0].name}:量能、回流、承接。` : focusSectors[0] - ? `${focusSectors[0]} 仍值得盯,但不满足确认前不追。` - : "观察是否会出现新的主线聚焦。", + ? `${focusSectors[0]}:确认前不追。` + : "观察新主线聚焦。", watch[1] - ? `${watch[1].name} 适合放进观察队列,不在首页直接下结论。` - : "盘中若出现新热点,先确认是否有板块扩散,再决定是否纳入观察。", - observe.length > 0 ? `其余 ${observe.length} 只候选保持后台观察,不占用首页决策空间。` : "没有必要在首页堆更多弱标的。", + ? `${watch[1].name}:观察队列。` + : "新热点先看板块扩散。", + observe.length > 0 ? `后台观察 ${observe.length} 只。` : "暂无弱候选。", ]; const avoid = [ diff --git a/frontend/src/app/(auth)/diagnose/page.tsx b/frontend/src/app/(auth)/diagnose/page.tsx index 78ec2259..cf780419 100644 --- a/frontend/src/app/(auth)/diagnose/page.tsx +++ b/frontend/src/app/(auth)/diagnose/page.tsx @@ -325,7 +325,6 @@ export default function DiagnosePage() {
结构化结论
-
先看当前结论,再看完整长文分析。
))}
- -
-
方法说明
-
- 这个页面现在承担“今天怎么做”的职责,不再展示一大堆弱候选。没有可操作标的时,空仓或只观察也是正常结果。 -
-
@@ -250,9 +240,6 @@ export default function RecommendationsPage() {

{focusTabs.find((tab) => tab.key === focusTab)?.label ?? "焦点标的"}

-

- 只给今天真正要处理的少量标的,剩余候选不占主视图。 -

@@ -274,7 +261,6 @@ export default function RecommendationsPage() {

后台观察

-

只保留少量名字方便回看,不参与今天的主决策。

{observe.length} 只
@@ -302,7 +288,6 @@ export default function RecommendationsPage() {

历史记录

-

历史默认折叠,只在需要复盘某一天时展开。

{SIGNAL_FILTERS.map((item) => ( @@ -389,45 +374,45 @@ function buildFocusSummary({ const allowTrading = strategyProfile?.allow_trading ?? actionable.length > 0; const headline = !allowTrading - ? "今天不主动出手,只保留观察名单" + ? "防守观察" : actionable.length > 0 - ? `今天只处理 ${actionable.length} 只可操作标的` + ? `处理 ${actionable.length} 只可操作标的` : watch.length > 0 - ? `今天没有直接执行标的,重点看 ${watch.length} 只等待确认` - : "今天没有明确优势机会,先观察"; + ? `关注 ${watch.length} 只确认信号` + : "暂无优势机会"; const detail = strategyProfile?.decision_note ?? (!allowTrading - ? "系统判断今天更适合防守观察,不需要为了参与而强行找票。" + ? "防守观察,等待确认。" : actionable.length > 0 - ? "首页只保留最接近执行的标的,真正长分析进入个股详情。" + ? "执行名单已收敛。" : watch.length > 0 - ? "今天偏等待确认,不适合在大量候选里反复横跳。" - : "当前没有明确优势机会,先观察,不主动扩池。"); + ? "等待确认,不扩池。" + : "观察为主。"); const now = [ !allowTrading - ? "先看最强主线是否重新形成扩散和回流,再决定是否恢复进攻。" + ? "等待主线扩散和回流。" : actionable[0] - ? `先看 ${actionable[0].name}${actionable[0].trigger_condition ? ` 的触发条件是否成立` : " 是否进一步确认"}。` + ? `看 ${actionable[0].name}${actionable[0].trigger_condition ? `:${actionable[0].trigger_condition}` : " 的确认信号"}。` : watch[0] ? `盯住 ${watch[0].name} 是否从观察转成可操作。` - : "只保留最强主线的少量候选,不主动扩池。", + : "只留主线候选。", watch.length > 0 - ? `${watch.length} 只重点关注标的只做跟踪,不提前下结论。` + ? `${watch.length} 只重点关注,等待确认。` : allowTrading - ? "没有重点关注时,不要强行从观察池里挑票。" - : "没有确认信号前,不把观察股抬升为执行名单。", + ? "不从观察池强挑。" + : "确认前不提级。", tracking.length > 0 - ? `${tracking.length} 只跟踪中标的继续看兑现情况,避免只看新增不看结果。` - : "没有跟踪中的标的时,就把注意力集中在今天的新结论上。", + ? `${tracking.length} 只跟踪兑现。` + : "关注今日新结论。", ]; const later = [ - observe.length > 0 ? `${observe.length} 只后台观察标的不应占据首页主注意力。` : "没有必要把弱标的堆在默认视图。", - closed.length > 0 ? `${closed.length} 只已结束样本只在需要回看时再展开,不参与今日执行决策。` : "没有结束样本时,也不需要额外制造解释性信息。", - "方法说明只作为辅助,不应该压过今天的执行结论。", + observe.length > 0 ? `${observe.length} 只后台观察。` : "不堆弱标的。", + closed.length > 0 ? `${closed.length} 只已结束样本。` : "暂无结束样本。", + "不追无触发标的。", ]; return { headline, detail, now, later }; diff --git a/frontend/src/app/(auth)/sectors/page.tsx b/frontend/src/app/(auth)/sectors/page.tsx index af6c79a3..8c8239c6 100644 --- a/frontend/src/app/(auth)/sectors/page.tsx +++ b/frontend/src/app/(auth)/sectors/page.tsx @@ -9,7 +9,7 @@ import { useWebSocket } from "@/hooks/use-websocket"; function getThemeAliasLine(sector: SectorData) { const aliases = (sector.theme_aliases ?? []).filter((alias) => alias && alias !== sector.sector_name).slice(0, 4); - if (!aliases.length) return "系统主题已归一,无需拆分原始板块口径。"; + if (!aliases.length) return "系统主题"; return `包含:${aliases.join(" / ")}`; } @@ -36,31 +36,31 @@ function getActionPlan(sector: SectorData) { if (pct <= 0) { return { label: "抗跌观察", - description: "当前只看谁先止跌转强,不把仍为负的方向当进攻主线。", - risk: "如果板块继续走弱或前排补跌,直接降级处理,不主动追击。", + description: "等待止跌转强。", + risk: "继续走弱或前排补跌。", }; } if (stage === "early") { return { label: "优先盯", - description: "优先看龙头和首次分歧后的回流。", - risk: "如果没有扩散、没有回流、没有承接,就不能当主线。", + description: "龙头和分歧回流。", + risk: "无扩散、无回流、无承接。", }; } if (stage === "mid" && pct > 0 && mainForce > 20) { return { label: "跟回流", - description: "更适合等确认,不适合无脑追高。", - risk: "如果板块内部开始掉队,要立刻降级成观察。", + description: "等待确认。", + risk: "内部掉队。", }; } return { label: "只观察", - description: "保留跟踪,不作为今天的主仓位方向。", - risk: "一旦退潮加速,直接移出主视野。", + description: "保留跟踪。", + risk: "退潮加速。", }; } @@ -79,8 +79,8 @@ function getHeadline(sectors: SectorData[]) { return { title: "暂无主线数据", detail: "等待实时主题榜或扫描结果更新后再判断。", - canDo: ["当前不适合强行定义主线。"], - avoid: ["不要在没有主线主题支撑时做情绪化追涨。"], + canDo: ["等待主题榜更新。"], + avoid: ["不做情绪追涨。"], }; } @@ -91,51 +91,51 @@ function getHeadline(sectors: SectorData[]) { const hasPositiveLeader = primaryPct > 0; return { - title: hasPositiveLeader ? `当前优先盯 ${primary.sector_name}` : `当前没有明确进攻主线,${primary.sector_name} 只是相对抗跌`, + title: hasPositiveLeader ? `优先盯 ${primary.sector_name}` : `${primary.sector_name} 相对抗跌`, detail: hasPositiveLeader - ? `这里展示的不是外部行业榜,而是系统归一后的主线主题。当前次主线是 ${secondaryName},观察线优先看 ${watchName}。` - : `当前排在前面的主题也仍然下跌,说明系统拿到的是“相对最强”而不是“真正走强”的方向。此时更适合把 ${primary.sector_name}、${secondaryName} 当成抗跌观察线,而不是进攻主线。`, + ? `次主线 ${secondaryName},观察线 ${watchName}。` + : `${primary.sector_name}、${secondaryName} 暂按抗跌观察。`, canDo: hasPositiveLeader ? [ - `${primary.sector_name} 是当前最值得盯的方向,${primaryPlan.description}`, - secondary ? `${secondary.sector_name} 适合放在次主线观察,等是否转强。` : "如果没有次主线,就不要硬做轮动。", - "盯主题时优先看前排代表股、内部涨跌广度和是否出现回流。", + `${primary.sector_name}:${primaryPlan.description}`, + secondary ? `${secondary.sector_name}:次主线观察。` : "暂无次主线。", + "看前排、广度、回流。", ] : [ - `优先看 ${primary.sector_name} 是否最先止跌转强,而不是因为它排第一就直接当主线做。`, - secondary ? `${secondary.sector_name} 只适合作为备选抗跌方向观察。` : "没有明显次主线时,不要强行找轮动方向。", - "当前更重要的是确认谁先翻红、谁先扩散、谁有前排承接。", + `看 ${primary.sector_name} 是否止跌转强。`, + secondary ? `${secondary.sector_name}:备选抗跌。` : "暂无次主线。", + "确认翻红、扩散、承接。", ], avoid: hasPositiveLeader ? [ - "不要把后排补涨方向当主线来做。", - "不要只看主题涨幅,不看阶段、扩散和前排强弱。", - watch ? `${watch.sector_name} 更偏观察,不适合当今天的主攻方向。` : "阶段偏后的板块只保留观察。", + "不把后排补涨当主线。", + "不只看涨幅。", + watch ? `${watch.sector_name}:观察线。` : "后期板块只观察。", ] : [ - "不要把仍然为负的主题写成“今日主线”来理解。", - "不要在全市场偏弱时,因为相对抗跌就重仓进攻。", - "不要忽略整体环境,只盯着排行榜第一名。", + "不把负涨幅当主线。", + "不因抗跌重仓进攻。", + "不只盯排名第一。", ], }; } function getSourceLabel(source?: string) { - if (source === "eastmoney") return "东方财富实时板块榜归一"; - if (source === "sina") return "新浪实时行业聚合归一"; - if (source === "snapshot") return "本地主题快照"; - if (source === "mixed") return "多源归一主题"; + if (source === "eastmoney") return "东方财富"; + if (source === "sina") return "新浪"; + if (source === "snapshot") return "本地快照"; + if (source === "mixed") return "多源"; return "未知来源"; } function getSourceRiskHint(source?: string, dataMode?: string) { if (source === "snapshot" || dataMode === "daily_snapshot") { - return "当前展示的是系统主题快照,不是实时外部行业榜;如果你拿它逐项对比东方财富原始板块名,会存在口径差异。"; + return "快照口径"; } if (source === "sina") { - return "当前主题由新浪行业聚合后再归一,和东方财富原始板块分类不完全一致。"; + return "新浪口径"; } - return "当前优先使用实时板块数据,并统一归一成系统主题。"; + return "实时口径"; } function LeadingStockPill({ stock }: { stock: LeadingStock }) { @@ -530,27 +530,18 @@ export default function SectorsPage() {

主线主题

-

- 先看今天主线主题是谁,再看怎么跟,最后才看完整方向列表。 - {hasRealtime ? · 今日实时优先 : null} -

- 当前来源 + 来源 {getSourceLabel(source)} · {dataMode} + {hasRealtime ? 实时 : null} + · + {sourceRiskHint}
-

- {sourceRiskHint} -

- {hasRealtime && dataMode === "realtime_today" ? ( -

- 当前使用今日实时数据归一后的主题榜,涨幅、成交额、涨跌广度和领涨股均优先使用当日数据。 -

- ) : null} {hasRealtime && dataMode === "realtime_overlay" ? (

- 当前是实时覆盖模式,结构字段仍参考 {structureTradeDate || "最近交易日"} 的主题快照。 + 结构日 {structureTradeDate || "最近交易日"}

) : null}
@@ -569,8 +560,8 @@ export default function SectorsPage() {

{summary.title}

{summary.detail}

- - + +
@@ -586,19 +577,19 @@ export default function SectorsPage() {
@@ -609,9 +600,6 @@ export default function SectorsPage() {

完整方向列表

-

- 这里只做完整查询和比对,不承担主结论。 -

{[ @@ -654,9 +642,6 @@ export default function SectorsPage() {

方向轮动

-

- 用来确认最近几天资金是否在不同方向之间切换,不是首屏主信息。 -

) : null}
- -
- -
- - - -
-
+
- -
- 这些结论应该影响下一轮推荐方法,而不是只停留在页面上。
{(iteration.adjustment_suggestions.length @@ -216,12 +192,12 @@ export default function StrategyPage() {
@@ -234,9 +210,6 @@ export default function StrategyPage() {
-
- 这些不是给你盘中参考的,而是告诉系统哪些错误不该继续重复。 -
{iteration.failure_patterns.length ? ( iteration.failure_patterns.map((pattern, index) => ( @@ -255,7 +228,6 @@ export default function StrategyPage() { ) : (
暂无系统校准数据
-
等待推荐进入跟踪和闭环后,再生成方法迭代结论
)}
@@ -271,27 +243,27 @@ function buildCalibrationDiagnosis( const tracked = performance?.tracked ?? 0; const headline = tracked < 10 - ? "当前更像早期样本积累阶段" + ? "样本积累中" : winRate >= 55 && avgReturn >= 0 - ? "当前方法仍然有效,但需要持续校准" - : "当前方法出现退化,需要收紧与调整"; + ? "方法有效" + : "方法退化"; const detail = iteration?.summary ?? (tracked < 10 - ? "闭环样本还不够多,这一页更适合看方向性的偏差,而不是做强结论。" - : "这个页面的目标是判断推荐方法最近有没有偏掉,以及下一轮应该如何调整。"); + ? "闭环样本不足,只看方向偏差。" + : "检查推荐方法偏差和下一轮调整。"); const useFor = [ - "验证系统最近推荐出来的东西,长期看是否真的有效。", - "识别哪类策略、哪类信号最近更有效或更容易失效。", - "把复盘结论转成下一轮推荐系统的收紧、加强或降权指令。", + "验证推荐兑现率。", + "识别有效策略和信号。", + "生成下一轮配置调整。", ]; const notFor = [ - "不是盘中决策页,不负责告诉你现在立刻买哪只股票。", - "不是板块行情页,不负责追踪今天最热方向。", - "不是个股详情页,不负责展开单只股票的全部逻辑。", + "不做盘中买卖决策。", + "不替代板块行情。", + "不展开单股长逻辑。", ]; return { headline, detail, useFor, notFor }; @@ -527,15 +499,6 @@ function formatUnknown(value: unknown): string { } } -function UsageCard({ title, description }: { title: string; description: string }) { - return ( -
-
{title}
-
{description}
-
- ); -} - function NextInstruction({ item, index }: { item: StrategyAdjustment; index: number }) { const verb = ACTION_LABELS[item.action] ?? item.action; const color = diff --git a/frontend/src/app/(auth)/watchlists/page.tsx b/frontend/src/app/(auth)/watchlists/page.tsx index b763aec0..383526cf 100644 --- a/frontend/src/app/(auth)/watchlists/page.tsx +++ b/frontend/src/app/(auth)/watchlists/page.tsx @@ -369,9 +369,6 @@ function WatchlistOverview({
Personal Mission Control

把自选股变成你的个人执行池

-

- 观察池负责收集线索,重点池负责明日盯盘,候选池负责临门一脚,持仓池负责兑现和风控。 -

@@ -384,7 +381,6 @@ function WatchlistOverview({
统一动作
-
你可以手动刷新整池分析,也可以等系统收盘后自动跑。
diff --git a/frontend/src/components/sector-heatmap.tsx b/frontend/src/components/sector-heatmap.tsx index da69af18..4a3cc27c 100644 --- a/frontend/src/components/sector-heatmap.tsx +++ b/frontend/src/components/sector-heatmap.tsx @@ -20,9 +20,9 @@ function getSectorFocus(sector: SectorData): string { return `盯住 ${leaders.slice(0, 2).map((item) => item.name).join(" / ")} 的承接和回流。`; } if ((sector.realtime_up_count ?? 0) > (sector.realtime_down_count ?? 0)) { - return "板块内上涨家数占优,优先看前排继续强化。"; + return "上涨占优,看前排强化。"; } - return "板块内分化较重,只保留观察,不追后排。"; + return "分化较重,观察不追。"; } export default function SectorHeatmap({ sectors }: { sectors: SectorData[] }) { @@ -43,9 +43,6 @@ export default function SectorHeatmap({ sectors }: { sectors: SectorData[] }) {

今日主线

-

- 不是展示板块分数,而是告诉你今天该盯什么方向、看什么前排。 -

{hasRealtime && ( diff --git a/frontend/src/components/stock-card.tsx b/frontend/src/components/stock-card.tsx index 36b6a4bc..7bca5d33 100644 --- a/frontend/src/components/stock-card.tsx +++ b/frontend/src/components/stock-card.tsx @@ -52,9 +52,9 @@ export default function StockCard({ rec, compact = false }: { rec: Recommendatio invalidated: "已失效", }; const actionPlanCopy: Record = { - "可操作": "触发条件成立时才执行", - "重点关注": "等待确认,不提前交易", - "观察": "只记录,不主动出手", + "可操作": "触发后执行", + "重点关注": "等待确认", + "观察": "仅观察", }; const evidence = [ rec.prefilter_reason,