From 2fe6a1602bfc5c89d6b83f67ef15d23825fdd32c Mon Sep 17 00:00:00 2001 From: aaron <> Date: Mon, 30 Mar 2026 10:25:55 +0800 Subject: [PATCH] 1 --- backend/app/crypto_agent/crypto_agent.py | 74 +++++++++++++++--------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/backend/app/crypto_agent/crypto_agent.py b/backend/app/crypto_agent/crypto_agent.py index 5fb6cbd..1a26e25 100644 --- a/backend/app/crypto_agent/crypto_agent.py +++ b/backend/app/crypto_agent/crypto_agent.py @@ -2128,15 +2128,30 @@ class CryptoAgent: Returns: (positions, account, pending_orders) """ + # 1. 余额(独立 try,确保余额始终可用) try: bg_state = self.bitget.get_account_state() + except Exception as e: + logger.error(f"获取 Bitget 余额失败: {e}") + bg_state = {"account_value": 0, "total_margin_used": 0, "available_balance": 0} - position_list = [] + logger.info( + f"[Bitget] 余额: account_value=${bg_state['account_value']:.2f}, " + f"available=${bg_state['available_balance']:.2f}" + ) + + # 2. 持仓(独立 try) + position_list = [] + try: for pos in self.bitget.get_open_positions(): coin = pos["coin"] size = pos["size"] if size != 0: - tp_sl = self.bitget.get_tp_sl_prices(coin) + tp_sl = {} + try: + tp_sl = self.bitget.get_tp_sl_prices(coin) + except Exception as e: + logger.warning(f"获取 {coin} TP/SL 失败(不影响交易): {e}") position_list.append({ 'symbol': f"{coin}USDT", 'side': 'buy' if size > 0 else 'sell', @@ -2146,27 +2161,32 @@ class CryptoAgent: 'stop_loss': tp_sl.get('stop_loss'), 'take_profit': tp_sl.get('take_profit'), }) + except Exception as e: + logger.error(f"获取 Bitget 持仓失败: {e}") - total_position_value = sum( - p['holding'] * p['entry_price'] for p in position_list - ) - account = { - 'current_balance': bg_state["account_value"], - 'initial_balance': self.bitget.initial_balance, - 'used_margin': bg_state["total_margin_used"], - 'available_balance': bg_state["available_balance"], - 'available': bg_state["available_balance"], # 决策器期望的键名 - 'order_leverage': 10, - 'total_position_value': total_position_value, - 'max_total_leverage': self.bitget.max_total_leverage, - } - if account['current_balance'] > 0: - account['current_total_leverage'] = total_position_value / account['current_balance'] - else: - account['current_total_leverage'] = 0 + # 3. 构建 account 字典 + total_position_value = sum( + p['holding'] * p['entry_price'] for p in position_list + ) + account = { + 'current_balance': bg_state["account_value"], + 'initial_balance': self.bitget.initial_balance, + 'used_margin': bg_state["total_margin_used"], + 'available_balance': bg_state["available_balance"], + 'available': bg_state["available_balance"], # 决策器期望的键名 + 'order_leverage': 10, + 'total_position_value': total_position_value, + 'max_total_leverage': self.bitget.max_total_leverage, + } + if account['current_balance'] > 0: + account['current_total_leverage'] = total_position_value / account['current_balance'] + else: + account['current_total_leverage'] = 0 + # 4. 挂单(独立 try) + pending_orders = [] + try: all_orders = self.bitget.get_open_orders() - pending_orders = [] for order in all_orders: pending_orders.append({ 'order_id': order.get('order_id'), @@ -2178,12 +2198,10 @@ class CryptoAgent: 'is_reduce_only': order.get('is_reduce_only', False), 'created_at': order.get('created_at'), }) - - return position_list, account, pending_orders - except Exception as e: - logger.error(f"获取 Bitget 状态失败: {e}") - return [], {}, [] + logger.error(f"获取 Bitget 挂单失败: {e}") + + return position_list, account, pending_orders def _calculate_position_size(self, signal: Dict[str, Any], account: Dict[str, Any], @@ -2377,14 +2395,14 @@ class CryptoAgent: if remaining_leverage <= 0: return False, f"已达最大杠杆 {current_leverage:.1f}x/{max_leverage}x" - # 2. 可用余额检查 + # 2. 可用余额检查(仅警告,不阻止执行——由交易所做最终校验) available = account.get('available', account.get('available_balance', 0)) symbol = signal.get('symbol', '').replace('USDT', '').upper() rules = self.PLATFORM_RULES.get(platform_name, {}) min_margin = rules.get('min_margin', {}).get(symbol, 10) - if available < min_margin: - return False, f"可用余额 ${available:.2f} < 最小保证金 ${min_margin}" + if available > 0 and available < min_margin: + logger.warning(f"[{platform_name}] 余额偏低 ${available:.2f} < ${min_margin},仍尝试执行") # 3. 持仓数量限制(每个币种最多3个持仓+挂单) symbol_orders = [o for o in positions + pending_orders if o.get('symbol') == signal.get('symbol')]