From fa48f70758228983a68952577064e50bf7e4ea78 Mon Sep 17 00:00:00 2001 From: ddrwode <34234@3来 34> Date: Fri, 20 Feb 2026 22:16:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=93=88=E5=93=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 111 | 1 + 四分之一,五分钟,反手条件充足.py | 57 ++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 111 diff --git a/111 b/111 new file mode 100644 index 0000000..f5624ae --- /dev/null +++ b/111 @@ -0,0 +1 @@ +1600 \ No newline at end of file diff --git a/四分之一,五分钟,反手条件充足.py b/四分之一,五分钟,反手条件充足.py index 58681b9..6675e5e 100644 --- a/四分之一,五分钟,反手条件充足.py +++ b/四分之一,五分钟,反手条件充足.py @@ -65,6 +65,14 @@ class BitmartFuturesTransaction: self.prev_entity = None # 上一根K线实体大小 self.current_open = None # 当前K线开盘价 + # API 节流:主循环与持仓/价格查询间隔,避免 429 Request too many requests + self.loop_interval_seconds = 2.5 # 每轮循环最少间隔(秒) + self._last_position_fetch = 0.0 + self._last_price_fetch = 0.0 + self._position_refresh_interval = 2.0 # 持仓/价格最少隔多久才重新请求(秒) + self._position_cache = None # 上次成功的持仓状态,用于节流时复用 + self._price_cache = None # 上次成功的价格,用于节流时复用 + def get_klines(self): """获取最近2根K线(当前K线和上一根K线)""" try: @@ -99,9 +107,12 @@ class BitmartFuturesTransaction: return None, None def get_current_price(self): - """获取当前最新价格""" + """获取当前最新价格(带节流:间隔内返回缓存值)""" + now = time.time() + if self._price_cache is not None and (now - self._last_price_fetch) < self._position_refresh_interval: + return self._price_cache try: - end_time = int(time.time()) + end_time = int(now) response = self.contractAPI.get_kline( contract_symbol=self.contract_symbol, step=1, # 1分钟 @@ -109,11 +120,14 @@ class BitmartFuturesTransaction: end_time=end_time )[0] if response['code'] == 1000: - return float(response['data'][-1]["close_price"]) - return None + price = float(response['data'][-1]["close_price"]) + self._price_cache = price + self._last_price_fetch = now + return price + return self._price_cache # 失败时用旧价格 except Exception as e: logger.error(f"获取价格异常: {e}") - return None + return self._price_cache def get_available_balance(self): """获取合约账户可用USDT余额""" @@ -133,7 +147,15 @@ class BitmartFuturesTransaction: return None def get_position_status(self): - """获取当前持仓方向""" + """获取当前持仓方向(带节流:间隔内返回缓存状态)""" + now = time.time() + if self._position_cache is not None and (now - self._last_position_fetch) < self._position_refresh_interval: + c = self._position_cache + self.start = c['start'] + self.open_avg_price = c.get('open_avg_price') + self.current_amount = c.get('current_amount') + self.unrealized_pnl = c.get('unrealized_pnl') + return True try: response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0] if response['code'] == 1000: @@ -143,21 +165,34 @@ class BitmartFuturesTransaction: self.open_avg_price = None self.current_amount = None self.unrealized_pnl = None + self._position_cache = {'start': 0, 'open_avg_price': None, 'current_amount': None, 'unrealized_pnl': None} + self._last_position_fetch = now return True pos = positions[0] self.start = 1 if pos['position_type'] == 1 else -1 self.open_avg_price = float(pos['open_avg_price']) self.current_amount = float(pos['current_amount']) self.position_cross = pos["position_cross"] - # 直接从API获取未实现盈亏(Bitmart返回的是 unrealized_value 字段) self.unrealized_pnl = float(pos.get('unrealized_value', 0)) + self._position_cache = {'start': self.start, 'open_avg_price': self.open_avg_price, 'current_amount': self.current_amount, 'unrealized_pnl': self.unrealized_pnl} + self._last_position_fetch = now logger.debug(f"持仓详情: 方向={self.start}, 开仓均价={self.open_avg_price}, " f"持仓量={self.current_amount}, 未实现盈亏={self.unrealized_pnl:.2f}") return True else: + if self._position_cache is not None: + c = self._position_cache + self.start, self.open_avg_price = c['start'], c.get('open_avg_price') + self.current_amount, self.unrealized_pnl = c.get('current_amount'), c.get('unrealized_pnl') + return True # 请求失败但用缓存 return False except Exception as e: logger.error(f"持仓查询异常: {e}") + if self._position_cache is not None: + c = self._position_cache + self.start, self.open_avg_price = c['start'], c.get('open_avg_price') + self.current_amount, self.unrealized_pnl = c.get('current_amount'), c.get('unrealized_pnl') + return True # 429 等异常时用缓存 return False def get_unrealized_pnl_usd(self): @@ -492,6 +527,7 @@ class BitmartFuturesTransaction: self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录 self.last_open_time = time.time() self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None) + self._last_position_fetch = 0 # 强制下一轮重新拉持仓 logger.success("开多成功") return True else: @@ -517,6 +553,7 @@ class BitmartFuturesTransaction: self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录 self.last_open_time = time.time() self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None) + self._last_position_fetch = 0 # 强制下一轮重新拉持仓 logger.success("开空成功") return True else: @@ -542,6 +579,7 @@ class BitmartFuturesTransaction: if self.verify_position_direction(1): self.max_unrealized_pnl_seen = None + self._last_position_fetch = 0 # 强制下一轮重新拉持仓 logger.success("反手做多成功") self.last_reverse_time = time.time() time.sleep(20) @@ -568,6 +606,7 @@ class BitmartFuturesTransaction: if self.verify_position_direction(-1): self.max_unrealized_pnl_seen = None + self._last_position_fetch = 0 # 强制下一轮重新拉持仓 logger.success("反手做空成功") self.last_reverse_time = time.time() time.sleep(20) @@ -698,8 +737,8 @@ class BitmartFuturesTransaction: else: logger.warning(f"交易执行失败或被阻止: {signal[0]}") - # 短暂等待后继续循环(同一根K线遇到信号就操作) - time.sleep(0.1) + # 主循环间隔,避免持仓/价格查询过于频繁触发 429 + time.sleep(self.loop_interval_seconds) if page_start: self.page.close()