From a941032c24d42eefc8a2c0209206046a22dec5d3 Mon Sep 17 00:00:00 2001 From: zlt Date: Wed, 26 Aug 2026 11:50:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=89=8D=E7=AB=AF=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEVLOG.md | 3 + app/web/static/index.html | 198 ++++++++++++++++++++++++++------------ 2 files changed, 138 insertions(+), 63 deletions(-) diff --git a/DEVLOG.md b/DEVLOG.md index 4633f56..ba0e4ce 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -50,6 +50,9 @@ app/services/strategy_advisor.py(新增);app/services/strategy_service.py **真机判收** 部分判收(2026-08-25 盘中)。桥机 make deploy + make test 见 ALL SUITES PASS;dry-run 试算真机四票读数全部合理:688802.SH 想挂网格但「按投入比例折出 47,250 元买不起一手」被挡(科创板高价票,判定正确);002179.SZ 有在途指令主动让路;其余两票无信号静默跳过;unknown_states 为空(子串归类修对了)。**尚未判收的**:真挂一条(等在途清了重扫或次日 09:40)、边三/边四真机走一遍、strategy_runner 对自动网格的逐档发单。 +**次日午间第七批(2026-08-26):布局重设计——撤掉双栏,改「持仓全宽 + 信号速览带 + 信号中心收起」** +第六批的左右双栏上真机即被否:持仓表被压窄到操作列整个被切掉;信号卡片本是全宽设计,塞进右栏后股票名逐字竖排;右栏比左栏长数倍,「同屏盯两块」根本没实现。重新分析:交易员要随时看的不是整个信号中心(几百条,翻查用),而是与决策相关的信号——尤其持仓票的信号。重做为融合式三层:一,持仓表恢复全宽(操作列回来),并新增「今日信号」列——每只持仓票显示今天与它相关的最新信号(类别、方向、时刻,多条显示 +N,悬停看前三条),信号出现在交易员本来就在看的那一行上;二,持仓表下方新增全宽「信号速览」带——持仓票的信号置顶标「持仓」,其余只收重要与警告级,决策系统买卖、风控卖出、择时入场三路独立信号一并汇入,一行一条按时间倒序,高度受控内部滚动,右上角一键展开完整信号中心;三,完整信号中心整块移到「今日在办」之后、默认收起,卡片恢复全宽可读。区块顺序:持仓 → 信号速览 → 策略 → 今日在办 → 信号中心。全量 560 例通过。 + **次日上午第六批(2026-08-26):前端文字整改与双栏布局(用户三条标准)** 用户定下三条标准并全页执行:交易员可读且含义明确;开发人员口吻的文字彻底清除;系统文字最大限度精简,提示能删则删、必须留的进悬浮问号不占版面。整改清单:删掉「随便点」「只是看一眼」这类不严肃表述,预演说明并入按钮旁的悬浮提示;预演结果头行压成「预演结果(未执行)· 查 N 只持仓」;执行状态行改为「今日自动挂载已于 09:41 执行:查 4 · 挂载 0 · 被挡 1 · 跳过 1」句式;颜色约定整条彩字图例压成一个悬浮问号;告警级别筛选的「只前端过滤、不查后端」删除改悬浮;上游信号来源行去掉内部代号(mtf);操作日志说明收紧为一句;空策略引导语改严肃措辞;后端返回里会显示到页面的英文类型码全部换成中文名(网格、跟踪止盈、做T)。布局:交易员视图改双栏栅格(左七右五)——左栏持仓加策略,右栏上游信号常驻展开,两边可同屏实时盯;窗口窄于 1500 像素自动叠回单栏,其余区块次序不变。全量 560 例通过。 diff --git a/app/web/static/index.html b/app/web/static/index.html index 445431b..dcc6f5f 100644 --- a/app/web/static/index.html +++ b/app/web/static/index.html @@ -57,10 +57,11 @@ body{margin:0;background:var(--plane);color:var(--ink); .m .v{color:var(--ink);font-size:21px;font-weight:680;margin-top:5px;letter-spacing:-.2px;font-variant-numeric:tabular-nums;} .m .v .muted,.m .v span{font-weight:500;} .m .v.up{color:var(--up);} .m .v.down{color:var(--down);} -/* 双栏布局: 持仓与策略在左、上游信号在右 (2026-08-26) */ -.tcols{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:12px;align-items:start} -@media (max-width:1500px){.tcols{grid-template-columns:minmax(0,1fr)}} -.tcol{min-width:0} +/* 信号速览带 (2026-08-26): 全宽紧凑行, 高度受控内部滚动 */ +.sigbrief{max-height:216px;overflow:auto} +.sb-row{display:flex;gap:8px;align-items:center;padding:2px 0;border-bottom:1px dashed rgba(128,128,128,.18)} +.sb-row:last-child{border-bottom:none} +.sb-t{width:46px;flex:none;font-size:11.5px} /* 颜色约定图例 */ .legend{display:flex;gap:15px;flex-wrap:wrap;align-items:center;color:var(--muted);font-size:12px;margin:0 2px 16px;} .legend .sw{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:4px;vertical-align:middle;} @@ -298,7 +299,7 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius: · 读取失败:{{ usrc('alerts').error }} · 暂无告警
- 下方查看全部 ▾ + 完整信号中心 ▾ @@ -348,8 +349,6 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius: - -

我的持仓 · {{ heldPositions.length }} 只

@@ -398,6 +397,21 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius: + + + @@ -423,6 +437,24 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:
+ +
+

信号速览 · {{ sigBrief.length }} 条,持仓相关 {{ sigBriefHeldCount }} 条 + 完整信号中心 ▾

+
持仓票今日暂无信号,全场暂无重要或警告级信号。
+
+
+ {{ g.time || '—' }} + 持仓 + {{ nm(g.ts_code) }}{{ g.ts_code }} + {{ g.cat }} + {{ g.direction || '' }} + {{ lvLabel(g.level) }} + 陈旧 +
+
+

我的策略 · {{ strategies.length }} 个 @@ -525,9 +557,61 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:

-
- + +
+

今日在办

+
今天下出去的买卖单,按状态分三档:还在跑的、已成交的、已经结束的。
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
今天考察过、但没建仓的票,连原因一起摆出来。
+ + + + +
+
+

今天发生了什么 · {{ ledger.length }} 条 {{ showLedger?'▲ 收起':'▼ 展开' }}

+ +
+ + +

上游信号 · 只读参考,不进下单逻辑 {{ showUpstream?'▲ 收起':'▼ 展开' }}

-
- - -
-

今日在办

-
今天下出去的买卖单,按状态分三档:还在跑的、已成交的、已经结束的。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
今天考察过、但没建仓的票,连原因一起摆出来。
- - - - -
-
-

今天发生了什么 · {{ ledger.length }} 条 {{ showLedger?'▲ 收起':'▼ 展开' }}

- -
@@ -1648,7 +1679,7 @@ createApp({ const lastRefresh = ref(''); const autoRefresh = ref(true); const upstream = ref({ sources: {} }); - const showUpstream = ref(true); // 双栏后信号在右栏常驻显示, 点标题可折叠 (2026-08-26) + const showUpstream = ref(false); // 信号中心默认收起; 常驻速览带在持仓下方 (2026-08-26) const showAlerts = ref(false); const alertShowMap = reactive({ money_flow:true, capital:true, qrs:true, volume:true, multi:true, price_notice:false, buy_emitted:false, other:true }); // 级别筛选记忆: 存 sessionStorage —— 普通刷新保留, 关标签页/新开标签=回默认。默认关 普通/提示。 @@ -2207,6 +2238,46 @@ createApp({ const alertLatest = computed(() => alertStripItems.value[0] || {}); const alertStripCount = computed(() => alertStripItems.value.length); const alertTotalCount = computed(() => alertItems.value.length); + // ── 信号速览 (2026-08-26 重设计): 交易员要随时看到的不是整个信号中心, 而是 + // 「持仓票的信号 + 全场重要/警告级」。持仓票置顶; 决策系统买卖/风控卖出/择时 + // 入场三路独立信号也并进来, 免得只看告警漏了真正会动手的那几条。 ── + const code6 = s => (String(s || '').match(/\d{6}/) || [''])[0]; + const heldCodeSet = computed(() => new Set(heldPositions.value.map(p => code6(p.ts_code)))); + const sigBrief = computed(() => { + const held = heldCodeSet.value; + const out = []; + for (const a of alertItems.value) { + const isHeld = held.has(code6(a.ts_code)); + if (!isHeld && !['DANGER', 'WARNING'].includes(normLv(a.level))) continue; + out.push({ ts_code: a.ts_code, time: a.time || '', cat: a.cat_label || a.cat, + direction: a.direction, level: a.level, held: isHeld, stale: a.stale }); + } + const s = SIG.value; + for (const r of (s.sell || [])) out.push({ + ts_code: r.ts_code, time: r.time || '', cat: '风控卖出', + direction: '卖出', level: 'DANGER', held: held.has(code6(r.ts_code)) }); + for (const r of (s.decision || [])) out.push({ + ts_code: r.ts_code, time: r.time || '', cat: '决策系统', + direction: r.action === 'SELL' ? '卖出' : '买入', level: 'WARNING', + held: held.has(code6(r.ts_code)) }); + for (const r of (s.timing || [])) out.push({ + ts_code: r.ts_code, time: r.time || '', cat: '择时入场', + direction: '买入', level: 'INFO', held: held.has(code6(r.ts_code)) }); + out.sort((a, b) => (b.held - a.held) || String(b.time).localeCompare(String(a.time))); + return out; + }); + const sigBriefHeldCount = computed(() => sigBrief.value.filter(x => x.held).length); + const heldSigMap = computed(() => { + const m = {}; + for (const x of sigBrief.value) { + if (!x.held) continue; + const k = code6(x.ts_code); + (m[k] || (m[k] = [])).push(x); + } + return m; + }); + function heldSigOf(code) { return heldSigMap.value[code6(code)] || []; } + function openSigCenter() { showUpstream.value = true; scrollTo('t-sig'); } const alertLevelClass = computed(() => { const it = alertStripItems.value; if (it.some(x => normLv(x.level) === 'DANGER')) return 'strong'; @@ -2590,6 +2661,7 @@ createApp({ showAlerts, alertItems, alertLatest, alertLevelClass, alertGroups, alertStripItems, alertStripCount, alertTotalCount, catShown, toggleCat, ageText, alertRowClass, alertItemsF, levelShown, toggleLevel, sellOpen, toggleSell, levelCount, ALERT_LEVELS, lvLabel, lvClass, alertGridFixed, passLevel, flowText, flowClass, + sigBrief, sigBriefHeldCount, heldSigOf, openSigCenter, SIG, moneyCn, zBand, zBars, dirUp, eventsQuiet }; } }).use(ElementPlus).mount('#app');