步骤4阶段1 - 3-4天核心闭环方案(修正版V2)
制定日期: 2026-09-13
观察任务: cron_id=7e8ae2aeca81
当前进度: D1观察中(18次自动运行,100%成功)
任务1:修正风控熔断定义
1.1 交易执行方式确认
交易执行方式: 人工执行
熔断机制: 阻止操作 → 通知用户 → 等待人工确认恢复
1.2 熔断逻辑定义
| 熔断项 |
触发条件 |
阻止动作 |
恢复条件 |
| 总仓位 |
总仓位>80% |
阻止新开仓 |
仓位降至80%以下 |
| 单票 |
单票回撤≥8% |
发出警告,不建议加仓 |
回撤修复或人工确认 |
| 单票 |
单票回撤≥10% |
阻止该票交易 |
人工确认恢复 |
| 单日回撤 |
单日回撤>3% |
冻结新开仓 |
人工确认恢复 |
| 总回撤 |
总回撤≥15% |
强制降仓至50%以下 |
人工确认恢复 |
| 流动性 |
成交额<1亿或换手率<1% |
阻止该票交易 |
流动性恢复 |
1.3 熔断实现伪代码
# D:/Hermes/scripts/risk_circuit_breaker.py
def check_circuit_breaker(position, stock, daily_drawdown, total_drawdown, liquidity):
"""核心6项熔断检查"""
results = []
# 1. 总仓位检查
if position.total_position_pct > 80:
results.append({
"item": "总仓位",
"level": "WARNING",
"action": "阻止新开仓",
"message": f"总仓位{position.total_position_pct:.1f}%>80%,阻止新开仓"
})
# 2. 单票回撤检查(分级)
if stock.drawdown_pct >= 10:
results.append({
"item": "单票回撤",
"level": "CIRCUIT_BREAK",
"action": "阻止该票交易",
"message": f"{stock.code}回撤{stock.drawdown_pct:.1f}%≥10%,阻止交易"
})
elif stock.drawdown_pct >= 8:
results.append({
"item": "单票回撤",
"level": "WARNING",
"action": "不建议加仓",
"message": f"{stock.code}回撤{stock.drawdown_pct:.1f}%≥8%,建议不加仓"
})
# 3. 单日回撤检查
if daily_drawdown > 3:
results.append({
"item": "单日回撤",
"level": "CIRCUIT_BREAK",
"action": "冻结新开仓,人工确认恢复",
"message": f"单日回撤{daily_drawdown:.2f}%>3%,冻结新开仓"
})
# 4. 总回撤检查
if total_drawdown >= 15:
results.append({
"item": "总回撤",
"level": "EMERGENCY",
"action": "强制降仓至50%以下,人工确认恢复",
"message": f"总回撤{total_drawdown:.1f}%≥15%,强制降仓"
})
# 5. 流动性检查
if liquidity.turnover_rate < 0.01 or liquidity.volume < 100000000:
results.append({
"item": "流动性",
"level": "WARNING",
"action": "阻止该票交易",
"message": f"{stock.code}流动性不足,阻止交易"
})
return results
def apply_circuit_breaker(results):
"""执行熔断动作"""
for r in results:
if r["level"] == "CIRCUIT_BREAK":
# 记录日志 + 发送TG告警
send_tg_alert(r["message"])
elif r["level"] == "EMERGENCY":
# 紧急熔断,立即通知
send_tg_alert(f"🚨 紧急熔断: {r['message']}")
# WARNING级别只记录,不阻断
任务2:修正D2排期
2.1 D2时间表
| 时段 |
任务 |
耗时 |
验收标准 |
| 上午 9:00-11:00 |
4项受控测试 |
2小时 |
4项测试全部通过 |
| 下午 14:00-15:00 |
run_with_alert集成 |
1小时 |
集成后能触发告警检查 |
| 晚上 20:00-20:30 |
集成后回归验证 |
30分钟 |
无回归,cron正常运行 |
总计: 3.5小时
2.2 上午受控测试流程(9:00-11:00)
# === 9:00 前置备份 ===
cp C:/Users/Admin/AppData/Local/hermes/cron/jobs.json C:/Users/Admin/AppData/Local/hermes/cron/jobs.json.bak_D2
# === 9:10 测试1:告警路径(30分钟)===
# 添加测试任务 → 插入failed记录 → 等待cron运行 → 检查TG告警 → 清理
# === 9:40 测试2:超时路径(30分钟)===
# 修改last_run_at为3天前 → 等待cron运行 → 检查TG告警 → 恢复
# === 10:10 测试3:Dead-Man(30分钟)===
# 临时停heartbeat写入 → 等待30分钟 → 检查TG告警 → 恢复
# === 10:40 测试4:通道健康(30分钟)===
# 改TG token为错误值 → 等待cron运行 → 检查TG告警 → 恢复token
2.3 下午集成流程(14:00-15:00)
# 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:修正D4影子运行方案
3.1 D4全天运行安排
| 时段 |
任务 |
说明 |
| 08:30-09:15 |
盘前准备 |
启动双系统,配置比对脚本 |
| 09:30-11:30 |
盘中运行 |
原系统 vs 新系统并行 |
| 13:00-15:00 |
盘中运行 |
继续对比 |
| 15:00-15:30 |
盘后比对 |
生成偏差报告 |
| 20:00-20:30 |
晚间检查 |
确认双系统稳定 |
3.2 D3晚上配置(19:00-20:00)
# D3晚上配好影子运行环境
# 1. 创建影子目录
mkdir -p D:/Hermes/shadow_run
# 2. 复制原系统配置(只读)
cp -r D:/Hermes/评估中心 D:/Hermes/shadow_run/评估中心_backup
# 3. 配置新系统(可修改)
cp -r D:/Hermes/评估中心 D:/Hermes/shadow_run/评估中心_new
# 4. 准备比对脚本
cat > D:/Hermes/shadow_run/compare_output.py << 'EOF'
# 比对原系统 vs 新系统输出
# 输出差异>5%的项目
EOF
3.3 D4晚上比对(20:00-20:30)
# D4晚上执行比对
python D:/Hermes/shadow_run/compare_output.py
# 输出比对报告
# - 偏差>5%的项目列表
# - 新系统异常项
# - 建议:是否切换
任务4:确认D1观察完成条件
4.1 D1完成标准
| 检查项 |
通过标准 |
检查时间 |
| 20:00晚间检查 |
心跳更新正常,无异常告警 |
20:00 |
| 次日10:00 D1总结 |
汇总D1全天运行次数、成功率、心跳记录、TG通知、exit_code分布 |
次日10:00 |
4.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。
4.3 D1完成后启动D2
D1完成条件:
✓ 20:00晚间检查通过
✓ 次日10:00 D1总结输出
D2启动:
✓ D1总结通过后立即启动
✓ 不需额外确认
附录:当前系统状态
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