diff --git a/DEVLOG.md b/DEVLOG.md index 8c5a94c..920f4b3 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -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 · 清仓择时改造:紧急直通 + 卖出分桶收口 + 自主卖出窗口不作废 diff --git a/app/services/upstream_signals.py b/app/services/upstream_signals.py index 4a68b81..39a70c4 100644 --- a/app/services/upstream_signals.py +++ b/app/services/upstream_signals.py @@ -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} diff --git a/app/web/static/index.html b/app/web/static/index.html index 1e846a0..7ef789a 100644 --- a/app/web/static/index.html +++ b/app/web/static/index.html @@ -361,9 +361,10 @@ pre.json{background:var(--surface-2);border:1px solid var(--hair);border-radius: