第四件 PMS 侧:安全边际整句随候选透传到硬数字与提议卡,不送研判(第二十二批加一例,全套 677)

This commit is contained in:
zlt 2026-09-07 15:47:27 +08:00
parent 417d135cb7
commit fbad890b7d
4 changed files with 30 additions and 4 deletions

View File

@ -687,6 +687,8 @@ def eval_open(c: dict, params: dict, caps: dict, room_amt: float):
# 逻辑状态四态 (2026-09-07 第三件): 入场那一刻「研究证据还在不在」的读数, 进账本与提议卡, # 逻辑状态四态 (2026-09-07 第三件): 入场那一刻「研究证据还在不在」的读数, 进账本与提议卡,
# 持仓视图的「当初为什么买」从这里回溯; 不送研判 (judge.OPEN_JUDGE_KEYS 不收它)。 # 持仓视图的「当初为什么买」从这里回溯; 不送研判 (judge.OPEN_JUDGE_KEYS 不收它)。
"logic_state": c.get("logic_state"), "logic_state": c.get("logic_state"),
# 安全边际三情景的整句 (2026-09-07 第四件): 只给人看, 不送研判。
"valuation_text": c.get("valuation_text"),
# ---- 仓位口径: 只进评审账本做判分锚。judge.py 送研判时会把这几项过滤掉, # ---- 仓位口径: 只进评审账本做判分锚。judge.py 送研判时会把这几项过滤掉,
# 理由见那边的 OPEN_JUDGE_KEYS —— 决策系统本来就不管仓位, 别送过去带偏它。 # 理由见那边的 OPEN_JUDGE_KEYS —— 决策系统本来就不管仓位, 别送过去带偏它。
"target_pct": target_pct, "target_amount": round(full_amt, 2), "target_pct": target_pct, "target_amount": round(full_amt, 2),

View File

@ -222,6 +222,9 @@ def _rows(raw, bucket: str) -> list:
"logic": _list_or_none(it.get("logic"), limit=LOGIC_KEEP), "logic": _list_or_none(it.get("logic"), limit=LOGIC_KEEP),
# 逻辑状态四态 (2026-09-07 第三件): 跟着候选进硬数字, 不送研判 (judge.OPEN_JUDGE_KEYS 不收)。 # 逻辑状态四态 (2026-09-07 第三件): 跟着候选进硬数字, 不送研判 (judge.OPEN_JUDGE_KEYS 不收)。
"logic_state": _logic_state_or_none(it.get("logic_state")), "logic_state": _logic_state_or_none(it.get("logic_state")),
# 安全边际三情景的整句 (2026-09-07 第四件): 上游按盈利预测算的悲观/中性/乐观估值与赔率,
# 只给人看 (提议卡与账本), 不参与任何判定, 也不送研判。
"valuation_text": _text_or_none(it.get("valuation_text")),
}) })
return out return out
@ -413,7 +416,8 @@ def select_candidates(plan: dict, *, held=(), black=(), top_n: int = 30, tiers=N
"basis": r.get("basis"), "logic": r.get("logic"), "basis": r.get("basis"), "logic": r.get("logic"),
# 逻辑状态 (2026-09-07 第三件): 动作引擎放进硬数字; 判决候选而逻辑存疑的在 scan_open # 逻辑状态 (2026-09-07 第三件): 动作引擎放进硬数字; 判决候选而逻辑存疑的在 scan_open
# 里强制交人。它不改判决、不改排序 —— 收敛规则是单调的 (选股系统 logic_state.apply_to_card)。 # 里强制交人。它不改判决、不改排序 —— 收敛规则是单调的 (选股系统 logic_state.apply_to_card)。
"logic_state": r.get("logic_state")} "logic_state": r.get("logic_state"),
"valuation_text": r.get("valuation_text")}
for r in passed[:n]] for r in passed[:n]]
return {"date": plan.get("date"), "considered": len(pool), "eligible": len(passed), return {"date": plan.get("date"), "considered": len(pool), "eligible": len(passed),
"items": items, "dropped": dropped, "st_unknown": st_unknown, "items": items, "dropped": dropped, "st_unknown": st_unknown,

View File

@ -59,16 +59,16 @@
test_batch22_units.py 逻辑状态四态接入 (2026-09-07 第三件): 解析层收逻辑状态/硬数字带它而研判 test_batch22_units.py 逻辑状态四态接入 (2026-09-07 第三件): 解析层收逻辑状态/硬数字带它而研判
白名单不收/判决候选而逻辑存疑强制交人/持仓存疑停增持侧/研究走弱 白名单不收/判决候选而逻辑存疑强制交人/持仓存疑停增持侧/研究走弱
减持默认关且开了必交人/同轮减持优先级/早上取回与映射新鲜度/策略 减持默认关且开了必交人/同轮减持优先级/早上取回与映射新鲜度/策略
买入腿按来源暂停恢复/持仓视图两栏三情形/假仓库签名 (15 ) 买入腿按来源暂停恢复/持仓视图两栏三情形/假仓库签名/安全边际整句透传 (16 )
test_page_enum_guard.py 页面文案守卫 (静态扫描, 不连库不起浏览器): 枚举字段不许 test_page_enum_guard.py 页面文案守卫 (静态扫描, 不连库不起浏览器): 枚举字段不许
直接印到页面上 / 判据码显示前必须剥前缀 / 不许把整个对象 直接印到页面上 / 判据码显示前必须剥前缀 / 不许把整个对象
打给交易员看 / 翻译兜底不许让英文码单独当句子 (1 ) 打给交易员看 / 翻译兜底不许让英文码单独当句子 (1 )
test_wiring.py 装配自检: 服务层核心落表 全链路 (内存桩) + test_wiring.py 装配自检: 服务层核心落表 全链路 (内存桩) +
目标价到价必定入队 (档位 full 也不自动卖) + 目标价到价必定入队 (档位 full 也不自动卖) +
用户设的止损价与目标价单独成列显示 (70 ) 用户设的止损价与目标价单独成列显示 (70 )
676 677
(总数按实跑逐批相加校正过两次: 曾写 649 是笔误, 实为 650; 09-03 先后加了同轮只发一条 (总数按实跑逐批相加校正过两次: 曾写 649 是笔误, 实为 650; 09-03 先后加了同轮只发一条
减持与研究理由两键各一例, 652; 09-04 加了仅展示跳过原因与空候选说明各一例, 654; 又加了页面文案守卫一例, 655; 09-07 审查修复加了跨轮减持等五例, 660; 第二件低把握驳回交人一例, 661; 第三件逻辑状态接入第二十二批十五例, 现为 676) 减持与研究理由两键各一例, 652; 09-04 加了仅展示跳过原因与空候选说明各一例, 654; 又加了页面文案守卫一例, 655; 09-07 审查修复加了跨轮减持等五例, 660; 第二件低把握驳回交人一例, 661; 第三件逻辑状态接入第二十二批十五例, 676; 第四件安全边际整句透传一例, 现为 677)
任一子集失败即整体失败 (退出码 1) 任一子集失败即整体失败 (退出码 1)
哨兵位置清单 (2026-09-03 抄录; 改了对应的东西就得来这些地方改断言, 断言不动就是漏了): 哨兵位置清单 (2026-09-03 抄录; 改了对应的东西就得来这些地方改断言, 断言不动就是漏了):

View File

@ -201,6 +201,26 @@ def _():
assert "logic_state" not in jd.OPEN_JUDGE_KEYS assert "logic_state" not in jd.OPEN_JUDGE_KEYS
@case("安全边际整句·解析层收 valuation_text, 候选与硬数字带它, 研判白名单不收 (第四件, 只给人看)")
def _():
txt = "安全边际2026 年度预测9 家):悲观 42.64 元(-15.0%)、中性 56.75 元(+13.1%);赔率 0.87 比 1"
row = pf._rows([{"code": "600000.SH", "rank": 1, "score": 210, "valuation_text": txt}], "main")[0]
assert row["valuation_text"] == txt, row
assert pf._rows([{"code": "600000.SH", "rank": 1, "score": 210, "valuation_text": ""}], "main")[0]["valuation_text"] is None
plan = {"date": "2026-09-04", "main": [row], "observe": []}
item = pf.select_candidates(plan, top_n=10)["items"][0]
assert item["valuation_text"] == txt, item
c = {**item, "price": 10.0}
params = {"scale": 1_000_000, "stock_target_default": 0.06, "batch_split": (0.5, 0.25, 0.25)}
with _Patch() as p:
p(ae, "check_all_caps", lambda **kw: [])
p(ae, "_new_name_ctx", lambda caps, c: caps)
cand, why = ae.eval_open(c, params, {"names_count": 0, "max_names": 10}, 500_000)
assert cand and cand["hard_numbers"]["valuation_text"] == txt, why
assert "valuation_text" not in jd._judge_hard_numbers("OPEN", cand["hard_numbers"])
assert "valuation_text" not in jd.OPEN_JUDGE_KEYS
# ================================================================ 二, 新建仓与持仓的分流 # ================================================================ 二, 新建仓与持仓的分流
def _scan_open(cands, *, route_logic=True): def _scan_open(cands, *, route_logic=True):
params = {"scale": 1_000_000, "stock_target_default": 0.06, "batch_split": (0.5, 0.25, 0.25), params = {"scale": 1_000_000, "stock_target_default": 0.06, "batch_split": (0.5, 0.25, 0.25),