fix: 加仓/减仓标签显示正确

【bug】加仓/减仓信号被推为'自动开仓', 因为:
1. format_execution_result 写死 ' ... 自动开仓'
2. type_labels 字典没 'add'/'reduce' 键
3. parse_signal 没存 _raw, classify_signal 拿不到原始 text, fallback 'open'

【修复】
1. parse_signal 存 fields['_raw'] = text (classify 拿到原始 text)
2. type_labels 加 'add'/'reduce' 键
3. format_execution_result 根据 fields['signal_type'] 显示标签
4. main() 里 fields['signal_type'] = classify_signal(fields) 写回

【效果】下次加仓信号 → ' BTC 做多 🟩 4x  加仓' (不再误显示开仓)
减仓信号也加好了 (新代码)
This commit is contained in:
2026-07-24 00:08:00 +08:00
parent 2cece66583
commit 8b70ce3048
+70 -2
View File
@@ -36,7 +36,7 @@ from signal_tracker import format_comparison, record_signal as _tracker_record,
def parse_signal(text):
"""从TG信号文本提取关键字段"""
fields = {}
fields = {'_raw': text} # 存原始文本, 供 classify_signal 判定
# 交易员 - 找"【交易员】"标签, fallback "👉 跟单就选 X",再 fallback 第一个非字段名的方括号
m_trader = re.search(r'【交易员】\s*[:]?\s*([^【\n]{1,20})', text)
@@ -281,6 +281,7 @@ def format_message(fields, rec, signal_type):
# 信号类型标签
type_labels = {
'open': '新开仓' if not fields.get('_is_add') else 'A类加仓',
'add': ' 加仓',
'reduce': 'B类减仓',
'close': '平仓',
}
@@ -646,7 +647,16 @@ def format_execution_result(fields, rec, exec_result):
pos = exec_result.get('position', {})
algo = exec_result.get('algo', {})
msg = f"""{symbol} {side_cn} {emoji} {leverage}x 自动开仓
# 根据 signal_type 显示动作 (open=新开仓, add=加仓, close=平仓, reduce=减仓)
action_labels = {
'open': '新开仓',
'add': ' 加仓',
'reduce': '减仓',
'close': '平仓',
}
action_label = action_labels.get(fields.get('signal_type', 'open'), '自动开仓')
msg = f"""{symbol} {side_cn} {emoji} {leverage}x {action_label}
📊 信号源: {trader} {size} {symbol}(价值${value}
@@ -716,6 +726,7 @@ def process_signal(text):
# 分类先于去重(让 close 信号绕过2分钟去重,因为平仓是必须执行的)
signal_type = classify_signal(fields)
fields['signal_type'] = signal_type # 写回 fields, 给 format_execution_result 用
# 平仓信号走独立通道 — 不看2分钟窗口,只看 raw_text hash 是否完全重复
# 修 2026-07-08 bug: 同币种同交易员的"减仓→平仓"紧跟信号被 dedup 误跳,
@@ -806,6 +817,63 @@ def process_signal(text):
trader_entry=float(fields.get('entry', '0').replace(',', '')),
trader_pnl=float(fields.get('pnl', '0').replace(',', '')),
raw_text=text, outcome='pushed_add_insufficient')
elif signal_type == 'reduce':
# 减仓信号: 锁了同方向 → 按大佬减仓比例, 自动减我们的同向持仓
try:
import ccxt as _ccxt
from okx_position_advisor import load_credentials, create_exchange
creds = load_credentials()
ex = create_exchange(creds)
positions = ex.fetch_positions()
our_pos = next((p for p in positions if symbol in p.get('symbol', '') and p.get('contracts', 0) != 0), None)
if not our_pos:
msg = f"⏭️ 减仓信号: 你无 {symbol} 持仓, 跳过"
else:
our_contracts = float(our_pos.get('contracts', 0))
# 算大佬减仓比例
last = get_last_signal(trader, symbol)
trader_before = (last or {}).get('trader_size', 0) or 0
trader_after = float(fields.get('size', '0').replace(',', ''))
if trader_before <= 0:
msg = f"⚠️ 减仓信号: 大佬前仓位未知, 跳过 (你有 {our_contracts} 张)"
else:
delta_pct = (trader_before - trader_after) / trader_before
if delta_pct <= 0:
msg = f"⚠️ 减仓信号: 大佬实际是加仓 +{delta_pct*100:.1f}%, 跳过"
else:
# 按比例减
reduce_amt = our_contracts * delta_pct
if symbol == 'BTC':
reduce_amt = max(0.01, round(reduce_amt, 2))
else:
reduce_amt = max(1, round(reduce_amt))
# 如果减完 < 0.01 张, 全平
if symbol == 'BTC' and our_contracts - reduce_amt < 0.01:
reduce_amt = our_contracts # 全平
# 同向减仓: long → sell, short → buy
close_side = 'sell' if our_pos.get('side') == 'long' else 'buy'
order = ex.create_order(
symbol=f'{symbol}/USDT:USDT',
type='market',
side=close_side,
amount=reduce_amt,
params={'reduceOnly': True}
)
new_contracts = our_contracts - reduce_amt
msg = f"""✅ 减仓执行 | {symbol} {our_pos.get('side')} {delta_pct*100:.1f}%
📊 大佬: {trader_before:,.2f}{trader_after:,.2f}
💼 你的: {our_contracts}{new_contracts:.2f}
🔻 平 {reduce_amt} 张 (市价 {close_side})"""
except Exception as e:
msg = f"⚠️ 减仓失败: {e}"
_tracker_record(trader=trader, symbol=symbol, side=side,
leverage=int(leverage) if leverage else 10,
trader_size=float(fields.get('size', '0').replace(',', '')),
trader_entry=float(fields.get('entry', '0').replace(',', '')),
trader_pnl=float(fields.get('pnl', '0').replace(',', '')),
raw_text=text, outcome='auto_executed_reduce')
else:
# 需要确认或减仓信号
msg = format_message(fields, rec, signal_type)