按评审修订观察读数包:增持门口径改只数、清早重复无读数行、复核脚本与台账口径一致
按 docs/观察读数包与加固包评审_2026-09-14.md 第五节,改读数口径与文档一致性(非代码缺陷): - 增持门拦截改看只数:检查点是两分钟窗口,累计次数 rounds 会把同一只翻倍(一天最多 八次),会误读。复核脚本第二张表用只数,台账 013 口径同改,rounds 只当诊断。 - 映射重建先清当日 tech_noread(consensus_stat_repo 加 delete_day_kind),以最新一次 为准。06:30 缺读数、08:40 补上的票不再留旧行让逐只无读数偏高(占比用覆盖行算,一直准)。 - 复核脚本第四张表把「合议交人而人采纳」单列成信息行,不计入分歧——交人本就让人定; 提议上限按天数放大(三十天窗口够用)。 - DEVLOG 09-14 节点修内部不一致:补文档包、从欠账里删掉已完成的 README/CLAUDE.md。 - record_round 的 params 注明暂未用(保留对齐规格书签名)。 第三十一批加一例(映射重建先清当日无读数),开发机全量 847 例 ALL SUITES PASS。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
845d6f2d0b
commit
94da25bc25
|
|
@ -1483,15 +1483,19 @@ app/services/strategy_runner.py(跟踪止盈评估器 _eval_trail 加盘中 SA
|
||||||
## 2026-09-14 · 观察读数包与加固包(开发机完成,未真机判收)
|
## 2026-09-14 · 观察读数包与加固包(开发机完成,未真机判收)
|
||||||
|
|
||||||
**做了什么**
|
**做了什么**
|
||||||
下一阶段第一优先级是「补观察读数」。做了两个工作包,都在开发机完成并全量单测通过,尚未在 155 部署。
|
下一阶段第一优先级是「补观察读数」。做了三个不改行为的工作包(观察读数包、加固包、文档包),都在开发机完成并全量单测通过,尚未在 155 部署。
|
||||||
|
|
||||||
观察读数包:把每轮扫描里合议相关的判定归类落进新表 pms_consensus_stat(第 21 张),供台账 006 到 011 复核。之前这些数只活在扫描返回值与页面即时快照里,复核日期到了拿不出数。动作引擎给合议跳过项(跳过分无评析、看空两类,观察打等开口)与增持门(带 fill/add/dca)打类别标签,只在对应开关开着的分支里打,关掉逐字回旧。落表服务 consensus_stats.record_round 按检查点归类落表:转空离场实弹随时写,路由与装配两类只在检查点写(默认 0935,1030,1330,1445,一天最多四次),试算不写;映射重建时 record_map_cover 记覆盖只数与逐只无读数。复核脚本 scripts/consensus_review.py 与 make consensus-review 打出台账要的四个读数,日报加合议观察小节。新参数 PMS_CONSENSUS_STAT_TIMES 控制检查点。
|
观察读数包:把每轮扫描里合议相关的判定归类落进新表 pms_consensus_stat(第 21 张),供台账 006 到 011 复核。之前这些数只活在扫描返回值与页面即时快照里,复核日期到了拿不出数。动作引擎给合议跳过项(跳过分无评析、看空两类,观察打等开口)与增持门(带 fill/add/dca)打类别标签,只在对应开关开着的分支里打,关掉逐字回旧。落表服务 consensus_stats.record_round 按检查点归类落表:转空离场实弹随时写,路由与装配两类只在检查点写(默认 0935,1030,1330,1445,一天最多四次),试算不写;映射重建时 record_map_cover 记覆盖只数与逐只无读数。复核脚本 scripts/consensus_review.py 与 make consensus-review 打出台账要的四个读数,日报加合议观察小节。新参数 PMS_CONSENSUS_STAT_TIMES 控制检查点。
|
||||||
|
|
||||||
加固包:评审第五节四处小加固。转空去重集只在 SAR 明确为多时才清除(原来「不是空就清」把缺读数也当翻多,会重复减仓),抽出纯函数 _keep_tech_exit_done。持仓行的择时票带上当日盘中转多留痕(decorate_positions 从买入信号同一来源取 flip_map)。登记 PMS_CONSENSUS_WEAK_CONFIRM(默认开,关掉则弱表态放行),consensus.decide 加 weak_confirm 参数。第二十四批时钟用例改相对当前时刻构造陈旧告警,任何时刻跑都过。
|
加固包:评审第五节四处小加固。转空去重集只在 SAR 明确为多时才清除(原来「不是空就清」把缺读数也当翻多,会重复减仓),抽出纯函数 _keep_tech_exit_done。持仓行的择时票带上当日盘中转多留痕(decorate_positions 从买入信号同一来源取 flip_map)。登记 PMS_CONSENSUS_WEAK_CONFIRM(默认开,关掉则弱表态放行),consensus.decide 加 weak_confirm 参数。第二十四批时钟用例改相对当前时刻构造陈旧告警,任何时刻跑都过。
|
||||||
|
|
||||||
|
文档包:按拍板点五,README 与 CLAUDE.md 里「当前是影子模式、没有系统自动下单」改成「下发模式由 PMS_DISPATCH_MODE 决定、以页面顶部横幅为准」,写清模拟仓 155 现为 ws、真实仓 188 尚未追平上线等 QMT 侧、追平先进影子期。CLAUDE.md 入库(原为未跟踪)。本节点即文档包的开发节点记录。
|
||||||
|
|
||||||
**动了哪些文件**
|
**动了哪些文件**
|
||||||
观察读数包(提交 f2d6b37):新增 app/repo/consensus_stat_repo.py、app/services/consensus_stats.py、scripts/consensus_review.py、scripts/test_batch31_units.py;改 ddl_pms_v1.sql(第 21 张表)、app/core/action_engine.py(四个 tag 常量与两处打标签)、app/services/proposal_service.py(_attach_consensus 写 consensus_seen、scan_and_route 末尾调 record_round)、app/services/tech_service.py(build_map 后调 record_map_cover)、app/services/ledger_service.py(日报小节)、app/services/param_store.py(PMS_CONSENSUS_STAT_TIMES)、Makefile(consensus-review 目标)、scripts/run_tests.py(第 31 批登记)、scripts/test_batch6_units.py(DDL 表数 20→21)、scripts/test_batch10_units.py(record_round 进 SOFT_FAIL)、docs/复盘决定台账.md(台账 013)。
|
观察读数包(提交 f2d6b37):新增 app/repo/consensus_stat_repo.py、app/services/consensus_stats.py、scripts/consensus_review.py、scripts/test_batch31_units.py;改 ddl_pms_v1.sql(第 21 张表)、app/core/action_engine.py(四个 tag 常量与两处打标签)、app/services/proposal_service.py(_attach_consensus 写 consensus_seen、scan_and_route 末尾调 record_round)、app/services/tech_service.py(build_map 后调 record_map_cover)、app/services/ledger_service.py(日报小节)、app/services/param_store.py(PMS_CONSENSUS_STAT_TIMES)、Makefile(consensus-review 目标)、scripts/run_tests.py(第 31 批登记)、scripts/test_batch6_units.py(DDL 表数 20→21)、scripts/test_batch10_units.py(record_round 进 SOFT_FAIL)、docs/复盘决定台账.md(台账 013)。
|
||||||
加固包(提交 e21b73b):改 app/core/consensus.py、app/services/consensus_service.py、app/services/param_store.py(PMS_CONSENSUS_WEAK_CONFIRM)、app/services/proposal_service.py、scripts/test_batch24_units.py、scripts/test_batch28_units.py(加 3 例)、scripts/test_batch30_units.py(加 3 例)、scripts/run_tests.py(例数到 846)。
|
加固包(提交 e21b73b):改 app/core/consensus.py、app/services/consensus_service.py、app/services/param_store.py(PMS_CONSENSUS_WEAK_CONFIRM)、app/services/proposal_service.py、scripts/test_batch24_units.py、scripts/test_batch28_units.py(加 3 例)、scripts/test_batch30_units.py(加 3 例)、scripts/run_tests.py(例数到 846)。
|
||||||
|
文档包(提交 b1ebb36):改 README.md、CLAUDE.md(影子模式说法、CLAUDE.md 入库)、DEVLOG.md(本节点)。
|
||||||
|
评审修订(提交在文档包之后,按 docs/观察读数包与加固包评审_2026-09-14.md 第五节):复核脚本增持门改只数、台账 013 口径同改、复核脚本第四张表把「交人被采纳」单列信息行、提议上限按天数放大;record_map_cover 先清当日 tech_noread(consensus_stat_repo 加 delete_day_kind),以最新一次重建为准;本节点修了内部不一致。
|
||||||
|
|
||||||
**部署方式**
|
**部署方式**
|
||||||
改了 Python,make deploy 重建镜像加 force-recreate,并建新表 pms_consensus_stat。收盘后在 155 部署,先经用户审批(本包重建容器、加新表,按服务器铁律先列命令拿批准)。命令:git pull --ff-only && make deploy && make test,预期 ALL SUITES PASS、建表输出 21 张含 pms_consensus_stat。观察读数包与加固包一起部署。
|
改了 Python,make deploy 重建镜像加 force-recreate,并建新表 pms_consensus_stat。收盘后在 155 部署,先经用户审批(本包重建容器、加新表,按服务器铁律先列命令拿批准)。命令:git pull --ff-only && make deploy && make test,预期 ALL SUITES PASS、建表输出 21 张含 pms_consensus_stat。观察读数包与加固包一起部署。
|
||||||
|
|
@ -1500,7 +1504,7 @@ app/services/strategy_runner.py(跟踪止盈评估器 _eval_trail 加盘中 SA
|
||||||
未判收。开发机全量单测 846 例 ALL SUITES PASS(新增第 31 批 20 例,第 28 批到 40、第 30 批到 36)。155 部署待收盘后。判收要看:部署下一个交易日 09:37 后 make consensus-review DAYS=1 打出当天读数(第一天转空离场应为零);映射重建后 pms_consensus_stat 有 map_cover 行;台账 006 到 009 的第一次正式复核在 09-17。
|
未判收。开发机全量单测 846 例 ALL SUITES PASS(新增第 31 批 20 例,第 28 批到 40、第 30 批到 36)。155 部署待收盘后。判收要看:部署下一个交易日 09:37 后 make consensus-review DAYS=1 打出当天读数(第一天转空离场应为零);映射重建后 pms_consensus_stat 有 map_cover 行;台账 006 到 009 的第一次正式复核在 09-17。
|
||||||
|
|
||||||
**还欠着什么**
|
**还欠着什么**
|
||||||
一,收盘后在 155 部署观察读数包与加固包并真机判收,判收读数回填到本节点。二,文档包其余项随对应工作包做:README 影子模式过时说法要改(拍板点五,安全相关,待用户认框架)、CLAUDE.md 入库、台账 012(盘中确认,随盘中确认包)与 014(真实仓初始参数,随真实仓准备包)、接口契约单票研究面(随页面收尾包)。三,盘中确认包、页面收尾包、分段启用包按规格书第四节在 09-17 起推进。四,今天 09:40 那一跳(策略层已确认有意打开)的摘要盘后要拉给用户判读。
|
一,收盘后在 155 部署这三个包并真机判收,判收读数回填到本节点。评审建议 15:40 之后部署,避开 15:10/15:20/15:30 三个日结调度位。二,文档包其余项随对应工作包做:台账 012(盘中确认,随盘中确认包)、014(真实仓初始参数,随真实仓准备包)、接口契约单票研究面(随页面收尾包)。三,盘中确认包、页面收尾包、分段启用包按规格书第四节在 09-17 起推进;盘中确认包动工前要拍板点第二条的答复,拍板点第三、四条仍待答复。四,今天 09:40 那一跳(策略层已确认有意打开)的摘要盘后要拉给用户判读。
|
||||||
|
|
||||||
---
|
---
|
||||||
<!--
|
<!--
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from app.db.session import execute_many, fetch_all
|
from app.db.session import execute, execute_many, fetch_all
|
||||||
|
|
||||||
# 落表的业务列 (与 ddl_pms_v1.sql 的 pms_consensus_stat 对齐)。
|
# 落表的业务列 (与 ddl_pms_v1.sql 的 pms_consensus_stat 对齐)。
|
||||||
# rounds 不在插入列里 —— 插入时用 DDL 的 DEFAULT 1, 重复时在更新子句里 +1。
|
# rounds 不在插入列里 —— 插入时用 DDL 的 DEFAULT 1, 重复时在更新子句里 +1。
|
||||||
|
|
@ -53,6 +53,14 @@ def list_range(date_from: int, date_to: int, kinds=None) -> list:
|
||||||
f"ORDER BY stat_date ASC, kind ASC, ts_code ASC", p)
|
f"ORDER BY stat_date ASC, kind ASC, ts_code ASC", p)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_day_kind(stat_date: int, kind: str) -> int:
|
||||||
|
"""删某北京日期某类别的全部行, 返回删除行数。映射重建时先清当日 tech_noread ——
|
||||||
|
早上两次重建 (06:30/08:40) 各写一遍逐只无读数, 06:30 缺读数、08:40 补上的票那一行会留着,
|
||||||
|
先清再写即以最新一次为准 (2026-09-14 评审第三条)。"""
|
||||||
|
return execute("DELETE FROM pms_consensus_stat WHERE stat_date = :d AND kind = :k",
|
||||||
|
{"d": int(stat_date), "k": str(kind)})
|
||||||
|
|
||||||
|
|
||||||
def count_by_kind(date_from: int, date_to: int) -> dict:
|
def count_by_kind(date_from: int, date_to: int) -> dict:
|
||||||
"""[date_from, date_to] 内按 (日期, 类别) 的计数, 返回 {stat_date: {kind: {rows, rounds}}}。
|
"""[date_from, date_to] 内按 (日期, 类别) 的计数, 返回 {stat_date: {kind: {rows, rounds}}}。
|
||||||
rows 是行数 (几只票), rounds 是累计记到的次数 (同一票记了几轮)。"""
|
rows 是行数 (几只票), rounds 是累计记到的次数 (同一票记了几轮)。"""
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,9 @@ def record_round(out, scanned, params, now=None) -> dict:
|
||||||
"""一轮扫描的合议判定归类落表。调用点在 proposal_service.scan_and_route 末尾 (去重集写回之后)。
|
"""一轮扫描的合议判定归类落表。调用点在 proposal_service.scan_and_route 末尾 (去重集写回之后)。
|
||||||
|
|
||||||
tech_exit 随时写 (稀有实弹); 路由与装配两类只在检查点写 (每分钟太密); dry_run 一律不写。
|
tech_exit 随时写 (稀有实弹); 路由与装配两类只在检查点写 (每分钟太密); dry_run 一律不写。
|
||||||
返回 {ok, rows, ...}; 失败只记警告不抛 —— 登记进 test_batch10 的 SOFT_FAIL, 调用点要接住。"""
|
返回 {ok, rows, ...}; 失败只记警告不抛 —— 登记进 test_batch10 的 SOFT_FAIL, 调用点要接住。
|
||||||
|
|
||||||
|
params 暂未用到 (检查点从参数中心直接读), 保留是为对齐规格书签名, 也留给后续包备用。"""
|
||||||
now = now or datetime.now()
|
now = now or datetime.now()
|
||||||
if not isinstance(out, dict) or out.get("dry_run"):
|
if not isinstance(out, dict) or out.get("dry_run"):
|
||||||
return {"ok": True, "rows": 0, "note": "dry_run 或无 out, 不落表"}
|
return {"ok": True, "rows": 0, "note": "dry_run 或无 out, 不落表"}
|
||||||
|
|
@ -175,6 +177,13 @@ def record_map_cover(*, relevant_codes, state_codes, now=None) -> dict:
|
||||||
调用点在 tech_service.build_map 写完映射之后。失败只记警告、返回 ok 为假, 不拦建映射。"""
|
调用点在 tech_service.build_map 写完映射之后。失败只记警告、返回 ok 为假, 不拦建映射。"""
|
||||||
now = now or datetime.now()
|
now = now or datetime.now()
|
||||||
day = int(now.strftime("%Y%m%d"))
|
day = int(now.strftime("%Y%m%d"))
|
||||||
|
# 先清当天旧的 tech_noread 行 (2026-09-14 评审第三条): 早上 06:30 与 08:40 各重建一次映射,
|
||||||
|
# 06:30 缺读数、08:40 补上的票, 早上那一行本会留着让逐只无读数偏高。先清再写即以最新一次
|
||||||
|
# 重建为准。map_cover 行走 upsert 覆盖不受影响, 占比一直准。清失败只记警告, 不拦覆盖行落表。
|
||||||
|
try:
|
||||||
|
consensus_stat_repo.delete_day_kind(day, K_TECH_NOREAD)
|
||||||
|
except Exception as e: # noqa: BLE001
|
||||||
|
logger.warning("[合议观察] 清当日 tech_noread 失败 (逐只无读数可能偏高, 占比不受影响): %s", e)
|
||||||
rel = [c for c in (relevant_codes or []) if c]
|
rel = [c for c in (relevant_codes or []) if c]
|
||||||
have = set(state_codes or [])
|
have = set(state_codes or [])
|
||||||
rows = [_row(day, "*", K_MAP_COVER,
|
rows = [_row(day, "*", K_MAP_COVER,
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@
|
||||||
|
|
||||||
**依据。** 没有读数就没有复核,没有复核就不能把这套东西部署到真实仓。这是评审认定的下一阶段第一优先级。落表只加不改行为:失败只记警告、不抛、不拦扫描;开关关掉时动作引擎那几处标签一行都不打,逐字回旧。
|
**依据。** 没有读数就没有复核,没有复核就不能把这套东西部署到真实仓。这是评审认定的下一阶段第一优先级。落表只加不改行为:失败只记警告、不抛、不拦扫描;开关关掉时动作引擎那几处标签一行都不打,逐字回旧。
|
||||||
|
|
||||||
**口径。** 技术面无读数占比用映射覆盖那一行算,等于相关票数减覆盖只数再除以相关票数。增持门拦截次数用累计次数算,不是行数。转空离场的确认与否按动作名判,确认转空清仓走 EXIT,未确认减三分之一走 TRIM。合议与人工裁决的比对只看带合议六键且已被人裁决的提议,合议看多而人驳回、合议交人而人采纳的逐只列出。
|
**口径。** 技术面无读数占比用映射覆盖那一行算,等于相关票数减覆盖只数再除以相关票数。增持门拦截看只数,也就是当天被拦的持仓只数;检查点是两分钟窗口,累计次数会把同一只翻倍,只当诊断用,不当拦截次数。转空离场的确认与否按动作名判,确认转空清仓走 EXIT,未确认减三分之一走 TRIM。合议与人工裁决的差异分两类:真分歧是合议看多而人驳回,逐只列出;合议交人而人采纳只是信息行,交人本就是让人定,不算分歧。
|
||||||
|
|
||||||
**参数。** 落表检查点 PMS_CONSENSUS_STAT_TIMES 默认 0935,1030,1330,1445,四位时刻逗号分隔,页面可改。设为空串即不写检查点行,只留转空离场实弹。
|
**参数。** 落表检查点 PMS_CONSENSUS_STAT_TIMES 默认 0935,1030,1330,1445,四位时刻逗号分隔,页面可改。设为空串即不写检查点行,只留转空离场实弹。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,8 @@ def main():
|
||||||
print(" 窗口内没有观察读数 —— 观察读数包还没部署, 或映射还没重建过。")
|
print(" 窗口内没有观察读数 —— 观察读数包还没部署, 或映射还没重建过。")
|
||||||
|
|
||||||
# ---- 二、逐日路由分布 ----
|
# ---- 二、逐日路由分布 ----
|
||||||
print("\n【二】逐日合议路由 (等开口台账线: 每天 1 到 15 只)")
|
print("\n【二】逐日合议路由 (只数; 等开口台账线: 每天 1 到 15 只)")
|
||||||
print(" 日期 等开口 等盘中确认 跳过·无评析 跳过·看空 交人 放行 增持门拦")
|
print(" 日期 等开口 等盘中确认 跳过·无评析 跳过·看空 交人 放行 增持门拦(只)")
|
||||||
for d in _dates_in(counts):
|
for d in _dates_in(counts):
|
||||||
c = counts.get(d) or {}
|
c = counts.get(d) or {}
|
||||||
|
|
||||||
|
|
@ -127,7 +127,9 @@ def main():
|
||||||
sb = _n(cst.K_OPEN_SKIP_BEAR)
|
sb = _n(cst.K_OPEN_SKIP_BEAR)
|
||||||
cf = _n(cst.K_OPEN_CONFIRM)
|
cf = _n(cst.K_OPEN_CONFIRM)
|
||||||
ps = _n(cst.K_OPEN_PASS)
|
ps = _n(cst.K_OPEN_PASS)
|
||||||
gb = (c.get(cst.K_GATE_BLOCK) or {}).get("rounds", 0) # 拦截次数用累计次数
|
# 增持门看只数 (当天被拦的持仓只数)。检查点是两分钟窗口, 累计次数 rounds 会把同一只翻倍
|
||||||
|
# (一个检查点记两次、一天四个点最多八次), 只当诊断用, 不当拦截次数 (2026-09-14 评审第一条)。
|
||||||
|
gb = _n(cst.K_GATE_BLOCK)
|
||||||
flag = " ⚠ 等开口超 15" if wt > 15 else ""
|
flag = " ⚠ 等开口超 15" if wt > 15 else ""
|
||||||
print(" %-8s %5d %8d %9d %8d %4d %4d %6d%s"
|
print(" %-8s %5d %8d %9d %8d %4d %4d %6d%s"
|
||||||
% (d, wt, wc, sf, sb, cf, ps, gb, flag))
|
% (d, wt, wc, sf, sb, cf, ps, gb, flag))
|
||||||
|
|
@ -145,15 +147,17 @@ def main():
|
||||||
% (r["stat_date"], r["ts_code"], conf, d.get("qty"),
|
% (r["stat_date"], r["ts_code"], conf, d.get("qty"),
|
||||||
r.get("rounds"), (r.get("reason") or "")[:40]))
|
r.get("rounds"), (r.get("reason") or "")[:40]))
|
||||||
|
|
||||||
# ---- 四、合议方向与人工裁决比对 ----
|
# ---- 四、合议与人工裁决的差异 ----
|
||||||
print("\n【四】合议方向与人工裁决对不上的 (合议看多而你驳回 / 合议交人而你采纳)")
|
print("\n【四】合议与人工裁决的差异")
|
||||||
|
# 上限按天数放大 (2026-09-14 评审第四条): 三天窗口五百条够用, 三十天可能不够。
|
||||||
|
_lim = min(5000, max(500, int(args.days) * 200))
|
||||||
try:
|
try:
|
||||||
props = pms_repo.list_proposals(statuses=(ACCEPTED, DECLINED), limit=500,
|
props = pms_repo.list_proposals(statuses=(ACCEPTED, DECLINED), limit=_lim,
|
||||||
include_archived=True)
|
include_archived=True)
|
||||||
except Exception as e: # noqa: BLE001
|
except Exception as e: # noqa: BLE001
|
||||||
print(f" ✗ 提议表读取失败: {type(e).__name__}: {e}")
|
print(f" ✗ 提议表读取失败: {type(e).__name__}: {e}")
|
||||||
props = []
|
props = []
|
||||||
mismatches = []
|
divergences, handoff_ok = [], []
|
||||||
for p in props:
|
for p in props:
|
||||||
decided = str(p.get("decided_at") or "")[:10].replace("-", "")
|
decided = str(p.get("decided_at") or "")[:10].replace("-", "")
|
||||||
if not decided or not (str(a) <= decided <= str(b)):
|
if not decided or not (str(a) <= decided <= str(b)):
|
||||||
|
|
@ -164,13 +168,22 @@ def main():
|
||||||
continue # 没有合议六键的提议 (旧提议), 不比对
|
continue # 没有合议六键的提议 (旧提议), 不比对
|
||||||
status = p.get("status")
|
status = p.get("status")
|
||||||
if direction == "看多" and status == DECLINED:
|
if direction == "看多" and status == DECLINED:
|
||||||
mismatches.append((decided, p.get("ts_code"), "合议看多, 你驳回了", con))
|
divergences.append((decided, p.get("ts_code"), con))
|
||||||
elif route == "交人" and status == ACCEPTED:
|
elif route == "交人" and status == ACCEPTED:
|
||||||
mismatches.append((decided, p.get("ts_code"), "合议交人, 你采纳了", con))
|
handoff_ok.append((decided, p.get("ts_code"), con))
|
||||||
if not mismatches:
|
# 真分歧: 合议看多而人驳回。这才是台账要盯的「方向对不上」。
|
||||||
print(" 窗口内没有对不上的 (或还没有带合议六键、已被裁决的提议)。")
|
print(" 真分歧 (合议看多而你驳回):")
|
||||||
for d, code, why, con in sorted(mismatches):
|
if not divergences:
|
||||||
print(" %-8s %-10s %s (合议: %s)" % (d, code, why, con.get("reason") or ""))
|
print(" 无 (或还没有带合议六键、已被裁决的提议)。")
|
||||||
|
for d, code, con in sorted(divergences):
|
||||||
|
print(" %-8s %-10s (合议: %s)" % (d, code, con.get("reason") or ""))
|
||||||
|
# 信息行: 合议交人而人采纳。交人本就是让人定, 人采纳不是分歧 (2026-09-14 评审第二条),
|
||||||
|
# 单列出来是看合议是不是偏保守 (交人后多半被放行则可考虑放宽)。
|
||||||
|
print(" 信息行 (合议交人而你采纳; 交人本就让你定, 不算分歧):")
|
||||||
|
if not handoff_ok:
|
||||||
|
print(" 无。")
|
||||||
|
for d, code, con in sorted(handoff_ok):
|
||||||
|
print(" %-8s %-10s (合议: %s)" % (d, code, con.get("reason") or ""))
|
||||||
|
|
||||||
print("\n复核口径提醒: 本报告只陈述读数, 阈值调整要先回台账 006 到 011 写一条, "
|
print("\n复核口径提醒: 本报告只陈述读数, 阈值调整要先回台账 006 到 011 写一条, "
|
||||||
"不按单次复盘读数回调 (原则一)。")
|
"不按单次复盘读数回调 (原则一)。")
|
||||||
|
|
|
||||||
|
|
@ -92,17 +92,17 @@
|
||||||
开关关掉不打标签)/record_round 归类落表 (检查点写路由与装配两类、
|
开关关掉不打标签)/record_round 归类落表 (检查点写路由与装配两类、
|
||||||
转空实弹随时写、试算不写、被闸拒不记、confirm 据动作名、空串检查点)/
|
转空实弹随时写、试算不写、被闸拒不记、confirm 据动作名、空串检查点)/
|
||||||
record_map_cover 记覆盖与逐只无读数/日报小节失败不拖垮/upsert 更新子句
|
record_map_cover 记覆盖与逐只无读数/日报小节失败不拖垮/upsert 更新子句
|
||||||
只用 VALUES 列不带绑定参数且单表合规/参数登记与检查点窗口 (20 例)
|
只用 VALUES 列不带绑定参数且单表合规/参数登记与检查点窗口/映射重建先清当日无读数 (21 例)
|
||||||
test_page_enum_guard.py 页面文案守卫 (静态扫描, 不连库不起浏览器): 枚举字段不许
|
test_page_enum_guard.py 页面文案守卫 (静态扫描, 不连库不起浏览器): 枚举字段不许
|
||||||
直接印到页面上 / 判据码显示前必须剥前缀 / 不许把整个对象
|
直接印到页面上 / 判据码显示前必须剥前缀 / 不许把整个对象
|
||||||
打给交易员看 / 翻译兜底不许让英文码单独当句子 (1 例)
|
打给交易员看 / 翻译兜底不许让英文码单独当句子 (1 例)
|
||||||
test_wiring.py 装配自检: 服务层→核心→落表 全链路 (内存桩) +
|
test_wiring.py 装配自检: 服务层→核心→落表 全链路 (内存桩) +
|
||||||
目标价到价必定入队 (档位 full 也不自动卖) +
|
目标价到价必定入队 (档位 full 也不自动卖) +
|
||||||
用户设的止损价与目标价单独成列显示 (70 例)
|
用户设的止损价与目标价单独成列显示 (70 例)
|
||||||
共 846 例
|
共 847 例
|
||||||
(总数按实跑逐批相加校正过两次: 曾写 649 是笔误, 实为 650; 09-03 先后加了同轮只发一条
|
(总数按实跑逐批相加校正过两次: 曾写 649 是笔误, 实为 650; 09-03 先后加了同轮只发一条
|
||||||
减持与研究理由两键各一例, 到 652; 09-04 加了仅展示跳过原因与空候选说明各一例, 到 654; 又加了页面文案守卫一例, 到 655; 09-07 审查修复加了跨轮减持等五例, 到 660; 第二件低把握驳回交人一例, 到 661; 第三件逻辑状态接入第二十二批十五例, 到 676; 第四件安全边际整句透传一例, 到 677; 参考目标价一例, 到 678; 催化事件与定价状态透传一例, 到 679; 两个期限的头一例, 现为 680; 09-10 建议档位对齐第二十六批十七例到 697; 09-11 技术面接入工作包一第二十七批二十七例到 724; 三源合议工作包二纯逻辑第二十八批三十七例到 763; 接入下单链路第二十九批二十四例到 787; 工作包三离场纪律第三十批十八例到 805; part3 盘中 SAR 止损线补九例到 814; part4 弱基本面紧止盈补六例到 820;
|
减持与研究理由两键各一例, 到 652; 09-04 加了仅展示跳过原因与空候选说明各一例, 到 654; 又加了页面文案守卫一例, 到 655; 09-07 审查修复加了跨轮减持等五例, 到 660; 第二件低把握驳回交人一例, 到 661; 第三件逻辑状态接入第二十二批十五例, 到 676; 第四件安全边际整句透传一例, 到 677; 参考目标价一例, 到 678; 催化事件与定价状态透传一例, 到 679; 两个期限的头一例, 现为 680; 09-10 建议档位对齐第二十六批十七例到 697; 09-11 技术面接入工作包一第二十七批二十七例到 724; 三源合议工作包二纯逻辑第二十八批三十七例到 763; 接入下单链路第二十九批二十四例到 787; 工作包三离场纪律第三十批十八例到 805; part3 盘中 SAR 止损线补九例到 814; part4 弱基本面紧止盈补六例到 820;
|
||||||
09-14 观察读数包第三十一批二十例到 840; 加固包给第二十八批加三例、第三十批加三例, 现为 846)
|
09-14 观察读数包第三十一批二十例到 840; 加固包给第二十八批加三例、第三十批加三例到 846; 评审修订第三十一批加一例, 现为 847)
|
||||||
任一子集失败即整体失败 (退出码 1)。
|
任一子集失败即整体失败 (退出码 1)。
|
||||||
|
|
||||||
哨兵位置清单 (2026-09-03 抄录; 改了对应的东西就得来这些地方改断言, 断言不动就是漏了):
|
哨兵位置清单 (2026-09-03 抄录; 改了对应的东西就得来这些地方改断言, 断言不动就是漏了):
|
||||||
|
|
|
||||||
|
|
@ -74,15 +74,18 @@ class _patched:
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self._o_get = cst.param_store.get
|
self._o_get = cst.param_store.get
|
||||||
self._o_up = cst.consensus_stat_repo.upsert_many
|
self._o_up = cst.consensus_stat_repo.upsert_many
|
||||||
|
self._o_del = cst.consensus_stat_repo.delete_day_kind
|
||||||
cst.param_store.get = lambda k, d=None: (self.times if k == cst.STAT_TIMES_KEY
|
cst.param_store.get = lambda k, d=None: (self.times if k == cst.STAT_TIMES_KEY
|
||||||
else self._o_get(k, d))
|
else self._o_get(k, d))
|
||||||
cst.consensus_stat_repo.upsert_many = lambda rows: (self.captured.extend(rows)
|
cst.consensus_stat_repo.upsert_many = lambda rows: (self.captured.extend(rows)
|
||||||
or len(rows))
|
or len(rows))
|
||||||
|
cst.consensus_stat_repo.delete_day_kind = lambda d, k: 0 # 离线不打库
|
||||||
return self.captured
|
return self.captured
|
||||||
|
|
||||||
def __exit__(self, *a):
|
def __exit__(self, *a):
|
||||||
cst.param_store.get = self._o_get
|
cst.param_store.get = self._o_get
|
||||||
cst.consensus_stat_repo.upsert_many = self._o_up
|
cst.consensus_stat_repo.upsert_many = self._o_up
|
||||||
|
cst.consensus_stat_repo.delete_day_kind = self._o_del
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -285,6 +288,21 @@ def _():
|
||||||
assert {x["ts_code"] for x in bk["tech_noread"]} == {"600002.SH"}
|
assert {x["ts_code"] for x in bk["tech_noread"]} == {"600002.SH"}
|
||||||
|
|
||||||
|
|
||||||
|
@case("C record_map_cover·重建先清当日 tech_noread (以最新一次为准, 评审第三条)")
|
||||||
|
def _():
|
||||||
|
deleted, upserted = [], []
|
||||||
|
o_del, o_up = csr.delete_day_kind, csr.upsert_many
|
||||||
|
csr.delete_day_kind = lambda d, k: (deleted.append((d, k)), 0)[1]
|
||||||
|
csr.upsert_many = lambda rows: (upserted.extend(rows), len(rows))[1]
|
||||||
|
try:
|
||||||
|
cst.record_map_cover(relevant_codes=["600000.SH"], state_codes=set(),
|
||||||
|
now=datetime(2026, 9, 15, 8, 40))
|
||||||
|
finally:
|
||||||
|
csr.delete_day_kind, csr.upsert_many = o_del, o_up
|
||||||
|
assert (20260915, cst.K_TECH_NOREAD) in deleted # 先清当日 tech_noread
|
||||||
|
assert any(r["kind"] == cst.K_MAP_COVER for r in upserted) # 再写覆盖行
|
||||||
|
|
||||||
|
|
||||||
# ================================================================ D 仓库 upsert
|
# ================================================================ D 仓库 upsert
|
||||||
@case("D upsert_many·更新子句只用 VALUES 列不带绑定参数; SQL 单表合规")
|
@case("D upsert_many·更新子句只用 VALUES 列不带绑定参数; SQL 单表合规")
|
||||||
def _():
|
def _():
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue