From 644927145c7758f19e4c37c8b9bf8427c131e724 Mon Sep 17 00:00:00 2001 From: 27942 <1313123@342> Date: Sat, 7 Feb 2026 21:23:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../四分之一,五分钟,反手条件充足修改版.py | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/bitmart/四分之一,五分钟,反手条件充足修改版.py b/bitmart/四分之一,五分钟,反手条件充足修改版.py index 0ce5b52..1077a6c 100644 --- a/bitmart/四分之一,五分钟,反手条件充足修改版.py +++ b/bitmart/四分之一,五分钟,反手条件充足修改版.py @@ -41,7 +41,8 @@ class BitmartFuturesTransaction: self.bit_id = bit_id self.default_order_size = 25 # 开仓/反手张数,统一在此修改 - self.last_trade_kline_id = None # 上次开仓/平仓所在K线ID,同一根K线只允许开一笔仓位 + self.last_trade_kline_id = None # 上次新开仓所在K线ID,同一根K线只允许开一笔新仓(反手不受限) + self.accumulated_loss = 0 # 累计亏损:反手时上一笔亏损累加,移动止损激活阈值需覆盖此亏损 # 策略相关变量 self.prev_kline = None # 上一根K线 @@ -424,6 +425,7 @@ class BitmartFuturesTransaction: # 验证开仓是否成功 if self.verify_position_direction(1): self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录 + self.accumulated_loss = 0 # 新开仓重置累计亏损 logger.success("开多成功") return True else: @@ -447,6 +449,7 @@ class BitmartFuturesTransaction: # 验证开仓是否成功 if self.verify_position_direction(-1): self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录 + self.accumulated_loss = 0 # 新开仓重置累计亏损 logger.success("开空成功") return True else: @@ -456,6 +459,11 @@ class BitmartFuturesTransaction: elif signal_type == 'reverse_long': # 平空 + 开多(反手做多):先平仓,确认无仓后再开多,避免双向持仓 logger.info(f"执行反手做多,触发价: {trigger_price:.2f}") + # 反手前记录当前仓位的未实现盈亏,亏损则累加到 accumulated_loss + pre_reverse_pnl = self.get_unrealized_pnl_usd() + if pre_reverse_pnl is not None and pre_reverse_pnl < 0: + self.accumulated_loss += abs(pre_reverse_pnl) + logger.info(f"反手前亏损 {pre_reverse_pnl:.2f} 美元,累计亏损更新为 {self.accumulated_loss:.2f} 美元") self.平仓() time.sleep(1) # 给交易所处理平仓的时间 # 轮询确认已无持仓再开多(最多等约 10 秒) @@ -482,6 +490,11 @@ class BitmartFuturesTransaction: elif signal_type == 'reverse_short': # 平多 + 开空(反手做空):先平仓,确认无仓后再开空 logger.info(f"执行反手做空,触发价: {trigger_price:.2f}") + # 反手前记录当前仓位的未实现盈亏,亏损则累加到 accumulated_loss + pre_reverse_pnl = self.get_unrealized_pnl_usd() + if pre_reverse_pnl is not None and pre_reverse_pnl < 0: + self.accumulated_loss += abs(pre_reverse_pnl) + logger.info(f"反手前亏损 {pre_reverse_pnl:.2f} 美元,累计亏损更新为 {self.accumulated_loss:.2f} 美元") self.平仓() time.sleep(1) for _ in range(10): @@ -567,7 +580,7 @@ class BitmartFuturesTransaction: logger.debug(f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)") - # 3.5 止损/止盈/移动止损 + # 3.5 移动止损(激活阈值 = 基础阈值 + 累计亏损) if self.start != 0: pnl_usd = self.get_unrealized_pnl_usd() if pnl_usd is not None: @@ -576,23 +589,29 @@ class BitmartFuturesTransaction: self.max_unrealized_pnl_seen = pnl_usd else: self.max_unrealized_pnl_seen = max(self.max_unrealized_pnl_seen, pnl_usd) - # 移动止损:盈利曾达到 activation 后,从最高盈利回撤 trailing_distance 则平仓 - if self.max_unrealized_pnl_seen >= self.trailing_activation_usd: + # 移动止损激活阈值 = 基础阈值 + 累计亏损(需要先赚回之前反手的亏损) + effective_activation = self.trailing_activation_usd + self.accumulated_loss + if self.accumulated_loss > 0: + logger.debug(f"移动止损激活阈值: {self.trailing_activation_usd} + 累计亏损 {self.accumulated_loss:.2f} = {effective_activation:.2f} 美元") + # 移动止损:盈利曾达到 effective_activation 后,从最高盈利回撤 trailing_distance 则平仓 + if self.max_unrealized_pnl_seen >= effective_activation: if pnl_usd < self.max_unrealized_pnl_seen - self.trailing_distance_usd: - logger.info(f"移动止损:当前盈利 {pnl_usd:.2f} 从最高 {self.max_unrealized_pnl_seen:.2f} 回撤 >= {self.trailing_distance_usd} 美元,平仓") + logger.info(f"移动止损:当前盈利 {pnl_usd:.2f} 从最高 {self.max_unrealized_pnl_seen:.2f} 回撤 >= {self.trailing_distance_usd} 美元,平仓" + f"(激活阈值={effective_activation:.2f},含累计亏损 {self.accumulated_loss:.2f})") self.平仓() self.max_unrealized_pnl_seen = None + self.accumulated_loss = 0 # 止盈平仓后重置累计亏损 self.last_trade_kline_id = current_kline_time # 平仓后标记当前K线,下一根K线才能再开仓 - logger.info(f"平仓后标记K线({current_kline_time}),等待下一根K线再开仓") + logger.info(f"平仓后标记K线({current_kline_time}),等待下一根K线再开仓,累计亏损已重置") time.sleep(3) continue # 4. 检查信号 signal = self.check_signal(current_price, prev_kline, current_kline) - # 5. 同一根K线只允许开一笔仓位,平仓后等下一根K线再开仓 - if signal and self.last_trade_kline_id == current_kline_time: - logger.info(f"同一根K线({current_kline_time})已交易过,等待下一根K线") + # 5. 同一根K线只允许开一笔新仓位(反手不受限制) + if signal and signal[0] in ('long', 'short') and self.last_trade_kline_id == current_kline_time: + logger.info(f"同一根K线({current_kline_time})已开过新仓,等待下一根K线(反手不受此限制)") signal = None # 6. 有信号则执行交易