From 7df054f638b88d5b55134188ae6b4d766df2e69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Sat, 14 Feb 2026 23:39:19 +0800 Subject: [PATCH] 1 --- BINANCE_IP_BAN_1003.md | 11 +++ docs/交易表现分析_20260214.md | 109 ++++++++++++++++++++++++++++ trading_system/binance_client.py | 31 ++++++-- trading_system/position_manager.py | 3 +- 4 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 docs/交易表现分析_20260214.md diff --git a/BINANCE_IP_BAN_1003.md b/BINANCE_IP_BAN_1003.md index 930dc82..ec3108e 100644 --- a/BINANCE_IP_BAN_1003.md +++ b/BINANCE_IP_BAN_1003.md @@ -37,3 +37,14 @@ else: 4. **错误提示**:日志里「分析超时(10秒)」多是因为当时已被限频/封禁导致请求挂起或失败,解封后一般会恢复。 解封后若仍偶发 -1003,可先等 1~2 分钟再跑,或临时增大 `SCAN_INTERVAL` 再观察。 + +--- + +## 获取持仓/成交超时(TimeoutError) + +若日志出现「获取持仓信息最终失败 (已重试 7 次): TimeoutError」或「获取成交记录失败 XXX (已重试 5 次): TimeoutError」: + +1. **网络/限频**:与 -1003 类似,可能是当时网络抖动或请求排队,重试已用 60 秒超时 × 多轮;过几分钟通常恢复。 +2. **适当拉长只读超时**(可选):在运行交易进程的环境里设置环境变量 + `READ_ONLY_REQUEST_TIMEOUT=90`(默认 60 秒),只读接口(持仓、成交、交易对信息)单次等待时间会变长,**不影响下单/止损止盈的快速失败**。 +3. **本次已做**:获取交易对信息(如 ENAUSDT)增加 60 秒超时 + 3 次重试;获取成交记录后几次重试间隔改为 2 秒;开仓失败时会打出完整异常与堆栈,便于排查。 diff --git a/docs/交易表现分析_20260214.md b/docs/交易表现分析_20260214.md new file mode 100644 index 0000000..43982b0 --- /dev/null +++ b/docs/交易表现分析_20260214.md @@ -0,0 +1,109 @@ +# 交易表现分析 2026-02-14 + +## 一、数据概览 + +### 1. 20 点之后入场且已平仓(晚间段) +- **14 笔**,总盈亏 **-1.91 USDT**,胜率 **28.6%**(4 盈 8 亏 2 平) +- 平仓类型:自动止损 5 笔(-2.01)、同步平仓 4 笔(-0.75)、手动平仓 4 笔(+1.03)、移动止损 1 笔(-0.17) +- **特征**:20:00~20:28 集中开仓,多为「MACD金叉 + RSI超买 反向做空」;HYPEUSDT BUY 一笔 -1.31 止损(顺势多)。晚间段胜率、盈亏均差于全天,需单独关注。 + +### 2. 21 点之后平仓订单 +- **仅 1 笔**:XPLUSDT BUY,入场 22:17,自动止损,盈亏 **-0.26 USDT** +- 样本太少,与 20 点段合并为「晚间段」一起看改进即可。 + +### 3. 全量已平仓(96 笔) + +| 平仓类型 | 笔数 | 总盈亏 (USDT) | +|--------------------|------|----------------| +| 自动平仓(止损) | 32 | **-13.68** | +| 手动平仓 | 28 | +15.99 | +| 同步平仓 | 17 | -1.93 | +| 自动平仓(止盈) | 11 | -4.04 | +| 自动平仓(移动止损)| 8 | +3.48 | + +- **总盈亏**:约 +0.08 USDT(几乎打平) +- **胜率**:36.8%(BUY 36.4%,SELL 36.5%) +- **主要问题**:止损笔数多(32 笔)、亏损集中(-13.68);止盈 11 笔合计仍为负(-4.04),说明止盈单里存在“先盈后亏”或手续费侵蚀。 + +### 4. 当前持仓(持仓记录 16 个) +- **合计浮盈/亏**:**-5.46 USDT** +- 多数为 SELL,部分 BUY(HYPEUSDT、KITEUSDT、CLOUSDT)浮亏。 + +--- + +## 二、亏损单特征(入场原因 Top) + +1. **MACD死叉 + 价格在EMA20之下**(3 笔)—— 顺势做空在震荡/反弹里被扫。 +2. **RSI超买反向做空**(多笔,如 RSI 69.7~79.5 ≥65)—— “上升趋势 + RSI超买反空”在强趋势中容易连续止损。 +3. **sync_recovered**(2 笔)—— 补建仓后被动平仓,需确认是否为系统单、价格是否合理。 + +结论:**止损占比高、胜率偏低**,与“逆势/震荡中开仓”和“RSI 反向在趋势中触发”关联大。 + +--- + +## 三、可落地的改进建议 + +### 1. RSI 反向:只在 4H 中性时做(优先) +- **现状**:`RSI_EXTREME_REVERSE_ONLY_NEUTRAL_4H = False`,上升趋势里也会“RSI 超买反空”,易被趋势继续拉高打止损。 +- **建议**:改为 **True**,仅在 4H 为中性时允许 RSI 超买反空/超卖反多,减少趋势中逆势单。 +- **配置项**:全局配置 → 策略参数 → `RSI 反向仅允许 4H 中性` 设为 **是**。 + +### 2. 提高开仓信号门槛(减少低质量单) +- **现状**:`MIN_SIGNAL_STRENGTH = 8`,止损 32 笔说明仍有不少“可做可不做”的单子。 +- **建议**:提高到 **9**,只做最强信号,减少笔数、提高单笔质量。 +- **配置项**:全局配置 → `MIN_SIGNAL_STRENGTH` 设为 **9**。 + +### 3. 止损略放宽(给波动留空间) +- **现状**:`ATR_STOP_LOSS_MULTIPLIER = 3.0`,32 笔止损 -13.68 可能包含“刚打止损就反向”的噪音。 +- **建议**:试 **3.2 或 3.5**,单笔亏损略大但减少“被洗出”次数,观察 1~2 天胜率与总盈亏再微调。 +- **配置项**:全局配置 → 风险控制 → `ATR 止损倍数` 设为 **3.2** 或 **3.5**。 + +### 4. 止盈与第一目标(观察即可) +- 11 笔止盈总盈亏为负,可能原因:部分止盈后剩余仓位被止损、或手续费。建议先观察,若持续出现可再考虑: + - 略提高 `TAKE_PROFIT_1_PERCENT`(如 25%~30%),让更多单在“第一目标”就了结一部分利润; + - 或检查移动止损与止盈的衔接,避免“先触发移动止损再被扫”。 + +### 5. 同步平仓 17 笔 -1.93 +- 确认是否为“系统单 + 币安已平”的同步;若是,可接受。若包含非系统单误同步,需在同步逻辑里继续用 `SYSTEM_ORDER_ID_PREFIX` 等严格区分。 + +--- + +## 四、晚间段(20 点之后)改进方案 + +20 点之后 14 笔、胜率 28.6%、总盈亏 -1.91,明显弱于全天,可做**针对性收紧**: + +### 方案 A:通用收紧(优先,不改代码) +- 沿用第三节的 **RSI_EXTREME_REVERSE_ONLY_NEUTRAL_4H = True**、**MIN_SIGNAL_STRENGTH = 9**、**ATR_STOP_LOSS_MULTIPLIER = 3.2~3.5**。 +- 晚间大量是「RSI 超买反空」被扫,限制为 4H 中性才反向 + 只做强度 9+,会自然减少 20 点后的低质量开仓。 + +### 方案 B:晚间提高信号门槛(需加配置) +- 若希望**仅晚间更严**,可增加配置项,例如: + - `EVENING_HOURS_START` / `EVENING_HOURS_END`(如 20、24 表示 20:00~24:00 北京时间); + - `EVENING_MIN_SIGNAL_STRENGTH`(如 9 或 10):该时段内仅当信号强度 ≥ 该值才开仓。 +- 实现方式:在 `strategy.py` 开仓前根据当前北京时间是否落在晚间区间,动态用 `max(MIN_SIGNAL_STRENGTH, EVENING_MIN_SIGNAL_STRENGTH)` 做过滤。 +- 未加该配置前,用方案 A 即可。 + +### 方案 C:晚间少开或不开 RSI 反向(折中) +- 在现有「RSI 反向仅 4H 中性」基础上,若仍发现晚间 RSI 反向单亏损多,可再加一条:**20:00~24:00 不允许 RSI 反向开仓**(只做顺势单)。需在策略里按当前小时判断并跳过 RSI 反向逻辑。 + +**建议执行顺序**:先做 **方案 A**(三档全局参数),观察 1~2 天;若晚间段仍偏弱,再考虑加 **方案 B**(晚间信号门槛)或 **方案 C**(晚间关闭 RSI 反向)。 + +--- + +## 五、建议的配置调整汇总(可直接在全局配置里改) + +| 配置项 | 当前建议 | 说明 | +|--------|----------|------| +| RSI_EXTREME_REVERSE_ONLY_NEUTRAL_4H | **True** | 仅 4H 中性时 RSI 反向,减少趋势中摸顶/抄底 | +| MIN_SIGNAL_STRENGTH | **9** | 只做最强信号,减少止损笔数 | +| ATR_STOP_LOSS_MULTIPLIER | **3.2** 或 **3.5** | 略放宽止损,减少噪音止损 | + +改完后**清除全局缓存 + 重启所有账号交易**,让配置生效;观察 1~2 天再微调。 + +--- + +## 六、关于“晚间没有明显盈利” + +- **20 点之后** 14 笔、胜率 28.6%、总盈亏 -1.91,明显差于全天(36.8%、+0.08)。 +- 晚间集中出现「RSI 超买反向做空」+ 多笔同步平仓/止损,说明该时段要么少做、要么只做更高置信度信号。 +- 优先做 **第四节 方案 A**(RSI 仅 4H 中性 + 信号强度 9 + 止损 3.2~3.5),观察全时段与晚间是否一起改善;若晚间仍弱,再考虑 **方案 B(晚间信号门槛)** 或 **方案 C(晚间关闭 RSI 反向)**。 diff --git a/trading_system/binance_client.py b/trading_system/binance_client.py index db88143..0cd7235 100644 --- a/trading_system/binance_client.py +++ b/trading_system/binance_client.py @@ -865,8 +865,9 @@ class BinanceClient: isinstance(e, BinanceAPIException) and (e.code == -1021 or str(e.code).startswith('5')) ) if is_retryable and attempt < retries - 1: - logger.warning(f"获取成交记录失败 {symbol} (第 {attempt + 1}/{retries} 次): {_format_exception(e)},1秒后重试...") - await asyncio.sleep(1) + wait = 2 if attempt >= 2 else 1 # 后几次多等 1 秒,给网络恢复时间 + logger.warning(f"获取成交记录失败 {symbol} (第 {attempt + 1}/{retries} 次): {_format_exception(e)},{wait}秒后重试...") + await asyncio.sleep(wait) continue break except Exception as e: @@ -913,9 +914,29 @@ class BinanceClient: self._symbol_info_cache[symbol] = cached return cached - # 3. 缓存未命中,调用 API + # 3. 缓存未命中,调用 API(加超时与重试,避免网络抖动导致开仓前获取交易对信息失败) + read_timeout = getattr(config, 'READ_ONLY_REQUEST_TIMEOUT', 60) + last_err = None + for attempt in range(3): + try: + exchange_info = await asyncio.wait_for( + self.client.futures_exchange_info(), + timeout=read_timeout + ) + break + except (asyncio.TimeoutError, BinanceAPIException, OSError) as e: + last_err = e + if attempt < 2: + logger.warning(f"获取 exchange_info 失败 (第 {attempt + 1}/3 次): {_format_exception(e)},1秒后重试...") + await asyncio.sleep(1) + continue + logger.error(f"获取 {symbol} 交易对信息失败 (已重试 3 次): {_format_exception(e)}") + return None + except Exception as e: + logger.error(f"获取 {symbol} 交易对信息失败: {_format_exception(e)}") + return None + try: - exchange_info = await self.client.futures_exchange_info() for s in exchange_info['symbols']: if s['symbol'] == symbol: # 提取数量/价格精度信息 @@ -975,7 +996,7 @@ class BinanceClient: logger.warning(f"未找到交易对 {symbol} 的信息") return None except Exception as e: - logger.error(f"获取 {symbol} 交易对信息失败: {e}") + logger.error(f"获取 {symbol} 交易对信息失败: {_format_exception(e)}") return None def _adjust_quantity_precision(self, quantity: float, symbol_info: Dict) -> float: diff --git a/trading_system/position_manager.py b/trading_system/position_manager.py index f1e2003..ab24cff 100644 --- a/trading_system/position_manager.py +++ b/trading_system/position_manager.py @@ -805,7 +805,8 @@ class PositionManager: return None except Exception as e: - logger.error(f"开仓失败 {symbol}: {e}") + err_msg = str(e).strip() if str(e) else f"{type(e).__name__}(无详情)" + logger.error(f"开仓失败 {symbol}: {err_msg}", exc_info=True) return None async def close_position(self, symbol: str, reason: str = 'manual') -> bool: