diff --git a/交易/bitmart-五分之一策略交易.py b/交易/bitmart-五分之一策略交易.py index ddeaf24..cc0b995 100644 --- a/交易/bitmart-五分之一策略交易.py +++ b/交易/bitmart-五分之一策略交易.py @@ -19,7 +19,7 @@ BitMart 五分之一回归策略交易(精准版) 4. 精准判断(使用1分钟K线): - 当当前3分钟K线同时触及做多和做空价格时,拉取该3分钟对应的3根1分钟K线判断哪个方向先被触发 """ - +import random import time import datetime from concurrent.futures import ThreadPoolExecutor @@ -158,10 +158,18 @@ class BitmartOneFifthStrategy: return 'short' if d_short < d_long else 'long' return None - def check_realtime_trigger(self, kline_data): + def check_realtime_trigger(self, kline_data, current_position=0): """ 实时检测当前3分钟K线是否触发信号 - 若多空都触发,优先用1分钟K线判断先后,否则用开盘价距离 + + 参数: + kline_data: K线数据列表 + current_position: 当前持仓状态 (1=多, -1=空, 0=无) + + 逻辑优化: + - 当已有持仓时,只关心反向信号(有多仓只看空信号,有空仓只看多信号) + - 无仓位时,用1分钟K线判断先触发的方向 + 返回:(方向, 触发价格, 有效前一根K线, 当前K线) 或 (None, None, None, None) """ if len(kline_data) < 2: @@ -187,25 +195,38 @@ class BitmartOneFifthStrategy: direction = None trigger_price = None - if long_triggered and short_triggered: - bars_1m = self.get_1m_bars_for_3m_bar(curr) - if bars_1m: - direction = self.determine_trigger_order_by_1m( - bars_1m, long_trigger, short_trigger - ) - trigger_price = long_trigger if direction == 'long' else short_trigger - if direction is None: - c_open = float(curr['open']) - d_long = abs(long_trigger - c_open) - d_short = abs(short_trigger - c_open) - direction = 'short' if d_short <= d_long else 'long' - trigger_price = long_trigger if direction == 'long' else short_trigger - elif short_triggered: - direction = 'short' - trigger_price = short_trigger - elif long_triggered: - direction = 'long' - trigger_price = long_trigger + # 关键优化:根据当前持仓状态决定关注哪个方向的信号 + if current_position == 1: + # 当前是多仓,只关心空信号(用于平多开空) + if short_triggered: + direction = 'short' + trigger_price = short_trigger + elif current_position == -1: + # 当前是空仓,只关心多信号(用于平空开多) + if long_triggered: + direction = 'long' + trigger_price = long_trigger + else: + # 无仓位,按原逻辑判断先触发的方向 + if long_triggered and short_triggered: + bars_1m = self.get_1m_bars_for_3m_bar(curr) + if bars_1m: + direction = self.determine_trigger_order_by_1m( + bars_1m, long_trigger, short_trigger + ) + trigger_price = long_trigger if direction == 'long' else short_trigger + if direction is None: + c_open = float(curr['open']) + d_long = abs(long_trigger - c_open) + d_short = abs(short_trigger - c_open) + direction = 'short' if d_short <= d_long else 'long' + trigger_price = long_trigger if direction == 'long' else short_trigger + elif short_triggered: + direction = 'short' + trigger_price = short_trigger + elif long_triggered: + direction = 'long' + trigger_price = long_trigger if direction is None: return None, None, None, None @@ -383,7 +404,7 @@ class BitmartOneFifthStrategy: """ prefix = "❌五分之一策略:" if error else "🔔五分之一策略:" full_msg = f"{prefix}{msg}" - + if error: logger.error(msg) # 异步发送多条错误消息 @@ -393,7 +414,7 @@ class BitmartOneFifthStrategy: logger.info(msg) # 异步发送单条消息 ding_executor.submit(self._send_ding_safe, full_msg) - + def _send_ding_safe(self, msg): """ 安全发送钉钉消息,捕获异常防止线程崩溃 @@ -449,7 +470,15 @@ class BitmartOneFifthStrategy: curr = kline_data[-1] curr_time_str = datetime.datetime.fromtimestamp(curr['id']).strftime('%H:%M:%S') - direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(kline_data) + + # 优化:先获取持仓状态,再检测信号(传入持仓状态以便只关注反向信号) + if not self.get_position_status(): + logger.warning("获取仓位信息失败,使用缓存的持仓状态") + + # 传入当前持仓状态,确保有持仓时只关注反向信号 + direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger( + kline_data, current_position=self.start + ) if direction: curr_kline_id = curr_kline['id'] @@ -458,16 +487,15 @@ class BitmartOneFifthStrategy: self.last_trigger_direction = direction time.sleep(self.check_interval) continue - if not self.get_position_status(): - logger.warning("获取仓位信息失败") - time.sleep(self.check_interval) - continue 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) + # 由于 check_realtime_trigger 已经考虑了持仓状态,这里理论上不会出现同向信号 + # 但保留这个检查作为安全措施 if (direction == "long" and self.start == 1) or (direction == "short" and self.start == -1): + logger.debug(f"同向信号被过滤: direction={direction}, position={self.start}") self.last_trigger_kline_id = curr_kline_id self.last_trigger_direction = direction time.sleep(self.check_interval) @@ -529,8 +557,10 @@ class BitmartOneFifthStrategy: except Exception as e: logger.error(f"主循环异常: {e}") time.sleep(self.check_interval) - time.sleep(15) - self.page.close() + time.sleep(5) + + if random.randint(1,10)>7: + self.page.close() time.sleep(15) def _send_position_message(self, latest_kline):