修改前端页面
This commit is contained in:
parent
8372c388a3
commit
a941032c24
|
|
@ -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 例通过。
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
|||
<span class="muted" v-else-if="usrc('alerts') && usrc('alerts').ok===false">· 读取失败:{{ usrc('alerts').error }}</span>
|
||||
<span class="muted" v-else>· 暂无告警</span>
|
||||
<div class="spacer"></div>
|
||||
<span class="muted" style="font-size:11.5px;cursor:pointer" @click="showUpstream=true">下方查看全部 ▾</span>
|
||||
<span class="muted" style="font-size:11.5px;cursor:pointer" @click="openSigCenter">完整信号中心 ▾</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
@ -348,8 +349,6 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:
|
|||
</div>
|
||||
|
||||
<!-- 3) 我的持仓 -->
|
||||
<!-- 双栏 (2026-08-26 用户定): 左=持仓+策略, 右=上游信号, 两边都要实时盯; 窄屏自动叠回单栏 -->
|
||||
<div class="tcols"><div class="tcol">
|
||||
<div class="panel tblk" id="t-pos">
|
||||
<h3>我的持仓 · {{ heldPositions.length }} 只</h3>
|
||||
<el-table :data="heldPositions" size="small" border max-height="460" @expand-change="onPosExpand">
|
||||
|
|
@ -398,6 +397,21 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:
|
|||
<template #default="s"><el-tag size="small" effect="dark" :type="cuTag(s.row.cushion_state)">{{ tx('cushion', s.row.cushion_state) }}</el-tag>
|
||||
<div class="muted">{{ pct(s.row.cushion_pct) }}<span v-if="s.row.neg_cushion_days>0"> · 连负{{ s.row.neg_cushion_days }}日</span></div></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="今日信号" width="136">
|
||||
<template #default="s">
|
||||
<template v-if="heldSigOf(s.row.ts_code).length">
|
||||
<span style="cursor:default"
|
||||
:title="heldSigOf(s.row.ts_code).slice(0,3).map(g=>(g.time||'')+' '+g.cat+' '+(g.direction||'')).join('\n')">
|
||||
<span :class="dirUp(heldSigOf(s.row.ts_code)[0].direction)?'clr-up':'clr-down'">
|
||||
{{ heldSigOf(s.row.ts_code)[0].cat }} {{ heldSigOf(s.row.ts_code)[0].direction || '' }}</span>
|
||||
<span class="muted" style="font-size:11px"> {{ heldSigOf(s.row.ts_code)[0].time }}</span>
|
||||
<span v-if="heldSigOf(s.row.ts_code).length>1" class="muted" style="font-size:11px">
|
||||
+{{ heldSigOf(s.row.ts_code).length-1 }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<span v-else class="muted">—</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="120">
|
||||
<template #default="s">{{ tx('posStatus', s.row.status) }}
|
||||
<div v-if="s.row.frozen_reason && s.row.frozen_reason!=='NONE'" style="color:var(--warn)">{{ tx('frozen', s.row.frozen_reason) }}</div></template>
|
||||
|
|
@ -423,6 +437,24 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 信号速览 (2026-08-26 重设计): 全宽一行一条 —— 持仓票的信号置顶标「持仓」,
|
||||
其余只收重要/警告级; 完整信号中心默认收起在下方, 点右上角展开跳转 -->
|
||||
<div class="panel tblk">
|
||||
<h3>信号速览 <span class="muted" style="font-weight:400">· {{ sigBrief.length }} 条,持仓相关 {{ sigBriefHeldCount }} 条</span>
|
||||
<span class="muted" style="font-size:12px;font-weight:normal;cursor:pointer;float:right" @click="openSigCenter">完整信号中心 ▾</span></h3>
|
||||
<div class="muted" v-if="!sigBrief.length">持仓票今日暂无信号,全场暂无重要或警告级信号。</div>
|
||||
<div v-else class="sigbrief">
|
||||
<div v-for="(g,i) in sigBrief.slice(0,80)" :key="i" class="sb-row">
|
||||
<span class="muted mono sb-t">{{ g.time || '—' }}</span>
|
||||
<el-tag v-if="g.held" size="small" type="warning" effect="dark">持仓</el-tag>
|
||||
<b>{{ nm(g.ts_code) }}</b><span class="muted mono" style="font-size:11px">{{ g.ts_code }}</span>
|
||||
<span class="muted">{{ g.cat }}</span>
|
||||
<span :class="dirUp(g.direction)?'clr-up':(g.direction?'clr-down':'muted')">{{ g.direction || '' }}</span>
|
||||
<span class="disp" :class="lvClass(g.level)" style="padding:0 6px">{{ lvLabel(g.level) }}</span>
|
||||
<span v-if="g.stale" class="ab-stale">陈旧</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 4.5) 我的策略 + 操作日志 -->
|
||||
<div class="panel tblk">
|
||||
<h3>我的策略 · {{ strategies.length }} 个
|
||||
|
|
@ -525,9 +557,61 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:
|
|||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div><div class="tcol">
|
||||
<!-- 7) 上游信号 (只读参考) -->
|
||||
|
||||
<!-- 4) 今日在办与动向 -->
|
||||
<div class="panel tblk">
|
||||
<h3>今日在办</h3>
|
||||
<div class="sub2">今天下出去的买卖单,按状态分三档:还在跑的、已成交的、已经结束的。</div>
|
||||
<el-tabs v-model="insTab">
|
||||
<el-tab-pane name="live">
|
||||
<template #label>在办中 <span class="tabn">{{ insLive.length }}</span></template>
|
||||
<el-table :data="insLive" size="small" max-height="260" empty-text="没有在办的买卖">
|
||||
<el-table-column label="股票" min-width="150"><template #default="s"><b>{{ nm(s.row.ts_code) }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="动作" width="150"><template #default="s">{{ tx('action', s.row.action) }} · {{ tx('side', s.row.side) }}</template></el-table-column>
|
||||
<el-table-column label="数量 / 已成" width="120" align="right"><template #default="s"><span class="mono">{{ s.row.qty }} / {{ s.row.exec_qty||0 }}</span></template></el-table-column>
|
||||
<el-table-column label="限价" width="82" align="right"><template #default="s"><span class="mono">{{ s.row.limit_price||'—' }}</span></template></el-table-column>
|
||||
<el-table-column label="状态" width="118"><template #default="s"><span class="chip idle"><span class="dot"></span>{{ tx('insStatus', s.row.status) }}</span></template></el-table-column>
|
||||
<el-table-column label="操作" width="76"><template #default="s"><button class="tbtn sm" @click="cancelIns(s.row.instruction_id)">撤单</button></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="done">
|
||||
<template #label>今日成交 <span class="tabn">{{ insDone.length }}</span></template>
|
||||
<el-table :data="insDone" size="small" max-height="260" empty-text="今天还没有成交">
|
||||
<el-table-column label="股票" min-width="150"><template #default="s"><b>{{ nm(s.row.ts_code) }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="动作" width="150"><template #default="s">{{ tx('action', s.row.action) }} · {{ tx('side', s.row.side) }}</template></el-table-column>
|
||||
<el-table-column label="数量 / 已成" width="120" align="right"><template #default="s"><span class="mono">{{ s.row.qty }} / {{ s.row.exec_qty||0 }}</span></template></el-table-column>
|
||||
<el-table-column label="状态" width="120"><template #default="s"><span class="chip ok"><span class="dot"></span>{{ tx('insStatus', s.row.status) }}</span></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="end">
|
||||
<template #label>已了结 <span class="tabn">{{ insEnd.length }}</span></template>
|
||||
<el-table :data="insEnd" size="small" max-height="260" empty-text="今天没有了结的单">
|
||||
<el-table-column label="股票" min-width="150"><template #default="s"><b>{{ nm(s.row.ts_code) }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="动作" width="150"><template #default="s">{{ tx('action', s.row.action) }} · {{ tx('side', s.row.side) }}</template></el-table-column>
|
||||
<el-table-column label="结束方式" min-width="150"><template #default="s"><span class="chip warn"><span class="dot"></span>{{ tx('insStatus', s.row.status) }}</span></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="deny">
|
||||
<template #label>今日否决 <span class="tabn">{{ denyToday.length }}</span></template>
|
||||
<div class="sub2" style="margin:8px 2px 4px">今天考察过、但没建仓的票,连原因一起摆出来。</div>
|
||||
<el-table :data="denyToday" size="small" max-height="320" empty-text="今天没有被否决的候选">
|
||||
<el-table-column label="股票" width="180"><template #default="s"><b>{{ s.row.name }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="为什么没建仓" min-width="440"><template #default="s"><div class="why" style="margin:0">{{ s.row.why || '—' }}</div></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<h3 style="margin-top:14px;cursor:pointer" @click="showLedger=!showLedger">今天发生了什么 · {{ ledger.length }} 条 <span class="muted" style="font-size:12px;font-weight:normal">{{ showLedger?'▲ 收起':'▼ 展开' }}</span></h3>
|
||||
<template v-if="showLedger">
|
||||
<div class="muted" v-if="!ledger.length">今天还没有记录。</div>
|
||||
<div v-for="(l,i) in ledger" :key="i" class="feed-row">
|
||||
<span class="muted mono">{{ (l.decided_at||'').slice(11,16) }}</span>
|
||||
<b> {{ nm(l.ts_code) }}</b>:{{ tx('arbiter', l.arbiter) }}{{ tx('verdict', l.verdict) }} {{ tx('action', l.action) }}<span v-if="l.reason" class="muted"> —— {{ l.reason }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- 7) 上游信号 (只读参考) -->
|
||||
<div class="panel tblk" id="t-sig">
|
||||
<h3 style="cursor:pointer" @click="showUpstream=!showUpstream">上游信号 <span class="muted" style="font-weight:400">· 只读参考,不进下单逻辑</span> <span class="muted" style="font-size:12px;font-weight:normal">{{ showUpstream?'▲ 收起':'▼ 展开' }}</span></h3>
|
||||
<template v-if="showUpstream">
|
||||
<div class="muted" style="margin:-4px 0 12px" v-if="upstream.at">最近取数 {{ (upstream.at||'').slice(11,19) }} · 来源:决策系统 / 盘中择时</div>
|
||||
|
|
@ -696,59 +780,6 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:
|
|||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
<!-- 4) 今日在办与动向 -->
|
||||
<div class="panel tblk">
|
||||
<h3>今日在办</h3>
|
||||
<div class="sub2">今天下出去的买卖单,按状态分三档:还在跑的、已成交的、已经结束的。</div>
|
||||
<el-tabs v-model="insTab">
|
||||
<el-tab-pane name="live">
|
||||
<template #label>在办中 <span class="tabn">{{ insLive.length }}</span></template>
|
||||
<el-table :data="insLive" size="small" max-height="260" empty-text="没有在办的买卖">
|
||||
<el-table-column label="股票" min-width="150"><template #default="s"><b>{{ nm(s.row.ts_code) }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="动作" width="150"><template #default="s">{{ tx('action', s.row.action) }} · {{ tx('side', s.row.side) }}</template></el-table-column>
|
||||
<el-table-column label="数量 / 已成" width="120" align="right"><template #default="s"><span class="mono">{{ s.row.qty }} / {{ s.row.exec_qty||0 }}</span></template></el-table-column>
|
||||
<el-table-column label="限价" width="82" align="right"><template #default="s"><span class="mono">{{ s.row.limit_price||'—' }}</span></template></el-table-column>
|
||||
<el-table-column label="状态" width="118"><template #default="s"><span class="chip idle"><span class="dot"></span>{{ tx('insStatus', s.row.status) }}</span></template></el-table-column>
|
||||
<el-table-column label="操作" width="76"><template #default="s"><button class="tbtn sm" @click="cancelIns(s.row.instruction_id)">撤单</button></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="done">
|
||||
<template #label>今日成交 <span class="tabn">{{ insDone.length }}</span></template>
|
||||
<el-table :data="insDone" size="small" max-height="260" empty-text="今天还没有成交">
|
||||
<el-table-column label="股票" min-width="150"><template #default="s"><b>{{ nm(s.row.ts_code) }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="动作" width="150"><template #default="s">{{ tx('action', s.row.action) }} · {{ tx('side', s.row.side) }}</template></el-table-column>
|
||||
<el-table-column label="数量 / 已成" width="120" align="right"><template #default="s"><span class="mono">{{ s.row.qty }} / {{ s.row.exec_qty||0 }}</span></template></el-table-column>
|
||||
<el-table-column label="状态" width="120"><template #default="s"><span class="chip ok"><span class="dot"></span>{{ tx('insStatus', s.row.status) }}</span></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="end">
|
||||
<template #label>已了结 <span class="tabn">{{ insEnd.length }}</span></template>
|
||||
<el-table :data="insEnd" size="small" max-height="260" empty-text="今天没有了结的单">
|
||||
<el-table-column label="股票" min-width="150"><template #default="s"><b>{{ nm(s.row.ts_code) }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="动作" width="150"><template #default="s">{{ tx('action', s.row.action) }} · {{ tx('side', s.row.side) }}</template></el-table-column>
|
||||
<el-table-column label="结束方式" min-width="150"><template #default="s"><span class="chip warn"><span class="dot"></span>{{ tx('insStatus', s.row.status) }}</span></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="deny">
|
||||
<template #label>今日否决 <span class="tabn">{{ denyToday.length }}</span></template>
|
||||
<div class="sub2" style="margin:8px 2px 4px">今天考察过、但没建仓的票,连原因一起摆出来。</div>
|
||||
<el-table :data="denyToday" size="small" max-height="320" empty-text="今天没有被否决的候选">
|
||||
<el-table-column label="股票" width="180"><template #default="s"><b>{{ s.row.name }}</b> <span class="muted mono">{{ s.row.ts_code }}</span></template></el-table-column>
|
||||
<el-table-column label="为什么没建仓" min-width="440"><template #default="s"><div class="why" style="margin:0">{{ s.row.why || '—' }}</div></template></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<h3 style="margin-top:14px;cursor:pointer" @click="showLedger=!showLedger">今天发生了什么 · {{ ledger.length }} 条 <span class="muted" style="font-size:12px;font-weight:normal">{{ showLedger?'▲ 收起':'▼ 展开' }}</span></h3>
|
||||
<template v-if="showLedger">
|
||||
<div class="muted" v-if="!ledger.length">今天还没有记录。</div>
|
||||
<div v-for="(l,i) in ledger" :key="i" class="feed-row">
|
||||
<span class="muted mono">{{ (l.decided_at||'').slice(11,16) }}</span>
|
||||
<b> {{ nm(l.ts_code) }}</b>:{{ tx('arbiter', l.arbiter) }}{{ tx('verdict', l.verdict) }} {{ tx('action', l.action) }}<span v-if="l.reason" class="muted"> —— {{ l.reason }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 挂交易方案 对话框 (非盲填: 现价/持仓/可卖/浮盈都摆出来) -->
|
||||
|
|
@ -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');
|
||||
|
|
|
|||
Loading…
Reference in New Issue