diff --git a/backend/app/crypto_agent/crypto_agent.py b/backend/app/crypto_agent/crypto_agent.py index 3edf12f..e45bda9 100644 --- a/backend/app/crypto_agent/crypto_agent.py +++ b/backend/app/crypto_agent/crypto_agent.py @@ -2249,8 +2249,17 @@ class CryptoAgent: for p in self.bitget.get_open_positions() ) + # 获取决策层的保证金建议(如果有) + quantity = decision.get('quantity', 0) # 保证金金额 leverage = min(decision.get('leverage', 5), 10) + # 如果决策层提供了保证金,计算最小仓位价值 + min_position_from_margin = 0 + if quantity and isinstance(quantity, (int, float)) and quantity > 0: + min_position_from_margin = quantity * leverage # 保证金 × 杠杆 + logger.info(f" 决策层保证金: ${quantity:.2f} → 最小仓位价值: ${min_position_from_margin:.2f}") + + # 计算最大仓位限制 max_by_config = self.bitget.max_single_position max_by_available = available_balance * leverage max_by_total_leverage = ( @@ -2259,6 +2268,21 @@ class CryptoAgent: max_position_usd = min(max_by_config, max_by_available, max_by_total_leverage) max_position_usd = min(max_position_usd, current_balance * 0.5) + # 确保最小仓位价值(如果决策层提供了保证金) + if min_position_from_margin > 0: + max_position_usd = max(max_position_usd, min_position_from_margin) + logger.info(f" 调整最小仓位: ${max_position_usd:.2f} (确保 ≥ 保证金 × 杠杆)") + + # 详细日志 + logger.info(f"💰 Bitget 仓位计算:") + logger.info(f" 账户余额: ${current_balance:.2f}, 可用: ${available_balance:.2f}") + logger.info(f" 当前持仓价值: ${total_position_value:.2f}") + logger.info(f" 杠杆: {leverage}x") + logger.info(f" 单笔上限: ${max_by_config:.2f}") + logger.info(f" 可用杠杆空间: ${max_by_available:.2f}") + logger.info(f" 总杠杆空间: ${max_by_total_leverage:.2f}") + logger.info(f" 最终仓位 USD: ${max_position_usd:.2f}") + if max_position_usd <= 0: logger.warning(f"⚠️ Bitget 可用保证金不足,无法开仓 (balance={current_balance:.2f})") return 0 @@ -2266,16 +2290,28 @@ class CryptoAgent: symbol = decision.get('symbol', '').replace('USDT', '') contract_size = self.bitget.get_contract_size(symbol) if contract_size <= 0 or current_price <= 0: + logger.warning(f"⚠️ Bitget 合约规格或价格无效 (contract_size={contract_size}, price={current_price})") return 0 # notional → coins → contracts(向下取整) coin_amount = max_position_usd / current_price contracts = math.floor(coin_amount / contract_size) + logger.info(f" 币数量: {coin_amount:.6f}, 合约规格: {contract_size}, 张数: {contracts}") + + # 如果计算出的张数 < 1,检查是否是保证金太少 if contracts < 1: - logger.warning( - f"⚠️ Bitget 仓位计算 {coin_amount:.4f} 币 = {contracts} 张,低于最小 1 张" - ) + min_coins_needed = contract_size + min_usd_needed = min_coins_needed * current_price + min_margin_needed = min_usd_needed / leverage + + logger.warning(f"⚠️ Bitget 仓位计算 {coin_amount:.4f} 币 = {contracts} 张,低于最小 1 张") + logger.warning(f" 最小需要: {min_coins_needed} 币 ≈ ${min_usd_needed:.2f}") + logger.warning(f" 最小保证金: ${min_margin_needed:.2f} (杠杆 {leverage}x)") + + if quantity and isinstance(quantity, (int, float)) and quantity > 0: + logger.warning(f" 当前保证金: ${quantity:.2f},建议提高到至少 ${min_margin_needed:.2f}") + return 0 logger.info(