189 lines
7.3 KiB
Markdown
189 lines
7.3 KiB
Markdown
# v4.5.48 (2026-08-07) 5 个新硬规则 — 用户明确报错要求
|
||
|
||
## 背景
|
||
|
||
用户在 8/7 这一天密集发火,5 次指出同一流程反复出问题:
|
||
1. `"刚才的做多的能开仓了吗"` —— 推了性价比低还下
|
||
2. `"还有一点,刚才下单的有提示性价比低的,还是下了,这种不该下"`
|
||
3. `"这个是多余的消息吧"` —— 无持仓平仓信号还推
|
||
4. `"你算不出来就把字段删了吧"` (前一天,本质同) + `"刚才的BTC空单信号再处理一次"`
|
||
5. `"这种报错你要主动记录的,不然跟那个定时任务一样,我根本不知道有没有成功"`
|
||
6. `"那我根本不知道有没有成功"` —— 错误不主动记
|
||
7. `"信号源不对"` —— trader 标了 "X聚合社区" 但实际是 "未知"
|
||
|
||
## 5 个新硬规则(每条都对应"用户原话" + 修复路径)
|
||
|
||
### 1. 性价比低不自动下 (v4.5.48 P1)
|
||
|
||
**用户原话**: "刚才下单的有提示性价比低的,还是下了,这种不该下"
|
||
|
||
**旧行为** `process_signal.py`:
|
||
```python
|
||
auto_execute = rec.get('contracts', 0) > 0 # 有可开张数 = 自动执行
|
||
```
|
||
→ 性价比低(`rating_text='性价比低'`)也照样下。
|
||
|
||
**新行为** (2026-08-07):
|
||
```python
|
||
cc_check = rec.get('cost_check', {})
|
||
rating_text_check = cc_check.get('rating_text', '')
|
||
is_low_rating = '性价比低' in rating_text_check
|
||
auto_execute = contracts > 0 and not is_low_rating # 性价比低**不**自动下
|
||
```
|
||
|
||
**为什么**: 性价比低 = 期望收益 < 手续费 = 净亏,**自动下是亏钱**。用户原话"这种不该下"。
|
||
|
||
**注意**: 不下 ≠ 不推。仍推 QQ 告知"性价比低,跳过"。
|
||
|
||
### 2. D 类信号"无持仓可平"静默 (v4.5.48 P2)
|
||
|
||
**用户原话**: "这个是多余的消息吧"
|
||
|
||
**旧行为** `process_signal.py` `format_close_message`:
|
||
```python
|
||
elif action == 'none':
|
||
return f"""ℹ️ {symbol} {side_cn} 平仓信号 | {trader}
|
||
|
||
无持仓可平"""
|
||
```
|
||
→ 推 QQ,但实际**没平**,纯冗余。
|
||
|
||
**新行为** (2026-08-07):
|
||
```python
|
||
if signal_type == 'close':
|
||
close_result = close_position_raw(symbol_usdt, signal_side_en)
|
||
action = close_result['action']
|
||
if action == 'none':
|
||
# 静默: 仍记录去重 + 释放锁 + 不推 QQ
|
||
record_signal(...)
|
||
dedup_conn.close()
|
||
release_lock(symbol_usdt, trader, auto=True)
|
||
return f"⏭️ 平仓信号无持仓静默 | {symbol_usdt} {signal_side_en}"
|
||
# 否则正常推
|
||
```
|
||
|
||
**为什么**: 用户之前多次说"只要有错就推,正常就静默" — close=none 不算错,也不算事件。**主动记日志但 QQ 静默**。
|
||
|
||
### 3. trader default 改 "未知" (v4.5.48 P3)
|
||
|
||
**用户原话**: "信号源不对,之前修复了一版,是脚本都没了吗?"
|
||
|
||
**诊断**: `process_signal.py` parse_signal 第 87 行:
|
||
```python
|
||
# 旧
|
||
fields['trader'] = 'X聚合社区' # 默认值
|
||
```
|
||
|
||
**问题**: 当 raw_text 里**没** trader 标记时,被标成 "X聚合社区"(误导)。
|
||
|
||
**新行为** (2026-08-07):
|
||
```python
|
||
# 2026-08-07: 不要硬编码 'X聚合社区', 标 '未知'
|
||
fields['trader'] = '未知'
|
||
```
|
||
|
||
**为什么**: 之前修复 v4.5.36 时把 "X聚合社区"写死当默认值,但很多信号 trader 标记缺失,这条会被错误归类成"X聚合社区"。
|
||
|
||
**trader 解析 3 层 fallback**:
|
||
1. `【交易员】XXX`
|
||
2. `👉 跟单就选 X`
|
||
3. **第一个非字段【xx】**(币种/方向/杠杆/仓位等跳过)
|
||
4. 全失败 → "未知"
|
||
|
||
### 4. 订单错误主动记录 (v4.5.48 P4)
|
||
|
||
**用户原话**: "这种报错你要主动记录的,不然跟那个定时任务一样,我根本不知道有没有成功"
|
||
|
||
**背景**: 之前 `okx_position_advisor.py execute_order()` 失败只 `results['steps'].append({status: error, msg: ...})` —— **只在内存**,**不写日志**。Cron 失败不主动告警。
|
||
|
||
**新行为** (2026-08-07):
|
||
```python
|
||
# 0. 写错误日志的辅助函数
|
||
import json as _json
|
||
from datetime import datetime as _dt
|
||
_ERR_LOG = os.path.expanduser('~/.hermes/trading/order_errors.log')
|
||
|
||
def _log_error(stage, err_msg, extra=None):
|
||
"""主动记录订单错误到独立文件 (用户要求 2026-08-06)"""
|
||
try:
|
||
log_entry = {
|
||
'ts': _dt.now().isoformat(),
|
||
'stage': stage, # set_leverage / place_order / sl_algo
|
||
'symbol': symbol, 'inst_id': inst_id, 'side': side,
|
||
'contracts': contracts, 'leverage': leverage,
|
||
'error': str(err_msg)[:500],
|
||
'extra': extra or {},
|
||
}
|
||
with open(_ERR_LOG, 'a') as f:
|
||
f.write(_json.dumps(log_entry, ensure_ascii=False) + '\n')
|
||
except Exception:
|
||
pass # 写日志不能 fail 主流程
|
||
```
|
||
|
||
**覆盖 4 个 stage**:
|
||
- `set_leverage` 失败
|
||
- `place_order` 失败
|
||
- `sl_algo` 没返回 algoId
|
||
- `sl_algo` exception
|
||
|
||
**配套 cron 监控** `order-errors-monitor.sh`:
|
||
```bash
|
||
# 每小时(5 分)扫 ~/.hermes/trading/order_errors.log
|
||
# 有新错误 → 推 QQ
|
||
# 无错 → silent (cron deliver: origin)
|
||
```
|
||
|
||
**两条 cron** 都创建成功:
|
||
- `order-errors-monitor` (job_id: 81bd534cebfc) — 每小时 5 分
|
||
- `cron-self-check` (job_id: 09ca1313822c) — 每小时 0 分
|
||
|
||
### 5. cron 失败不主动监控 (v4.5.48 P5)
|
||
|
||
**用户原话**: "修好了?测试一下" + "你看,现在这个定时任务跑失败了,你也不主动检查"
|
||
|
||
**背景**: 之前 `lottery-hot-data` cron 跑失败 30+ 小时,agent 完全没发现,直到用户看到推送告诉我。
|
||
|
||
**新行为** (2026-08-07):
|
||
- `cron-self-check.sh` — 每小时跑,拉 `hermes cron list` 拿所有 cron script,缺失从 `~/.hermes/` 自动找修复,缺失 file **推 QQ**
|
||
- `order-errors-monitor.sh` — order 错误监控
|
||
- `cron-self-check` 默认 silent,**有错才推**
|
||
|
||
**Cron 配置**:
|
||
- `cron-self-check` (09ca1313822c) — `schedule: 0 * * * *`, `deliver: local` (silent)
|
||
- `order-errors-monitor` (81bd534cebfc) — `schedule: 5 * * * *`, `deliver: origin`
|
||
|
||
## 自我总结:8/7 用户 7 次报错 全都是"主动 vs 静默"问题
|
||
|
||
| 用户原话 | 修复 |
|
||
|---|---|
|
||
| "刚才的做多的能开仓了吗" | 推 OK + advisor 给 |
|
||
| "有提示性价比低的,还是下了,这种不该下" | auto_execute 跳过低 rating |
|
||
| "这个是多余的消息吧" | close=none 静默 |
|
||
| "这种报错你要主动记录的" | _log_error → order_errors.log |
|
||
| "我根本不知道有没有成功" | order-errors-monitor cron |
|
||
| "之前修复了一版,是脚本都没了吗" | trader default "X聚合社区" → "未知" |
|
||
| "修好了?测试一下" | cron-self-check + 静默模式 |
|
||
|
||
**核心洞察**: 8/7 用户的报错 = **"主动 vs 静默"控制不对**:
|
||
- 错的 → 主动推 + 主动记
|
||
- 正常的 → 静默
|
||
- 状态询问 → 主动给[实测数据]
|
||
|
||
## 关联
|
||
|
||
- `v4.5.45-lock-status-push-and-auto-unlock.md` — 锁状态推送(8/6)
|
||
- `v4.5.43-close-pnl-delete-display.md` — 平仓 PnL 字段(8/5)
|
||
- `v4.5.42-insufficient-funds-explicit-notify.md` — 余额不足(8/5)
|
||
- `forwarder-rule-enable-killer.md` — forwarder silent killer(8/6)
|
||
- `agent-workflow-feedback-rules.md` — 用户工作流纠错 master 文档
|
||
|
||
## 部署状态
|
||
|
||
- [x] auto_execute 跳过低 rating (process_signal.py 已改)
|
||
- [x] close=none 静默 (process_signal.py 已改)
|
||
- [x] trader default "未知" (process_signal.py 已改)
|
||
- [x] _log_error → order_errors.log (okx_position_advisor.py 已改)
|
||
- [x] order-errors-monitor cron (job_id: 81bd534cebfc)
|
||
- [x] cron-self-check cron (job_id: 09ca1313822c)
|
||
- [x] cron-self-check 改 silent (deliver: local)
|