From dbf76fe385741607acc1d8651f5287a31a18f557 Mon Sep 17 00:00:00 2001 From: ddrwode Date: Fri, 30 Jan 2026 01:01:07 +0800 Subject: [PATCH] hahaa --- me/bitmart-三分之一策略交易.py | 52 ++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/me/bitmart-三分之一策略交易.py b/me/bitmart-三分之一策略交易.py index f44b15d..573995d 100644 --- a/me/bitmart-三分之一策略交易.py +++ b/me/bitmart-三分之一策略交易.py @@ -14,7 +14,7 @@ BitMart 三分之一回归策略交易(双向触发版) 3. 执行逻辑: - 做多时遇到做空信号 -> 平多并反手开空 - 做空时遇到做多信号 -> 平空并反手开多 - - 同一根K线内只交易一次,防止频繁反手 + - 同一根K线内:若先开空后价格回调到「做多触发价」(开仓价+上一根实体/3),则平空开多;反之先开多后跌到做空触发价则平多开空。同一根K线内仅允许一次反手,防止频繁来回开仓。 示例1(阳线): 前一根K线:开盘3000,收盘3100(阳线,实体=100) @@ -554,21 +554,27 @@ class BitmartOneThirdStrategy: if direction: curr_kline_id = curr_kline['id'] - # 检查是否在同一K线内已经交易过(防止频繁反手) - if self.last_trade_kline_id == curr_kline_id: - logger.debug(f"同一K线内已交易,跳过本次{direction}信号") - # 更新触发记录,避免重复日志 - self.last_trigger_kline_id = curr_kline_id - self.last_trigger_direction = direction - time.sleep(self.check_interval) - continue - - # 获取持仓状态 + # 获取持仓状态(先获取,用于判断是否允许同一K线内反手) if not self.get_position_status(): logger.warning("获取仓位信息失败") time.sleep(self.check_interval) continue + # 检查是否在同一K线内已经交易过(防止频繁反手) + # 例外(同一根K线内仅允许一次反手): + # - 先开空 -> 价格回调到做多触发价 -> 允许平空开多 + # - 先开多 -> 价格跌到做空触发价 -> 允许平多开空 + if self.last_trade_kline_id == curr_kline_id: + allow_reverse = (self.start == -1 and direction == "long") or (self.start == 1 and direction == "short") + if not allow_reverse: + logger.debug(f"同一K线内已交易且非反手场景,跳过本次{direction}信号") + self.last_trigger_kline_id = curr_kline_id + self.last_trigger_direction = direction + time.sleep(self.check_interval) + continue + action_desc = "平空开多" if (self.start == -1 and direction == "long") else "平多开空" + logger.info(f"同一K线内回调/反弹触发反手:当前持仓{'空' if self.start == -1 else '多'},信号{direction} -> {action_desc}") + prev_time = datetime.datetime.fromtimestamp(valid_prev['id']).strftime('%H:%M') prev_type = "阳线" if self.is_bullish(valid_prev) else "阴线" prev_body = self.get_body_size(valid_prev) @@ -581,6 +587,18 @@ class BitmartOneThirdStrategy: time.sleep(self.check_interval) continue + # 开仓原因(用于日志:多久、为什么开仓) + is_same_kline_reverse = (self.last_trade_kline_id == curr_kline_id) + if is_same_kline_reverse and direction == "long": + open_reason = f"同一根K线内价格回调到做多触发价 {trigger_price:.2f}(前一根[{prev_time}]{prev_type} 实体={prev_body:.2f}),平空反手开多" + elif is_same_kline_reverse and direction == "short": + open_reason = f"同一根K线内价格跌到做空触发价 {trigger_price:.2f}(前一根[{prev_time}]{prev_type} 实体={prev_body:.2f}),平多反手开空" + elif direction == "long": + open_reason = f"当前K线最高价触达做多触发价 {trigger_price:.2f}(前一根[{prev_time}]{prev_type} 实体={prev_body:.2f} 收盘={valid_prev['close']:.2f})" + else: + open_reason = f"当前K线最低价触达做空触发价 {trigger_price:.2f}(前一根[{prev_time}]{prev_type} 实体={prev_body:.2f} 收盘={valid_prev['close']:.2f})" + open_time_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + logger.info(f"{'=' * 50}") logger.info(f"🚨 检测到{direction}信号!触发价格: {trigger_price:.2f}") logger.info( @@ -588,6 +606,8 @@ class BitmartOneThirdStrategy: logger.info( f" 当前K线: H={curr_kline['high']:.2f} L={curr_kline['low']:.2f} C={curr_kline['close']:.2f}") logger.info(f" 当前持仓: {self.start} (1=多, -1=空, 0=无)") + logger.info(f" 开仓时间: {open_time_str}") + logger.info(f" 开仓原因: {open_reason}") # ========== 执行交易逻辑 ========== balance = self.get_available_balance() @@ -598,25 +618,25 @@ class BitmartOneThirdStrategy: executed = False if direction == "long": if self.start == -1: # 当前空仓,平空开多 - logger.info("📈 平空仓,反手开多") + logger.info(f"📈 平空仓,反手开多 | {open_time_str} | {open_reason}") self.平仓() time.sleep(1) self.开单(marketPriceLongOrder=1, size=trade_size) executed = True elif self.start == 0: # 当前无仓,直接开多 - logger.info("📈 无仓位,开多") + logger.info(f"📈 无仓位,开多 | {open_time_str} | {open_reason}") self.开单(marketPriceLongOrder=1, size=trade_size) executed = True elif direction == "short": if self.start == 1: # 当前多仓,平多开空 - logger.info("📉 平多仓,反手开空") + logger.info(f"📉 平多仓,反手开空 | {open_time_str} | {open_reason}") self.平仓() time.sleep(1) self.开单(marketPriceLongOrder=-1, size=trade_size) executed = True elif self.start == 0: # 当前无仓,直接开空 - logger.info("📉 无仓位,开空") + logger.info(f"📉 无仓位,开空 | {open_time_str} | {open_reason}") self.开单(marketPriceLongOrder=-1, size=trade_size) executed = True @@ -627,6 +647,8 @@ class BitmartOneThirdStrategy: if executed: # 记录交易K线,防止同一K线内频繁反手 self.last_trade_kline_id = curr_kline_id + # 发送开仓时间与原因到钉钉 + self.ding(msg=f"开仓时间: {open_time_str}\n开仓原因: {open_reason}") # 交易后立即发送持仓信息 self.get_position_status() self._send_position_message(curr_kline)