步骤4阶段1 - 3-4天核心闭环方案(修正版V3)
制定日期: 2026-09-13
观察任务: cron_id=7e8ae2aeca81
当前进度: D1观察中(18次自动运行,100%成功)
任务1:风控熔断细节补充
1.1 "阻止操作"在人工执行下的落地方式
落地方式: 盘前报告顶部标注 + audit_log记录
具体实现:
1. 盘前报告顶部标注(morning_eval.py)
- 若触发熔断,在报告最顶部输出🚨醒目标注
- 格式: "🚨 熔断警告: [总仓位>80% / 单票回撤≥10% / ...]"
- 下方附: "请人工确认后决定是否开仓"
2. audit_log记录(tools/audit_logger.py)
- 每次熔断触发写入audit_log.json
- 字段: timestamp, item, level, condition, action, confirmed_by, confirmed_at
- 人工确认后补填confirmed_by和confirmed_at
3. TG告警(alert_channel_health.py)
- 熔断级别(CIRCUIT_BREAK/EMERGENCY)立即推TG
- 警告级别(WARNING)写入日志,不推TG
1.2 单票回撤口径修正
原定义: 从买入价算回撤
修正: 从持仓期间最高价算回撤
计算公式:
peak_price = max(持仓期间每日最高价)
drawdown_pct = (peak_price - current_price) / peak_price * 100%
示例:
买入价: 10元
持仓期间最高: 12元
当前价: 10元
回撤 = (12-10)/12 = 16.7%(不是从10元算的0%)
1.3 单日回撤口径修正
原定义: 当日收盘价相对前日收盘回撤
修正: 盘中实时"当日最高资产→当前资产"回撤
计算公式:
daily_peak_asset = max(当日实时资产曲线)
current_asset = 当前资产
daily_drawdown = (daily_peak_asset - current_asset) / daily_peak_asset * 100%
触发条件:
- 盘中实时计算(每分钟更新)
- >3%时触发熔断,冻结新开仓
- 收盘后若未恢复,次日继续冻结
1.4 流动性阈值板块差异
原定义: 统一阈值(成交额<1亿或换手率<1%)
修正: 按板块差异化阈值
| 板块 | 成交额阈值 | 换手率阈值 | 说明 |
|------|-----------|-----------|------|
| 主板 | <1亿 | <1% | 标准阈值 |
| 科创板 | <5000万 | <2% | 流动性较弱,阈值放宽 |
| 创业板 | <8000万 | <1.5% | 介于主板和科创板之间 |
实现:
def check_liquidity(code, volume, turnover_rate):
# 识别板块
market = get_market(code) # "mainboard" / "star" / "chinext"
thresholds = {
"mainboard": {"volume": 100000000, "turnover": 0.01},
"star": {"volume": 50000000, "turnover": 0.02},
"chinext": {"volume": 80000000, "turnover": 0.015}
}
t = thresholds[market]
return volume < t["volume"] or turnover_rate < t["turnover"]
1.5 完整熔断定义(修正版)
| 熔断项 |
触发条件 |
阻止动作 |
恢复条件 |
备注 |
| 总仓位 |
>80% |
阻止新开仓 |
仓位降至80%以下 |
盘前报告标注+TG告警 |
| 单票回撤 |
≥8% |
警告,不建议加仓 |
回撤修复或人工确认 |
仅警告,不阻断 |
| 单票回撤 |
≥10% |
阻止该票交易 |
人工确认恢复 |
盘前报告🚨标注 |
| 单日回撤 |
>3% |
冻结新开仓 |
人工确认恢复 |
盘中实时计算 |
| 总回撤 |
≥15% |
强制降仓至50%以下 |
人工确认恢复 |
🚨紧急熔断 |
| 流动性 |
板块阈值以下 |
阻止该票交易 |
流动性恢复 |
板块差异化阈值 |
任务2:D2排期修正
2.1 D2时间表
| 时段 |
任务 |
耗时 |
验收标准 |
| 08:00-09:00 |
4项受控测试(盘前) |
1小时 |
4项测试全部通过 |
| 15:30-16:30 |
run_with_alert集成(盘后) |
1小时 |
集成后能触发告警检查 |
| 20:00-20:30 |
回归验证 |
30分钟 |
无回归,cron正常运行 |
总计: 2.5小时
2.2 上午受控测试流程(08:00-09:00)
# === 08:00 前置备份 ===
cp C:/Users/Admin/AppData/Local/hermes/cron/jobs.json C:/Users/Admin/AppData/Local/hermes/cron/jobs.json.bak_D2
# === 08:10 测试1:告警路径(15分钟)===
# 添加测试任务 → 插入failed记录 → 等待cron运行 → 检查TG告警 → 清理
# === 08:25 测试2:超时路径(15分钟)===
# 修改last_run_at为3天前 → 等待cron运行 → 检查TG告警 → 恢复
# === 08:40 测试3:Dead-Man(15分钟)===
# 临时停heartbeat写入 → 等待15分钟 → 检查TG告警 → 恢复
# === 08:55 测试4:通道健康(5分钟)===
# 改TG token为错误值 → 等待cron运行 → 检查TG告警 → 恢复token
2.3 下午集成流程(15:30-16:30)
# run_with_alert集成到评估流程
# 在eval_smart.py末尾添加alert钩子
# 伪代码:
if __name__ == "__main__":
# 原有评估逻辑...
results = evaluate_batch(codes)
# 新增:触发告警检查
from alert_channel_health import check_alerts
alerts = check_alerts()
if alerts:
print("[ALERT] " + " | ".join(alerts))
2.4 晚上回归验证(20:00-20:30)
# 20:00 检查cron状态
hermes cron list 2>&1 | grep -A 6 "7e8ae2aeca81"
# 20:15 检查心跳记录
python -c "import sqlite3; conn=sqlite3.connect('D:/Hermes/data/state/alert_state.db'); rows=conn.execute('SELECT check_time,status FROM channel_health ORDER BY check_time DESC LIMIT 5').fetchall(); [print(f' {r[0]} | {r[1]}') for r in rows]; conn.close()"
# 20:30 确认无回归,输出D2总结
任务3:D1完成确认
3.1 D1完成标准
| 检查项 |
通过标准 |
检查时间 |
| 20:00晚间检查 |
心跳更新正常,无异常告警 |
20:00 |
| 次日10:00 D1总结 |
汇总D1全天运行次数、成功率、心跳记录、TG通知、exit_code分布 |
次日10:00 |
3.2 D1总结报告内容
# D1观察总结
**日期**: 2026-09-13
**观察时段**: 10:30-14:30(暂定)
## 运行统计
- 自动运行次数: X次
- 成功率: 100%
- 平均间隔: 15m05s
- 心跳记录: X条(全部ok)
- TG通知: 0次(expected)
- exit_code分布: 全部0
## 检查点
- [x] 10:30 首次自动运行
- [x] 11:00 自动运行
- ...
- [x] 14:00 自动运行
- [x] 14:02 检查通过
- [ ] 20:00 晚间检查(待执行)
- [ ] 次日10:00 D1总结(待执行)
## 结论
D1观察通过,可进入D2。
3.3 D1完成后启动D2(人工确认)
D1完成条件:
✓ 20:00晚间检查通过
✓ 次日10:00 D1总结输出
D2启动条件:
✓ D1总结输出后,人工确认通过
✓ 不由系统自动启动
✓ 用户明确指令"进入D2"后才启动
附录:当前系统状态
A.1 已部署组件
| 组件 |
文件路径 |
cron_id |
状态 |
| alert_channel_health |
D:/Hermes/scripts/alert_channel_health.py |
7e8ae2aeca81 |
✅ 运行中 |
| dead_mans_switch |
D:/Hermes/scripts/dead_mans_switch.py |
- |
✅ 已部署 |
| run_with_alert |
D:/Hermes/scripts/run_with_alert.py |
- |
⏳ D2集成 |
A.2 D1观察统计
| 指标 |
值 |
| 自动运行次数 |
18次(10:30-14:15) |
| 成功率 |
100% |
| 平均间隔 |
15m05s |
| 心跳记录 |
18条(全部ok) |
| TG通知 |
0次(expected) |
| exit_code |
全部0 |
A.3 待执行检查
| 时间 |
检查内容 |
状态 |
| 14:30 |
自动运行 |
⏳ 即将执行 |
| 20:00 |
晚间检查 |
⏳ 待执行 |
| 次日10:00 |
D1总结 |
⏳ 待执行 |
方案修正时间: 2026-09-13T14:35:00
下一步: 等待20:00晚间检查 + 次日10:00 D1总结,人工确认通过后启动D2