From b6d0d68803582b73c81427c53ffccdc09740af0c Mon Sep 17 00:00:00 2001 From: mike Date: Mon, 13 Jul 2026 23:53:55 +0800 Subject: [PATCH] =?UTF-8?q?v4.5.3:=20=E5=8C=BA=E5=88=86=E5=9B=9E=E5=A4=8D?= =?UTF-8?q?=E4=BE=A7=20vs=20QQ=E6=8E=A8=E9=80=81=E4=BE=A7=20=E2=80=94=20?= =?UTF-8?q?=E5=9B=9E=E5=A4=8D=E4=BB=85=E6=8A=A5=E6=A0=B8=E5=BF=83=E7=8A=B6?= =?UTF-8?q?=E6=80=81,QQ=E6=8E=A8=E5=85=A8=E5=A5=97=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- okx-auto-position/SKILL.md | 339 +++++++++++++++++++++++++++++++++++-- 1 file changed, 328 insertions(+), 11 deletions(-) diff --git a/okx-auto-position/SKILL.md b/okx-auto-position/SKILL.md index 2b85d0d..fc85576 100644 --- a/okx-auto-position/SKILL.md +++ b/okx-auto-position/SKILL.md @@ -1,8 +1,8 @@ --- name: okx-auto-position -description: "OKX自动仓位管理+信号推送v4.5.0:脚本驱动信号处理。process_signal.py自动完成解析→过期检查(30分钟)→advisor→性价比→格式化含📐→去重→仓位变化对比→推QQ。channel_prompts只需一条命令。signal_tracker.py记录仓位历史对比加减仓变化。v4.5.0: (1)只设止损不设止盈,平仓信号触发市价平仓(2)平仓信号自动跟单-无需确认(同方向平,反向不动)(3)完全自动跟单-无Y/N确认-只推结果。" -version: 4.5.0 -tags: [trading, okx, crypto, position-sizing, auto, push, templates, qq, signal, expiration] +description: "OKX自动仓位管理+信号推送v4.5.5:脚本驱动信号处理。process_signal.py自动完成解析→过期检查(30分钟)→平仓信号raw REST自动跟平(同方向平,反向不动,无仓推提醒)→advisor→性价比→格式化含📐→去重→仓位变化对比→推QQ。signal_tracker.py记录仓位历史对比加减仓变化。v4.5.0: 只设止损不设止盈,平仓信号触发市价平仓+平仓信号自动跟单-无需确认(同方向平,反向不动)+完全自动跟单-无Y/N确认-只推结果。v4.5.1: 反查订单真实status避免假阳性成功推送。v4.5.2: 禁止过度分析(用户原话:该分析的都在skill里了)/CCXT vs raw REST可靠性/杠杆丢失bug(3次复现)/dedup误跳平仓信号/30% utilization安全仓位。v4.5.3: 平仓信号raw REST签名修复(GET签名须加? + query按字典序排序,POST body直接拼接)+回复侧vs QQ推送侧严格区分。v4.5.4: SPCX-USDT-SWAP自动下单静默失败(2次确认)+连发信号仓位噪声过滤(<1%变化视为持仓快照同步)。v4.5.5: 杠杆丢失bug 3次实战复现(SKHY×2+MU)+ reference文档+已知受害币种清单。" +version: 4.5.5 +tags: [trading, okx, crypto, position-sizing, auto, push, templates, qq, signal, expiration, close-follow] --- # OKX 自动仓位管理 + 信号推送模板 @@ -34,6 +34,105 @@ python3 ~/.hermes/skills/trading/okx-auto-position/scripts/okx_position_advisor. 2. **加仓 → 直接 --execute → 推结果+📐+持仓表格(不推Y/N)** 3. **新开仓 → 直接 --execute(所有信号自动执行,余额不足才跳过)** +--- + +**🔴 [2026-07-08 v4.5.3 用户明令] 回复侧 vs QQ推送侧严格区分**: +- **用户最新指令(2026-07-08)**: "我是指这个信息,是你分析的吗,只需要把跟单结果中涉及数据相关的推给QQ,这里不需要推" +- **铁律**: + 1. **数据/执行结果** → 推QQ(包括品种/方向/张数/杠杆/avgPx/upl/保证金/可用余额/强平价/异常说明) + 2. **回复侧(Telegram/本会话)** → 只报**核心状态**(已跟单 X 张 @ Yx, 浮盈/亏 Z, 可用 USDT W),不重复QQ里的全套字段 + 3. **禁止在回复侧写**: 跟单小结、对比分析表、三选一、Y/N菜单、"熬鹰开比你高/逆势"这类主观判断 + 4. **推QQ要齐全**(用户需要看),回复侧要极简(避免冗余) +- **实战案例**: MU short 跟单后,agent 回复侧写了"avgPx 940.40 比熬鹰937.62更贵 / 浮亏-0.03% / 系统对加仓信号更稳定"等分析,被用户指出"你分析这些没有用" +- **正确示例**: + - ❌ 错: 熬鹰MU短664张,系统已跟0.52张,你的开仓940.40比熬鹰937.62高$2.78(逆势),熬鹰也在亏... + - ✅ 对: `MU short 0.52张@10x 已跟, 浮亏-$0.28, USDT $59` + +--- + +**🔴 [2026-07-08 v4.5.2 用户明令] 禁止过度分析**: +- **用户原话**: "你分析这些没有用,不需要你分析,该分析的都在skill里了" +- ❌ **禁止**: 在信号推送/执行后,写"三选一/Y持/Y减/Y全平"等判断清单、长篇"判断/节奏/操作建议" +- ❌ **禁止**: 把"麻吉扛不住/他可能会..."这类主观推测写进回复 +- ❌ **禁止**: 用大段 markdown 表格对比"信号 vs 实际/你的状态 vs 麻吉状态/三个方案优劣" +- ✅ **正确**: 跑脚本 → 反查真实持仓 → 推QQ结果 → 简短报"已跟单 X 张 / 浮盈 Y / USDT Z" +- ✅ **唯一例外**: 出现余额不足/advisor报错/方向矛盾等**真正需要用户决策的异常**时,可以简短提示,1-2 行就够,不展开 +- **原因**: skill 已经编码了所有规则,agent 再分析等于重复+冗余,违反"该分析的都在skill里了"原则 +- **判断标准**: 推送后只回"已执行 X 张 @ Yx, 当前持仓/余额"这类事实报告,不写"如果...就.../建议..."等决策建议 +- **实战案例**: 风寻SKHY加仓信号执行后,agent 写了"完美跟单/三选一/Y持/Y减/Y加"被用户骂"分析这些没有用" + +--- + +**🔴 [2026-07-08 v4.5.2] CCXT vs Raw REST 可靠性差距 (实战确认)**: +- **症状**: `ccxt` 库频繁报 `SSLError: UNEXPECTED_EOF_WHILE_READING` / `ReadTimeout` / `RequestTimeout`(尤其 `load_markets()` 和 `fetch_currencies()`) +- **根因**: ccxt 内部对 `/api/v5/asset/currencies` 的 SSL handshake 在 proxy 127.0.0.1:7890 下不稳 +- **实测可靠路径** (凭证类操作统一走这条): + ```python + import json,time,hmac,hashlib,base64,requests + creds = open('/home/openclaw/.bashrc').read() + api_key = sec = passphrase = None + for line in creds.split('\n'): + if line.startswith('export OKX_API_KEY='): api_key = line.split('=',1)[1].strip().strip('"').strip("'") + elif line.startswith('export OKX_SECRET='): sec = line.split('=',1)[1].strip().strip('"').strip("'") + elif line.startswith('export OKX_PASSPHRASE='): passphrase = line.split('=',1)[1].strip().strip('"').strip("'") + def okx_get(path, params=None, t=15): + ts = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime()) + msg = ts + 'GET' + path + (json.dumps(params) if params else '') + sig = base64.b64encode(hmac.new(sec.encode(), msg.encode(), hashlib.sha256).digest()).decode() + h = {'OK-ACCESS-KEY': api_key, 'OK-ACCESS-SIGN': sig, 'OK-ACCESS-TIMESTAMP': ts, + 'OK-ACCESS-PASSPHRASE': passphrase, 'Content-Type': 'application/json'} + px = {'http':'http://127.0.0.1:7890','https':'http://127.0.0.1:7890'} + return requests.get(f'https://www.okx.com{path}', params=params or {}, + headers=h, proxies=px, timeout=t).json() + def okx_post(path, body, t=15): + body_str = json.dumps(body) + ts = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime()) + msg = ts + 'POST' + path + body_str + sig = base64.b64encode(hmac.new(sec.encode(), msg.encode(), hashlib.sha256).digest()).decode() + h = {'OK-ACCESS-KEY': api_key, 'OK-ACCESS-SIGN': sig, 'OK-ACCESS-TIMESTAMP': ts, + 'OK-ACCESS-PASSPHRASE': passphrase, 'Content-Type': 'application/json'} + px = {'http':'http://127.0.0.1:7890','https':'http://127.0.0.1:7890'} + return requests.post(f'https://www.okx.com{path}', data=body_str, + headers=h, proxies=px, timeout=t).json() + ``` +- **何时用 raw REST**: 查询持仓/余额/下单/平仓 → 全部走 raw REST,不依赖 ccxt +- **何时用 ccxt**: advisor 脚本内的 indicator/ATR 计算可以用(那部分不调 OKX 私有 API),但**任何写操作(下单/平仓/撤单)必须 raw REST** +- **agent 侧 fallback**: advisor 报 SSL/超时错误时,**不要重试 ccxt 路径**,直接 raw REST 重做 + +--- + +**🔴 [2026-07-13 v4.5.2] process_signal 杠杆丢失 bug (实战确认 3次)**: +- **症状**: 信号原文杠杆 X,advisor/execute 后实际下单是 10x(始终是默认 10,不是信号值) +- **实战复现**: + - 2026-07-08 风寻 SKHY:信号5x → execute 10x (avgPx 161.01, 强平价 192.86) + - 2026-07-13 风寻 SKHY:信号2x → execute 10x (avgPx 157.02, 强平价 187.95) + - 2026-07-13 熬鹰 MU:信号2x → execute 10x (avgPx 940.40, 强平价 1136.92) +- **根因**: process_signal.py 调用 advisor 时 `leverage=str(leverage)` 传的可能是默认值 10,未正确读取信号里的 leverage 字段 +- **影响**: 真实杠杆 = 信号 5倍 = 强平价 5倍近 = 风险**5倍**爆 +- **agent 侧强制校验**: execute 后立即 raw REST 查持仓 `lever` 字段,对比信号里的杠杆,**不一致就 manual close 重开(用 raw REST 下正确杠杆)** +- **永久修复 (待改 process_signal.py)**: parse_signal 时把 leverage 强制转 int 并验证 1-50 范围,传给 advisor +- **已知受害币种**: SKHY, MU. 任何小币种永续都需校验。 + +--- + +**🔴 [2026-07-08 v4.5.2] 平仓信号 dedup window 太短 bug (实战确认)**: +- **症状**: 风寻SKHY连发"减仓"+"已平仓提醒"两条信号,process_signal 把第2条 dedup 跳过 → **平仓信号没触发** +- **根因**: 2分钟去重窗口把"减仓"+"平仓"当成同一类信号 +- **正确行为**: "减仓"(仓位变化)和"已平仓提醒"(全平)是不同信号类型,**不应该去重** +- **永久修复 (待改 process_signal.py)**: dedup key 加入 signal_type,只有同 trader+同 coin+同 signal_type 才去重 +- **agent 侧绕路**: dedup 命中时,手动判断信号类型,如果是"已平仓提醒"/"📉 平仓止损"且查持仓仍有同方向 → 手动 raw REST 平仓 + +--- + +**🔴 [2026-07-08 v4.5.2] 30% utilization 安全仓位 (新规上线)**: +- **用户明确**: 币圈安全仓位 = 30% utilization(覆盖默认45%) +- 总保证金 ≤ 可用余额 × 30% +- 超过此线严禁加仓,即使 advisor 推荐高性价比 +- 加仓前必须 raw REST 查 `/api/v5/account/balance`,计算 `current_margin / availBal`,>30% 拒绝加仓 +- **实战案例 (2026-07-08)**: CL 已加到 40张(43% utilization),用户问"能再加吗",30% 安全线下不能再加 +- **自动化脚本**: `scripts/safety_check.py [--symbol X] [--market-cap 30]` — read-only 诊断工具,输出每个持仓的保证金/方向/杠杆/浮盈/强平价,以及总 utilization vs 安全线。返回码 0=安全,2=超线,1=空仓 +- **agent 侧校验**: advisor 输出 `margin_pct > 30` 时,即使 `auto_execute=true` 也要 raw REST 反查实际 utilization,超线则拒绝 execute 并推"⚠️ 30% utilization 超线,不加仓" + **🔴 [2026-07-08 v4.5.0 平仓规则修订(实战教训)]**: v4.3.0 规定"反向持仓不动",但 2026-07-08 实战证明: - 熬鹰 ETH 空单平仓盈利时,你持 ETH long 9.82张 → 按 v4.3.0 应不动,但**系统实际平掉了 ETH long**(你亏 -$11) - 熬鹰 BTC 多单平仓盈利时,你持 BTC long 0.73张(同方向) → 系统平掉,+$0.48 @@ -47,6 +146,35 @@ python3 ~/.hermes/skills/trading/okx-auto-position/scripts/okx_position_advisor. - **agent 强制流程**: 任何 `--execute` 调用后,必须 raw REST 反查 `/api/v5/account/positions?instId=X-USDT-SWAP` 和 `/api/v5/account/balance` 的 `frozenBal` 字段,**以反查结果为准**报告仓位,不要凭 stdout 推断 - **永久修复(待改 `scripts/okx_position_advisor.py`)**: execute 路径成功下单后,在 stdout JSON 追加 `{"order_id": "...", "filled": true/false, "fill_price": ...}` 字段 +**🔴 [2026-07-10 v4.5.1 用户反馈教训] 禁止"假阳性成功"推送**: +- 场景: cron 推送 `📊 HK 1810.HK 现价 25.28 / ✅ 下单成功: 1260056765857271808`,实际查询发现订单 status=Rejected +- 用户原话: "这个没成功,不要乱发。被拒绝了。" +- **根因**: hk_intraday_cli.py 推送逻辑直接读 execute_order() 返回的 order_id,就把 `❌ 下单失败: ...` 改成 `✅ 下单成功: {id}`,**没看订单实际 status** +- **新规(覆盖之前推送逻辑)**: + 1. execute_order() 之后,必须**反查订单实际 status** (`fetch_order(order_id)` 或 `fetch_open_orders()`) + 2. 只有 `status == 'closed'` 或 `'filled'` 才推 "✅ 下单成功" + 3. `status == 'Rejected'` 推 "❌ 下单被拒: {id} (原因: 查看长桥 App 或 CLI `orders --json`)" + 4. `status == 'NotReported'` 推 "⏳ 已提交: {id} (等待成交, 港股日内单收盘自动作废)" + 5. `status == 'Canceled'` 推 "🚫 已撤: {id}" + 6. **没反查前, 推送只能说"已提交 {id}, 待确认", 不能说"成功"** +- **绝对禁止**: 看 stdout 有 order_id 就推 "✅ 下单成功" —— stdout 只代表"已发请求",不代表"已成交" +- **自动化**: 在 `hk_intraday_cli.py` 和 `us_intraday_cli.py` 改 `submit_order` 调用为: + ```python + resp = openapi.submit_order(...) + order_id = resp.order_id + # 立即反查 + status = check_order_status(order_id, symbol) # 新函数 + if status == 'closed': + push "✅ {symbol} 下单成功 @ {price}, 订单 {id}" + elif status == 'Rejected': + push "❌ {symbol} 下单被拒 (id={id}), 查 CLI: orders --json" + elif status == 'NotReported': + push "⏳ {symbol} 已提交 {id}, 等成交" + else: + push f"⚠️ {symbol} 订单 {id} 状态: {status}" + ``` +- 同样适用于 longbridge-cli 推送: 任何订单推送前先 `orders --json | grep {id}` 验证 status + **🔴 [2026-07-08 v4.5.0 新坑] advisor `--contracts N` 参数不存在**: - `okx_position_advisor.py` argparse 不支持 `--contracts`(实测报 `unrecognized arguments`) - 想自定义张数只能**直接调 raw REST `POST /api/v5/trade/order` 下市价单**,绕过 advisor @@ -88,18 +216,129 @@ python3 ~/.hermes/skills/trading/okx-auto-position/scripts/okx_position_advisor. --- +## 🔍 持仓速查 (2026-07-11 用户需求) + +**场景**: 用户随时问"现在有什么持仓"、"当前 SPCX / 1810 / ETH 持仓多少"。 + +**正确做法** (agent 立即执行,**不反问**): + +```bash +# === OKX 持仓 === +cat > /tmp/check_okx.py << 'PYEOF' +import ccxt, sys +sys.path.insert(0, '/home/openclaw/.hermes/hermes-agent/venv/lib/python3.11/site-packages') +okx_key = open('/home/openclaw/.bashrc').read().split('OKX_API_KEY=')[1].split('\n')[0].strip() +okx_sec = open('/home/openclaw/.bashrc').read().split('OKX_SECRET=')[1].split('\n')[0].strip() +okx_pwd = open('/home/openclaw').read().split('OKX_PASSPHRASE=')[1].split('\n')[0].strip() +ex = ccxt.okx({'apiKey':okx_key,'secret':okx_sec,'password':okx_pwd, +'proxies':{'http':'http://127.0.0.1:7890','https':'http://127.0.0.1:7890'},'timeout':15000}) +ex.options['defaultType'] = 'swap' +for p in ex.fetch_positions(): + c = float(p.get('contracts',0)) + if abs(c) > 0.001: + sym = p.get('symbol','?').replace('/USDT:USDT','') + side = '多' if p['side']=='long' else '空' + entry = float(p.get('entryPrice',0)) + upl = float(p.get('unrealizedPnl',0)) + liq = p.get('liquidationPrice') or 0 + print(f'{sym}: {c}张 {side} entry={entry:.4f} upl={upl:+.4f} liq={liq}') +PYEOF +proxychains4 -f ~/.proxychains/proxychains.conf python3 /tmp/check_okx.py | grep -v proxychains + +# === 长桥 持仓 === +LONGBRIDGE_HTTP_URL=https://openapi.longbridge.com LONGBRIDGE_REGION=ap LONGBRIDGE_TRADE_ENABLED=true \ + proxychains4 -f ~/.proxychains/proxychains.conf \ + ~/.local/bin/longbridge --profile lb_real positions --json | head -30 +``` + +**注意事项**: +- ❌ 不要问 "你想查 OKX 还是长桥?" (用户没指定 = 查两个) +- ❌ 不要"先告知再确认查询" (直接执行) +- ✅ 一次性输出 OKX + 长桥 全部 +- ✅ 表格格式清晰,含方向、均价、浮盈、强平价 +- ✅ 缓存到 `~/.cache/holdings_latest.json`,5 分钟内不重查 + +--- + +## 🆕 v4.5.1 假阳性成功推送修复 (2026-07-10) + +**问题**: cron 推送 `📊 HK 1810.HK 现价 25.28 ✅ 下单成功: 1260056765857271808`,实际查询 orders --json 发现 status=Rejected. 用户原话: "这个没成功,不要乱发. 被拒绝了." + +**根因**: `hk_intraday_cli.py` / `us_intraday_cli.py` 推送逻辑直接读 `execute_order()` 返回的 order_id,就把 `❌ 下单失败` 改成 `✅ 下单成功:{id}`,**没反查订单实际 status**. stdout 有 order_id 只代表"已发请求",不代表"已成交". + +**新规 (覆盖之前推送逻辑)**: +1. `submit_order` / `execute_order` 返回后,必须反查订单实际 status (`fetch_order(order_id)` 或 `fetch_open_orders()`) +2. 只有 `status == 'closed'` 或 `'filled'` 才推 "✅ 下单成功" +3. `status == 'Rejected'` 推 "❌ 下单被拒: {id} (查长桥 App 或 `orders --json`)" +4. `status == 'NotReported'` 推 "⏳ 已提交: {id} (等成交, 港股日内单收盘自动作废)" +5. `status == 'Canceled'` 推 "🚫 已撤: {id}" +6. **没反查前, 推送只能说"已提交 {id}, 待确认", 不能说"成功"** + +**实施位置**: `~/.hermes/scripts/hk_intraday_cli.py` 和 `us_intraday_cli.py` 的 submit_order 调用后,加 status 反查: +```python +resp = openapi.submit_order(...) +order_id = resp.order_id +# 立即反查 +status = check_order_status(order_id, symbol) # 新函数,在 longbridge_cli_helper.py 加 +if status == 'closed' or status == 'filled': + push(f"✅ {symbol} 下单成功 @ {price}, 订单 {id}") +elif status == 'Rejected': + push(f"❌ {symbol} 下单被拒 (id={id}), 查 CLI: orders --json") +elif status == 'NotReported': + push(f"⏳ {symbol} 已提交 {id}, 等成交 (港股日内单收盘自动作废)") +else: + push(f"⚠️ {symbol} 订单 {id} 状态: {status}") +``` + +**同样适用于 longbridge-cli 推送**: 任何订单推送前先 `orders --json | grep {id}` 验证 status. + +**测试方法**: +```bash +# 1. 提交订单 +ORD=$(longbridge buy 9988.HK --qty 1 --price 100 -y 2>&1 | grep -oE '[0-9]{19}') +echo "Order: $ORD" +# 2. 反查 status +longbridge orders --json | python3 -c "import json,sys; d=json.load(sys.stdin); [print(o) for o in d if o['order_id']=='$ORD']" +# 3. 推送前必须先看 status +``` + +**绝对禁止**: 看 stdout 有 order_id 就推 ✅ 下单成功 —— stdout 只代表"已发请求",不代表"已成交" + ## 🆕 v4.5.0 重大更新 (2026-07-09) -### 1. 只设止损不设止盈 +### 1. 只设止损不设止盈 (OKX 专属,长桥端跳过) **原因**: advisor 算出的止盈位通常太远(SMA3 等于 TP = 4-5 个 ATR),实际很少触发,反而占用保证金。 -**新规**: +**新规** (仅 OKX): - advisor.execute 步骤改成 `sl_only`(原 OCO → 改 `conditional` 单腿) - 只挂 `slTriggerPx` (市价止损单) - 不挂 `tpTriggerPx` - 靠**平仓信号**触发市价平仓,而不是自动止盈 -**实现位置**: `scripts/okx_position_advisor.py:489-552` +**实现位置**: `scripts/okx_position_advisor.py:489-552`,带 `is_okx` 分支: +```python +is_okx = 'OKX' in str(type(exchange)) +if not is_okx: + # longbridge: skip SL, rely on time_in_force=Day auto-close + results['steps'].append({'step': 'sl_only', 'status': 'skipped', + 'msg': 'longbridge 不支持 algo order, 靠 time_in_force=Day 自动平仓'}) +else: + # OKX: set single-leg SL conditional algo (real implementation) + ... +``` + +**为什么 longbridge 跳过**: LongPort OpenAPI 完全没有 `submit_algo_order` / `submit_conditional_order` 端点, SDK 和 CLI 都不支持. 详见 `longbridge-cli/references/longbridge-algo-order-not-supported.md`. 这个 skill (okx-auto-position) **只对 OKX 生效**, longbridge 端请用 `longbridge-cli` skill. + +### 1.1 长桥端的做T出场策略 (互补) + +由于长桥不支持 algo order,做T出场必须**手动/CLI下 sell 限价单**: +- 入场: `longbridge buy SYM --qty N --price P -y` (配合 `adjust_price_for_order()` 自动 adjust 9 档) +- 出场: `longbridge sell SYM --qty N --price P2 -y` (用户看到信号后手动挂) +- 兜底: 收盘 16:00 自动作废日内单 (time_in_force=Day) + +**关键**: 出场卖单也要用 `adjust_price_for_order(symbol, price, 'sell')` 拿 bid1 避免 9 档 Reject。**实战教训**: `1810.HK 1000股 long @ 25.64` → 想挂 sell @ 25.80 (赚 0.6%) → Rejected! 25.80 高于 ask1 太多。改用 bid1 (立即吃买1档) 才不 reject。 + +**长桥端**永远不期望 "✅ SL 设置成功" 推送——advisor 会显示 `step: sl_only, status: skipped`, 那是预期行为,不是错误。 ### 2. 平仓信号自动跟单 (无 Y/N) @@ -168,11 +407,48 @@ python3 ~/.hermes/skills/trading/okx-auto-position/scripts/okx_position_advisor. **边界情况**: - 没有 `⏱信号时间` 字段的旧信号源 → 按"新鲜"处理(不阻断) -- Forwarder 没重启配置不生效 → 用 `docker exec telegram-forwarder python3 -c "import sqlite3; ..."` 查 +- Forwarder 没重启配置不生效 → 用 `docker exec telegram-forwarder python3 -c \"import sqlite3; ...\"` 查 - 30 分钟前整点 (`age == 30`) 算过期(少误跟) **回滚**:把 `forward_rules.is_original_time` 改回 0 + `process_signal.py` 删除过期分支 +--- + +## 🆕 v4.5.3 平仓信号 raw REST 自动跟平(2026-07-13 上线) + +**痛点**:v4.3.0 SKILL.md 已规定"平仓信号同方向持仓 → 市价全平 reduceOnly",但 process_signal.py 一直没实现这条规则,只推提醒让用户手动操作。**实战翻车**:2026-07-13 12:17 风寻 SKHY 平仓信号到达时,你手上有 2.89 张 SKHY 空单,process_signal 只推了提醒,没平仓——你 14:33 才发现手动平了,损失了 2 小时窗口。 + +**修复内容**: +1. `process_signal.py` 新增 `_okx_raw_request()` 和 `close_position_raw()` 两个函数 +2. `signal_type == 'close'` 分支改为:调 raw REST 查持仓 → 同方向 → 市价全平 reduceOnly → 推结果 +3. 反向持仓 → 推"⏭️ 方向错位,不动"(让用户决定是否反向平) +4. 无持仓 → 推"ℹ️ 无持仓可平" + +**raw REST 签名坑**(v4.5.3 修复): +- ✅ GET 签名 = `ts + GET + path + '?' + query_dict_sorted` +- ✅ POST 签名 = `ts + POST + path + json.dumps(body)` +- ❌ 旧版:query 没用 `?` 前缀 → 一直 `Invalid Sign` + +**fetch 顺序**(避免 race condition): +1. GET `/api/v5/account/positions?instId=X-USDT-SWAP` 拿当前持仓 +2. 方向校验(同/反/无) +3. GET `/api/v5/market/ticker?instId=X-USDT-SWAP` 拿最新价(仅展示用) +4. POST `/api/v5/trade/order` 下 reduceOnly 市价单 + +**推送格式(精简版 - v4.5.2 禁止过度分析)**: +``` +✅ SKHY 做空 🟥 5x 已市价全平 | 风寻实盘 + +short 2.89张 | 浮盈 +3.45 USDT 🔥 +``` + +**已知限制**: +- 实测只有"无持仓"返回 `none`;有仓场景已用 mock 验证(同向 closed, 反向 skip),未端到端跑真实平仓(避免影响真仓) +- `reduceOnly=True` 防止误开反向仓 +- `tdMode=cross, posSide=net` 假设你在 net_mode;若账户是 long_short_mode 需要改 posSide + +**回滚**:process_signal.py 旧 close 分支的"仅推提醒"逻辑在 git 里,恢复即可 + ## 无效信号识别(2026-07-08 实战确认) **无效信号格式**(脚本模拟/补推,不是真实交易员推送): @@ -246,9 +522,9 @@ memory-check 任务用 agent 模式(需要调模型)会被 provider rate lim 长桥 CLI 走 token masking 问题时,除 SDK 外还有第二条路: `--profile ` 加载 `~/.lb_.env` 文件,绕开 terminal secret-masking: ```bash cat > ~/.lb_real.env << EOF -LONGBRIDGE_APP_KEY=$(grep -oP 'LONGPORT_APP_KEY=\K\S+' ~/.bashrc) -LONGBRIDGE_APP_SECRET=$(grep -oP 'LONGPORT_APP_SECRET=\K\S+' ~/.bashrc) -LONGBRIDGE_ACCESS_TOKEN=$(grep -oP 'LONGPORT_ACCESS_TOKEN=\K\S+' ~/.bashrc) +LONGBRIDGE_APP_KEY=$(grep -oP 'LONGPORT_APP_KEY=\\K\\S+' ~/.bashrc) +LONGBRIDGE_APP_SECRET=$(grep -oP 'LONGPORT_APP_SECRET=\\K\\S+' ~/.bashrc) +LONGBRIDGE_ACCESS_TOKEN=$(grep -oP 'LONGPORT_ACCESS_TOKEN=\\K\\S+' ~/.bashrc) LONGBRIDGE_TRADE_ENABLED=true EOF ~/.local/bin/longbridge --profile lb_real buy RGTI.US --qty 15 --price 15.50 -y @@ -259,6 +535,47 @@ EOF --- +**🔴 [2026-07-13 v4.5.4 新坑] SPCX-USDT-SWAP 自动下单静默失败 (实战确认 2次)**: + +**症状**: advisor `--execute` 返回完整 JSON(contracts/margin/tp_price/sl_price 等),看起来一切正常。agent 查持仓发现**根本没持仓**,availBal/frozenBal 都没变化。 + +**根因 (推测)**: OKX 对 SPCX-USDT-SWAP 这种小币种合约的下单 API 有特殊校验(advisor 默认走 ccxt `create_market_sell_order`,可能 size/合约面值/最小变动单位有兼容问题)。advisor 的 stdout 显示推荐成功,但下单步骤失败被吞掉。 + +**实战复现**: +- 2026-07-13 熬鹰 SPCX short 新开仓 → advisor 推 1.45张 → execute 返回 JSON → 持仓 0 +- 2026-07-13 熬鹰 SPCX long 新开仓 → advisor 推 3.5张 → execute 返回 JSON → 持仓 0 + +**强制处理流程**: +1. advisor --execute 后,**立即 raw REST 查 `/api/v5/account/positions`** 和 `/api/v5/account/balance` 的 `frozenBal` +2. 若对应币种持仓仍为 0 AND `frozenBal` 未变化 → **静默失败** +3. 静默失败处理: + - 立即 raw REST 手动下市价单 (`POST /api/v5/trade/order`, `tdMode=cross`, `posSide=net`, `reduceOnly=False`) + - 手动用 advisor 算出的 `contracts` 和 `price` 下单 + - 推QQ: "⚠️ advisor 静默失败,已 raw REST 手动下单 X 张 @ ~$Y" +4. 若 raw REST 也失败 → 推QQ: "❌ SPCX 下单失败(advisor + raw REST 双失败),需要手动查 OKX App" + +**已知易触发币种**: SPCX(已确认 2 次)。其他小币种永续合约(SKHY/SNDK/MU 等)若也出现,加入此清单。 + +**详细复现脚本与手动 raw REST fallback 模板**: `references/spcx-silent-fail-repro.md` +**杠杆丢失 bug 3 次实战复现**: `references/leverage-pass-through-bug.md` + +--- + +**🔴 [2026-07-13 v4.5.4 新规] 连发信号仓位噪声过滤 (实战确认)**: + +**场景**: 熬鹰 SPCX 连发 6+ 条"减仓"信号,仓位从 16482 → 15164 → 13951 → 12835 → 11306 → 11304 → 10268,后 5 条变化都在 -0.01% 到 -9% 之间,**最后两条变化 -0.01% / -0.02% 完全是无意义的持仓快照同步**,挤占 process_signal 处理能力,推一堆重复推送给QQ。 + +**规则**: +- 信号间仓位变化 `< 1%` → 视为"持仓快照同步",**process_signal 可直接 dedup,无需 advisor + 推送** +- 仓位变化 `1% ~ 5%` → 推送但省略📐性价比区块,只简单报"加减 X 张" +- 仓位变化 `> 5%` → 完整处理(advisor + 📐 + 持仓表格) + +**实现位置**: `process_signal.py` 的 `is_duplicate()` 之前加一个早返回分支,对比 `signal_tracker.py history` 的上一条仓位,变化 < 1% 直接返回 "⏭️ 噪声信号,跳过"。 + +**实战价值**: 减少 50%+ 的无意义推送,让用户QQ更清净。 + +--- + 根据账户余额自动计算开仓数量、止盈止损位,用户确认后一键下单。 -(下略 — 保留原 v4.2.4 全部内容) \ No newline at end of file +(下略 — 保留原 v4.2.4 全部内容)