开始处理系统整体细节

This commit is contained in:
zlt 2026-08-18 13:34:20 +08:00
parent 82ab9ed5c1
commit 48a3267299
3 changed files with 34 additions and 6 deletions

View File

@ -76,6 +76,18 @@ mtf 实况分榜(这对通常列表长,单独拉高到 min-height 340
删掉不再用的 tierHasA/B/C、CARDS_B、armed 计算属性。判收:无头渲染六框全在、事件卡与待触发条
各自正确、零 Vue 告警。旧的"分档版"未曾部署,改版二是最终形态。
**同日再修(风控卖出显示为空,真机暴露)**
部署后风控卖出卡出现 40 行、每行只有一个"SELL"、无股票无理由无时间。根因是后端
`upstream_signals._read_sell_actions` 直读流的顶层字段,而 `bionic:signals:llm_sell_actions`
的真实载荷整包在 `data`(JSON 字符串)里、顶层只有 data 一个字段——这正是第一份审查报告
F3 标过的疑点,今天真机确认。修法:`_read_sell_actions` 按 data 解包(与消化端
`signal_rules.parse_risk_sell` 同口径),字段名对齐 bionic 写入端——理由 `llm_reason`
时间 `timestamp`(epoch 毫秒)、`dominant_signal` 区分风控止损与止盈(take_profit);顶层
字段留作兜底兼容未来扁平化。前端卡片相应不再硬写"SELL",改显示 股票名 + 风控卖出/止盈
标签 + 置信 + 时间 + 理由。判收后端纯逻辑单测data 包裹 + 扁平兜底两形态各解出
ts_code/理由/时间/主导信号);前端无头渲染确认卡片显示完整字段、止盈与风控区分正确、零告警。
动了 app/services/upstream_signals.py 与 app/web/static/index.html 两个文件。
---
## 2026-08-17 · 清仓择时改造:紧急直通 + 卖出分桶收口 + 自主卖出窗口不作废

View File

@ -207,12 +207,27 @@ def _read_metrics(c):
def _read_sell_actions(c):
"""风控卖出流: 真实载荷包在 data(JSON 字符串)里, 顶层只有 data 一个字段 ——
之前直接取顶层 ts_code/confidence/reason 全落空, 页面每行只剩硬编码的 SELL(2026-08-18 )
与消化端 signal_rules.parse_risk_sell 同口径拆 data; 字段名对齐 bionic 写入端
(tasks_risk/tasks_intraday): 理由是 llm_reason, 时间是 timestamp(epoch 毫秒),
dominant_signal 区分风控止损与止盈(take_profit)顶层字段留作兜底, 兼容未来可能的扁平化"""
key = "bionic:signals:llm_sell_actions"
out = []
for _id, f in c.xrevrange(key, count=_limit()):
out.append({"ts_code": f.get("ts_code"), "action": f.get("action"),
"confidence": _num(f.get("confidence")), "reason": f.get("reason"),
"time": _hm(f.get("trigger_time") or f.get("ts"))})
raw = f.get("data")
d = f
if raw:
try:
d = json.loads(raw) if isinstance(raw, str) else dict(raw)
except Exception:
d = {}
out.append({"ts_code": d.get("ts_code") or f.get("ts_code"),
"action": d.get("action") or f.get("action"),
"confidence": _num(d.get("confidence")),
"dominant_signal": d.get("dominant_signal"),
"reason": d.get("llm_reason") or d.get("reason") or f.get("reason"),
"time": _hm(d.get("timestamp") or d.get("trigger_time") or f.get("ts"))})
return {"key": key, "items": out}

View File

@ -361,9 +361,10 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius:
<div class="up-cell" v-if="SIG.sell.length">
<div class="up-h" style="color:var(--stop)">决策系统 · 风控卖出 <span class="muted" style="font-weight:400">· {{ SIG.sell.length }}</span></div>
<div class="sig-rows">
<div class="sig-row" v-for="(r,i) in SIG.sell.slice(0,10)" :key="i" style="flex-wrap:wrap">
<span class="sig-nm">{{ nm(r.ts_code) }}</span>
<span class="disp deny">SELL {{ r.confidence==null?'':r.confidence }}</span>
<div class="sig-row" v-for="(r,i) in SIG.sell.slice(0,12)" :key="i" style="flex-wrap:wrap">
<span class="sig-nm">{{ nm(r.ts_code) }}</span><span class="muted mono" style="font-size:11px">{{ r.ts_code }}</span>
<span class="disp deny">{{ r.dominant_signal==='take_profit'?'止盈':'风控卖出' }}</span>
<span class="muted" style="font-size:12px" v-if="r.confidence!=null">置信 <span class="mono" style="color:var(--ink)">{{ r.confidence }}</span></span>
<span class="sig-sp"></span>
<span class="mono muted" style="font-size:11px">{{ r.time }}</span>
<div style="flex-basis:100%;font-size:12px;line-height:1.4" class="muted" v-if="r.reason">{{ r.reason }}</div>