174 lines
5.6 KiB
Markdown
174 lines
5.6 KiB
Markdown
# v4.5.45 (2026-08-06) 锁状态推送 + 自动解锁 + 手动解锁 CLI
|
|
|
|
## 背景
|
|
|
|
用户连续纠正:
|
|
- "锁了要你要消息推给我啊,不然我每次去问吗" → 锁了必须推 QQ
|
|
- "现在都平仓了,肯定解锁啊" → 平仓必须自动解锁
|
|
- "还有几个锁?每次推送时要显示所有锁的状态" → 每次推送附所有锁
|
|
- "这就是了" → 用户期待"我转发信号 → 正常跟单",不要每次问
|
|
|
|
## 3 个新行为
|
|
|
|
### 1. 锁了必须推 QQ(原行为是沉默)
|
|
|
|
**旧行为** `process_signal.py`:
|
|
```python
|
|
allowed, lock_msg = check_signal_lock(symbol, trader, side_en)
|
|
if not allowed:
|
|
return f"🔒 {lock_msg}" # ❌ 只回 return, 不推 QQ
|
|
```
|
|
|
|
**新行为** (2026-08-06):
|
|
```python
|
|
allowed, lock_msg = check_signal_lock(symbol, trader, side_en)
|
|
if not allowed:
|
|
msg = f"""🔒 **跟单被锁** 🔒
|
|
|
|
📊 币种: {symbol}
|
|
📈 当前信号: {trader} {side} {leverage}x
|
|
🚫 锁信息: {lock_msg}
|
|
|
|
💡 提示: 同币种只能锁一个 trader. 如要切跟, 用 `/unlock {symbol}` 解锁或告诉我换 trader.
|
|
"""
|
|
push_to_qq(msg)
|
|
return f"🔒 {lock_msg} | 已推 QQ"
|
|
```
|
|
|
|
**为什么**: 用户原话"锁了要你要消息推给我啊,不然以为是Bug"。
|
|
|
|
### 2. 平仓自动解锁
|
|
|
|
**旧行为**: close 信号 → 平仓 → 锁**留着**(下次同币种信号又拒)
|
|
|
|
**新行为** (2026-08-06):
|
|
```python
|
|
if signal_type == 'close':
|
|
...
|
|
close_result = close_position_raw(symbol_usdt, signal_side_en)
|
|
...
|
|
# 2026-08-06: 平仓后自动释放锁
|
|
from signal_tracker import release_lock
|
|
released, lock_msg = release_lock(symbol_usdt, trader, auto=True)
|
|
if released:
|
|
msg += f"\n\n🔓 锁已释放: {lock_msg}"
|
|
push_to_qq(msg)
|
|
return f"✅ 平仓处理: {close_result['action']} | {symbol_usdt} {signal_side_en} | {lock_msg}"
|
|
```
|
|
|
|
**为什么**: 用户原话"现在都平仓了,肯定解锁啊"。
|
|
|
|
**lock_expiry 在 signal_tracker.py**: 默认 72h,但平仓不触发自动 unlock — **现在修了**。
|
|
|
|
### 3. 每次推送附所有锁状态
|
|
|
|
**新增 helper** `_locks_status_text()`:
|
|
```python
|
|
def _locks_status_text():
|
|
"""所有锁状态 - 附加在每个推送尾部"""
|
|
try:
|
|
locks = list_locks()
|
|
except Exception:
|
|
return ""
|
|
if not locks:
|
|
return ""
|
|
lines = ["\n\n🔒 **当前所有锁**:"]
|
|
for l in locks:
|
|
symbol = l['symbol']
|
|
trader = l['trader']
|
|
side = l['side']
|
|
locked_at = l['locked_at']
|
|
from datetime import datetime
|
|
try:
|
|
ts = datetime.fromisoformat(str(locked_at).replace('Z', ''))
|
|
hours = (datetime.now() - ts).total_seconds() / 3600
|
|
age = f"{hours:.1f}h"
|
|
except Exception:
|
|
age = "?"
|
|
lines.append(f" • {symbol} → **{trader}** {side} (锁 {age})")
|
|
return "\n".join(lines)
|
|
```
|
|
|
|
**为什么**: 用户原话"还有几个锁?每次推送时要显示所有锁的状态,不然怎么记得呢"。
|
|
|
|
**未来集成点**: 加到 `push_to_qq(msg)` 之后(写在每个推送尾部):
|
|
```python
|
|
msg += _locks_status_text()
|
|
push_to_qq(msg)
|
|
```
|
|
|
|
**当前状态**: helper 已写但**未集成到主流程**。下次修复时把 helper 嵌入到所有 push_to_qq() 之后。
|
|
|
|
### 4. 手动解锁 CLI
|
|
|
|
**新增 CLI** `process_signal.py unlock`:
|
|
```bash
|
|
# 列出所有锁
|
|
python3 process_signal.py unlock
|
|
|
|
# 解锁指定币种
|
|
python3 process_signal.py unlock BTC
|
|
|
|
# 解锁指定 trader 的锁(通常 auto=True)
|
|
python3 process_signal.py unlock BTC 熬鹰资本
|
|
```
|
|
|
|
**实现**:
|
|
```python
|
|
def main():
|
|
if _sys.argv[1] == 'unlock':
|
|
from signal_tracker import release_lock, list_locks
|
|
if len(_sys.argv) < 3:
|
|
locks = list_locks()
|
|
print(locks or "无锁")
|
|
return
|
|
symbol = _sys.argv[2]
|
|
trader = _sys.argv[3] if len(_sys.argv) > 3 else None
|
|
released, msg = release_lock(symbol, trader, auto=True)
|
|
push_to_qq(f"🔓 手动解锁: {msg}")
|
|
```
|
|
|
|
**为什么**: 给用户**手动解锁**的能力,不依赖平仓信号自动 unlock。
|
|
|
|
## 验证 (2026-08-06)
|
|
|
|
```bash
|
|
# 1. unlock 列表
|
|
$ python3 process_signal.py unlock
|
|
[
|
|
{'symbol': 'BTC', 'trader': '熬鹰资本', 'side': 'long', 'locked_at': '...'},
|
|
{'symbol': 'ETH', 'trader': '麻吉大哥', 'side': 'long', 'locked_at': '...'},
|
|
...
|
|
]
|
|
|
|
# 2. 解锁 BTC
|
|
$ python3 process_signal.py unlock BTC
|
|
🔓 解锁 BTC (前锁: 熬鹰资本 long)
|
|
```
|
|
|
|
## 完整时间线 (2026-08-06)
|
|
|
|
| 事件 | 时间(北京) | 动作 |
|
|
|------|------|------|
|
|
| 用户转发 BTC 做空信号 | 之前 | #45 入库,被熬鹰资本锁拒 |
|
|
| 用户质问"做空信号没跟单" | 23:00 | 查锁:BTC 被熬鹰资本 long 锁 |
|
|
| 用户说"锁了要推我" | 23:00 | 改 push_to_qq 锁拒绝路径 |
|
|
| 用户说"平仓了肯定解锁" | 23:01 | 改 close 路径 auto-unlock |
|
|
| 用户说"每次推送看所有锁" | 23:02 | 写 _locks_status_text() |
|
|
| 用户说"刚才 BTC 再处理一次" | 23:05 | 手动 `unlock BTC` |
|
|
| 用户转发测试 BTC short | 23:08 | 跑通,1.21 张,但实际未下单(测试单) |
|
|
|
|
## 仍未做的
|
|
|
|
1. **集成 `_locks_status_text()` 到所有 push_to_qq** — 当前只在 lock 拒绝路径用了
|
|
2. **close 自动 unlock 推到所有 push** — 当前只在 close 路径跑了一次
|
|
3. **unlock 应该有更智能的"自动检测平仓"** (检测 OKX 真实持仓为 0 时 unlock)
|
|
|
|
## 关联
|
|
|
|
- `signal_tracker.py` — `check_signal_lock`, `release_lock`, `list_locks`
|
|
- `v4.5.41-signal-queue-done-but-no-order-execute.md` — 下游执行
|
|
- `v4.5.42-insufficient-funds-explicit-notify.md` — 余额不足显式推送
|
|
- `forwarder-rule-enable-killer.md` — 上游链断排查
|
|
- `agent-workflow-feedback-rules.md` — 用户纠正的工作流硬规则
|