哈哈
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user