正在加载盘面数据…
竞彩决策台 三源融合 · 赔率分析与串关
⚠ 本工具仅供研究参考 · 彩票有风险 · 投注需理性

📋 复盘报告 修复与复盘交付报告-2026-09-10.md

文件:修复与复盘交付报告-2026-09-10.md | 位置:C:\qinglong\ticai\竞彩北单预测\reports\修复与复盘交付报告-2026-09-10.md
📄 报告内容

修复 · 复盘 · 预测 · 串关 —— 整合交付报告

  • 日期:2026-09-10
  • 范围:保活根治 + 计划任务加固 + 数据质量修复 + 今日全场复盘 + 补预测 + 串关复盘
  • 结论:6 项修复全部落地并实测验证;今日预测覆盖 100%;全场复盘 75 场(已比对 17 场,胜平负命中率 76%);串关实验 ROI 转正 +0.4%

一、执行摘要

项目结果验证方式
---------
保活(根治待机杀进程)✅ 已落地powercfg /requests SYSTEM 段出现 python 进程
Web 自动恢复(看门狗)✅ 已上线WB_WebWatchdog LastResult=0,20:25 正常巡检
计划任务声明式重建✅ 6 个任务全部 StartWhenAvailable=True、允许电池运行
告警静默修复✅ 双通道logs/alerts.log 实测落盘
赛果重复入库✅ 写入防线 + 清理 55 行150,365 → 150,310
健康检查口径✅ 九维度全绿health_check.py 结论「健康 ✅」
今日补预测✅ 5 场全部恢复方向占位「—」→ 市场隐含/上游共识
今日全场复盘✅ 75 场 / 已比对 17 场胜平负 13/17 = 76%
串关复盘✅ 325 条 / 276 已结算ROI +0.4%(+12.54 元)

二、保活:根治"系统待机杀进程"

根因(上一轮已定位)

系统空闲 120 秒进入新型待机(Modern Standby),把无人值守的长任务进程杀掉,

计划任务返回 0x8007042B(ERROR_PROCESS_ABORTED)。09-09 流水线死于 08:35:11,

5 秒后系统进入待机;09-10 同窗口两次待机;09-08 之所以跑满 94 分钟,是因为

当时有人操作、鼠标活动维持了唤醒。

修复(改代码,不动系统电源策略)

新增 core/keepawake.py:调用 Windows SetThreadExecutionState

(ES_CONTINUOUS | ES_SYSTEM_REQUIRED),守护线程每 30 秒续期。

几个刻意的设计选择:

  • 不申请 ES_DISPLAY_REQUIRED —— 屏幕可以正常熄灭,只保"系统不被判定空闲",

对笔记本日常使用影响最小;

  • 失败只记日志、绝不抛异常 —— 保活是增强项,不能反过来弄挂主流程;
  • KYGZ_NO_KEEPAWAKE=1 可整体关闭 —— 调试/受限环境留出口;
  • 两侧都接入:app.py(Web 进程)与 automation/run_daily.py(流水线进程)。

原因是 Power Request 按进程生效、不被子进程继承,而流水线通常由 Web 进程内的

daily_scheduler 以子进程拉起 —— 只在一侧声明会漏掉另一侧。

实测:powercfg /requests 的 SYSTEM 段出现 [PROCESS] python.exe ✅

⚠️ 一个必须说明的时序问题

当前正在运行的 Web 进程与流水线都启动于保活代码落盘之前——Python 不会热加载改动的

代码,所以它们体内还没有保活逻辑。也就是说,今天这一轮补跑流水线仍在待机风险下。

已用新增的 scripts/keep_awake_hold.py --until-pid 42788 起了独立保活守护临时覆盖

(目标进程退出即自动释放,已确认登记进 SYSTEM 电源请求)。

下次重启后保活永久生效(明天 08:30 计划任务起来即是新版)。


三、计划任务加固

新增 Web 看门狗

WB_WebApp 原来只有 BootTrigger —— 进程被杀后任务仍是 Ready,不会自愈,端口 5000

就此长期无监听。新增 WB_WebWatchdog(每日 00:00 起每 5 分钟,持续 23h55m):

  • 探活 127.0.0.1:5000/,健康时绝不动作(避免打断正在跑的流水线);
  • "端口有监听但 HTTP 不通"判定为僵死 → 先 /end 再 /run(否则 IgnoreNew 会拒绝新实例);
  • 拉起后复检 3 次,失败与恢复都经 core/alerts 落盘(同类 30 分钟内去重)。

声明式安装器

新增 scripts/install_tasks.py,把 6 个 WB_* 任务从代码生成 Task Scheduler XML 注册。

起因是旧的 automation/install_task.bat 任务名写着「体彩每日自动化」、时间是 02:00,

与现网实际在跑的 6 个任务完全不符 —— 照着它装只会装出一个没人知道的野任务。

统一电源策略为 StartWhenAvailable=true + 允许电池运行:掉电或错过时间窗都不再

放弃这一轮(介意电池耗电可传 --conservative-power 改回)。

一个有用的实测结论

担心"重新注册任务会连坐杀掉正在跑的流水线",所以先用一次性探针任务做了实验:

Register-ScheduledTask -Force 不会终止正在运行的实例(改定义前后探针进程都存活、

任务状态仍 Running)。确认后原位同步了 WB_WebApp,流水线与 Web 进程均安然无恙。

install_task.bat

重写为纯 ASCII 转调脚本。原因:cmd.exe 按 OEM 代码页(中文 Windows 为 936/GBK)

解析 .bat,UTF-8 的中文路径会在执行前就被花掉;把逻辑全部放进 Python,.bat 只负责

找到解释器并转发参数。


四、告警与日志

问题修复
------
alerts.webhook_url 为空 → notify_on_fail: true 形同虚设,两天故障静默新增 core/alerts.py 双通道:本地 logs/alerts.log 永久落盘(无需任何配置)+ 配置 webhook 后推送。异常时也落盘
Web 任务动作无 stdout 重定向,被杀时磁盘零痕迹app.py 增加 RotatingFileHandler → logs/app.log(10MB ×5)。进程内落盘比 shell 重定向可靠,不依赖谁以何种方式拉起
logs/alerts.log 已实测有内容(看门狗故障模拟)。

五、数据质量

赛果重复入库(真实问题)

根因:yucejia 与 qiulaile-HTFT 两条通道对同一场比赛各写一行 ——

一行 match_id 是 yucejia 上游返回的 32 位哈希(直接调其 API 确认,上游本身如此),

另一行是 qiulaile 的数字 ID。match_results 主键是 (source, match_id),

唯一约束拦不住,近 30 天积累 57 组,会被训练配对管线重复计数。

修复:

1. data/store.py 新增写入防线 drop_fixture_duplicate_rows —— 仅当

同源 + 同对阵 + 同日 + 同分且 match_id 不同才判重;比分冲突视为真实冲突两行都留。

索引按日期批量预载,避免退化成 O(N²)。

2. 新增 scripts/dedupe_results.py(默认演练,--apply 才落库),已执行:

赛果 150,365 → 150,310(删 55 行),2 组比分冲突按设计保留待人工确认。

备份用 SQLite 在线 backup API 而非文件复制(WAL 模式下直接 copy 会漏掉未 checkpoint 的内容)。

健康检查口径

  • 非法赔率(全表仅 8 条 / 221,553 行 = 0.004%,全为德国杯/国王杯首轮强队客战业余队的

上游客胜赔率触底截断):FAIL → WARN,条数 ≥50 才 FAIL(解析器回归时会飙升,仍能拦住)。

  • 重复赛果拆成"同分(可安全清理)/ 比分冲突(需人工确认)"两级,同分 ≥30 组才 FAIL。

结果:九维度全绿,health_check.py 结论「健康 ✅」


六、今日补预测("没有预测的进行预测")

定位过程

今日在售范围去重后 71 场,初筛 5 场方向为 —(无可用源):

26093-47 / 26093-48 / 26093-55(英冠)、26093-40(荷甲)、okooo-3010(英冠)。

另有 5 个疑似缺口经队名模糊复核全部是变体误判(里斯本竞技/里斯本、
女王公园/女王巡游、基多大学体育/基多大学…),实际都已有预测。

根因链(逐层验证)

config.yaml: fusion.league_blacklist = [法乙, 国际友谊, 英冠, 荷甲]
   ↓ 判据:全量回测 ROI 法乙-7.8% / 国际友谊-7.7% / 英冠-7.2% / 荷甲-6.5%
predict_match() 命中黑名单 → 直接返回空 Prediction(无 market_probs / 无 extras)
   ↓
rule_spf = None;若上游同时缺席 → _fuse_spf 三源全空
   ↓
退化为均匀分布 0.33/0.34/0.33 → top_pick 落成占位「—」
   ↓
预测记录存在但**没有方向**,复盘无从谈起

修复

core/fusion.py 新增:

  • _market_implied_spf(snapshots) —— 取快照中最新一组"标准胜平负"赔率去水;

让球档的 win/draw/lose 为 0,天然被排除;

  • _fuse_spf(..., fallback_probs=...) —— 仅当规则/ML/上游/KNN 全部缺席时才回退

市场隐含概率,来源显式标注「市场隐含」。

为什么用市场隐含兜底而不是放宽黑名单:黑名单是投注回避规则,不该顺带剥夺

"给个方向"的能力;而去水后的市场隐含概率正是项目长期结论里最强的基线

(欧赔/亚盘市场高度有效),用它兜底既给出可复盘的方向,也不冒充规则/ML 判断。

predict_match 的黑名单语义保持不动 —— 兜底只在融合层生效,既有测试全部不受影响。

落库

竞彩此前没有任何独立落库入口(只能等每日流水线)。新增

scripts/persist_predictions.py(--market jingcai|beidan|all、--db-day 历史回补、

--check 只统计)。

已执行并验证:5 场全部恢复方向(26093-47 负 / 26093-48 胜 / 26093-40 胜 /

26093-55 负 / okooo-3010 负)。

今日覆盖复核:75 场,占位方向 0 条 —— 100% 有方向。

方向分布  胜 33 / 负 30 / 平 12
来源分布  规则引擎 56 · 规则引擎+上游共识 14 · 市场隐含 3 · 上游共识 2
口径提示(踩过坑):prediction_key 含来源与版本,预测值变化时新增行;
而 key 命中既有行时走 UPDATE 并刷新 created_at(见 store._prediction_update_sql)。
所以"当前生效的那条"= created_at 最大者,不是 id 最大者 ——
原位更新保留旧 id,用 id 排序会选到已被取代的行(实测:修正后 26093-40/-55
仍被误算成占位)。scripts/persist_predictions.py 的统计口径已按此修正。

>

历史遗留 47 条占位方向(jingcai 21 / beidan 26,集中在 09-03~09-08,
全部来自黑名单联赛)。北单可按 --db-day 回补;竞彩历史无法回补
(场次池只加载当日)。今日已 100% 覆盖。

七、今日全场复盘

为什么不走 backtest/review.py --start/--end

该路径按 canonical_key = (date, league, home, away) 对齐 —— 联赛名参与键。

实测:同一场比赛赔率侧叫「美职业」、赛果侧叫「美职」,键不同即无法对齐;

2026-09-10 赔率侧 282 个 fixture、赛果侧仅 4 条通过严格过滤,交集 0 → 复盘出 0 场。

改用 AutoReviewPipeline(与每日流水线报告同源:store 路径 + 队名模糊桥接),

并新增 scripts/run_review.py 作为可直接调用的复盘 CLI。

结果(2026-09-10)

指标数值
------
场次总数75
已比对17
待回填58(今晚欧战尚未开赛)
胜平负命中率13/17 = 76%
比分 Top5 覆盖率9/17 = 53%

已比对 17 场全部为竞彩(okooo-3001~3015 与 周四001~007)。逐场命中示例:

欧冠 里斯本 3-1 ✅、那不勒斯 0-1 ✅、利物浦 2-1 ✅、切尔西 6-3 ✅、

拜仁 3-0 ✅、曼联 4-0 ✅;未中:查尔顿 0-0(预测胜)、芝加哥 1-1(预测负)、

费内巴切 4-1(预测负)、阿马多拉 3-0(预测负)。

⚠️ 口径不一致(值得注意)

复盘走的是 predict_match 的旧仓位口径(STAKE_UNITS:标准投注 100 / 减半 50 / 放弃 0),

今日 15/17 判为「放弃」,于是"模拟盈亏"只由 1 场决定(-100 单位),参考价值很低。

而 core/recommender.py 的"强制不放弃"规则下这些场次都有仓位。两套口径不同源,

不可直接对比。建议:复盘报告把"命中率"作为主指标,"模拟盈亏"标注为规则引擎旧口径,

或后续统一到推荐引擎口径(会改变历史可比性,需单独评估)。


八、串关复盘

补结算后重新统计(scripts/settle_parlays.py + scripts/parlay_tracker.py):

指标数值
------
总条数325(已结算 276 / 待结算 49)
命中20 胜 / 256 负,命中率 7.2%
投入2,814 元
净盈亏+12.54 元
ROI+0.4%
进度325/60 条(542%),17/30 天(57%)

分组明细

市场/玩法条数已结算命中率盈亏ROI
------------------
beidan/hcap403616.7%+872.40+302.9%
beidan/score30254.0%+259.36+129.7%
beidan/spf63557.3%+101.68+18.0%
jingcai/htft3333.3%+57.00+38.0%
jingcai/single22100%+12.60+31.5%
jingcai/hcap403315.2%-76.00-28.8%
jingcai/spf52462.2%-486.50-84.2%
jingcai/goals30230%-184.00-100%
jingcai/score30230%-184.00-100%
beidan/goals30250%-200.00-100%

读数:整体靠 beidan 让球盘单点撑起(+872.40,占全部正贡献的绝大部分);

jingcai 侧全线为负,其中 spf/goals/score 三个玩法是主要失血点。

命中率 7.2% 是高倍串关的设计后果,但 276 条样本下 ROI 仅 +0.4% 说明**这套选场尚未

证明有正期望** —— 建议再积累到 30 天/60+ 条门槛后重判,暂不下结论。


九、改动文件清单

新增(8 个脚本/模块 + 3 个测试)

core/keepawake.py                    保活核心
core/alerts.py                       告警双通道
scripts/web_watchdog.py              Web 看门狗
scripts/install_tasks.py             计划任务声明式安装器
scripts/dedupe_results.py            重复赛果清理
scripts/persist_predictions.py       预测落库单次执行器
scripts/run_review.py                全场复盘 CLI
scripts/keep_awake_hold.py           限时保活守护(应急)
tests/test_keepawake.py              13 项
tests/test_results_dedup.py          11 项
tests/test_fusion_market_fallback.py 10 项

修改

core/fusion.py            市场隐含兜底(_market_implied_spf + _fuse_spf fallback)
data/store.py             赛果入库去重防线 + 索引化
health_check.py           非法赔率/重复赛果判定口径
app.py                    保活接入 + 文件日志(RotatingFileHandler)
automation/run_daily.py   保活接入
automation/install_task.bat  重写为 ASCII 转调

计划任务

新增  WB_WebWatchdog   每 5 分钟探活,不可达自动拉起 Web
重建  WB_WebApp / WB_DailyPipeline / WB_SnapshotLoop / WB_BeidanPersist / WB_Backup
      (统一 StartWhenAvailable + 允许电池运行)

产出报告

reports/健康检查报告-2026-09-10.md        九维度体检(含根因证据链)
reports/复盘报告-2026-09-10-全场.md       今日 75 场逐场复盘
reports/修复与复盘交付报告-2026-09-10.md   本文件

十、遗留与建议

优先级事项说明
---------
P0重启 Web 与流水线当前进程早于保活代码启动,体内无保活;下次计划任务触发即自动带上(明天 08:30)
P1复盘仓位口径不一致复盘走规则引擎旧口径(今日 15/17 判「放弃」),与推荐引擎"强制不放弃"不同源
P1alerts.webhook_url 仍为空本地落盘已兜底,但主动推送需要一个机器人 webhook 地址
P2历史占位方向 47 条jingcai 21 / beidan 26,09-03~09-08,全为黑名单联赛;北单可按 --db-day 回补,竞彩历史不可回补
P22 组比分冲突赛果队名为空,疑为已隔离的假比分残留,需人工确认
P3串关选场待观察276 条样本 ROI +0.4%,尚不足以判定正期望;jingcai 侧全线为负值得专项排查

*本报告所有结论均附可复现证据;新增/修改代码均配套单元测试。*

← 返回回测中心