Files
Hermes-Skills/okx-auto-position/references/parse-signal-trader-and-price-pitfall.md
T

84 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: parse-signal-trader-and-price-pitfall
description: "trader 解析 fallback + 价格格式化 (避免 18 位小数和"币种"误标)"
version: 1.0.0
type: reference
---
# ⚠️ process_signal.py: trader 解析 + 价格格式化 实战教训
## Bug 1: `trader` 字段错误 = "币种"
**症状**: 推送里显示 `信号源: 币种 ? SKHY (价值$?)` — trader 字段名是 "币种",不是真 trader。
**根因**: `parse_signal` L41 用 `re.search(r'【([^】]+)】', text)` 抓**第一个**方括号 — 第一个就是 `【币种】...`,导致 trader = "币种"。
**真实 trader** 通常不是 `【X】` 格式,而是 **`👉 跟单就选 X聚合社区`**(在信号末尾)。
### 修复方案 (3 层 fallback)
```python
FIELD_NAMES = {'币种', '方向', '杠杆', '仓位大小', '仓位价值', '开仓价',
'当前价', '未实现盈亏', '收益额', '持仓量', '强平价', '数量'}
# 1. 优先: 【交易员】标签
m_trader = re.search(r'【交易员】\s*[:]?\s*([^【\n]{1,20})', text)
if m_trader:
fields['trader'] = m_trader.group(1).strip()
else:
# 2. Fallback: 👉 跟单就选 X (真实 trader 来源)
m_follow = re.search(r'👉\s*跟单就选\s*(\S+)', text)
if m_follow:
fields['trader'] = m_follow.group(1).strip()
else:
# 3. 最终 fallback: 第一个【xx】但跳过字段名
m_first = re.search(r'【([^】]{1,20})】', text)
if m_first and m_first.group(1) not in FIELD_NAMES:
fields['trader'] = m_first.group(1).strip()
else:
fields['trader'] = 'unknown'
```
### 测试用例
```python
signal = """📈 注意
【币种】: SKHYUSDT|永续|5x
【方向】: 做空 🟥
【仓位】: 528.16 SKHY
【开仓价】: 161.90000
👉 跟单就选 X聚合社区"""
parse_signal(signal)['trader'] # ✅ "X聚合社区" (不再是 "币种")
```
## Bug 2: 价格小数位溢出 (18 位)
**症状**: `入场: $161.01076124567473` — OKX 返回的浮点 × 比率算出 18 位小数。
**根因**: f-string 直接嵌入 float,没有 round。
### 修复: 通用 _fmt() helper
```python
def _fmt(x, n=4):
"""格式化数字: 字符串保留原样, 数字 round 到 n 位."""
try:
return f"{float(x):.{n}f}"
except (ValueError, TypeError):
return str(x)
# 模板里全部用 _fmt()
msg = f"""⚡ 跟单建议 ...
入场: ${_fmt(entry_price)} | 当前: ${_fmt(current)}
• SL: ${_fmt(rec['sl_price'])} → 预亏 -{_fmt(rec.get('sl_pnl', 0))} USDT
"""
```
⚠️ **`value` 缺失**: OKX 信号有时价值字段空 (e.g. `价值 $?`),`_fmt` 不能 float('?') 抛异常,**保留 `?`** — 让推送显示 "?" 但不报错。
## 相关
- `process_signal.py` L36-67 (parse_signal)
- `process_signal.py` L217-302 (format_message)
- 测试: `python3 -c "import process_signal; process_signal.parse_signal(s)"`