diff --git a/backend/api/routes/account.py b/backend/api/routes/account.py index 64595b9..7382997 100644 --- a/backend/api/routes/account.py +++ b/backend/api/routes/account.py @@ -19,43 +19,122 @@ router = APIRouter() async def get_realtime_account_data(): """从币安API实时获取账户数据""" + logger.info("=" * 60) + logger.info("开始获取实时账户数据") + logger.info("=" * 60) + try: # 从数据库读取API密钥 + logger.info("步骤1: 从数据库读取API配置...") api_key = TradingConfig.get_value('BINANCE_API_KEY') api_secret = TradingConfig.get_value('BINANCE_API_SECRET') use_testnet = TradingConfig.get_value('USE_TESTNET', False) + logger.info(f" - API密钥存在: {bool(api_key)}") + if api_key: + logger.info(f" - API密钥长度: {len(api_key)} 字符") + logger.info(f" - API密钥前缀: {api_key[:10]}...") + else: + logger.warning(" - API密钥为空!") + + logger.info(f" - API密钥存在: {bool(api_secret)}") + if api_secret: + logger.info(f" - API密钥长度: {len(api_secret)} 字符") + logger.info(f" - API密钥前缀: {api_secret[:10]}...") + else: + logger.warning(" - API密钥为空!") + + logger.info(f" - 使用测试网: {use_testnet}") + if not api_key or not api_secret: + error_msg = "API密钥未配置,请在配置界面设置BINANCE_API_KEY和BINANCE_API_SECRET" + logger.error(f" ✗ {error_msg}") raise HTTPException( status_code=400, - detail="API密钥未配置,请在配置界面设置BINANCE_API_KEY和BINANCE_API_SECRET" + detail=error_msg ) # 导入交易系统的BinanceClient + logger.info("步骤2: 导入BinanceClient...") try: from binance_client import BinanceClient - except ImportError: + logger.info(" ✓ 从当前路径导入BinanceClient成功") + except ImportError as e: + logger.warning(f" - 从当前路径导入失败: {e}") # 如果直接导入失败,尝试从trading_system导入 trading_system_path = project_root / 'trading_system' sys.path.insert(0, str(trading_system_path)) - from binance_client import BinanceClient + logger.info(f" - 添加路径到sys.path: {trading_system_path}") + try: + from binance_client import BinanceClient + logger.info(" ✓ 从trading_system路径导入BinanceClient成功") + except ImportError as e2: + logger.error(f" ✗ 导入BinanceClient失败: {e2}") + raise # 创建客户端 + logger.info("步骤3: 创建BinanceClient实例...") client = BinanceClient( api_key=api_key, api_secret=api_secret, testnet=use_testnet ) + logger.info(f" ✓ 客户端创建成功 (testnet={use_testnet})") - await client.connect() + # 连接币安API + logger.info("步骤4: 连接币安API...") + try: + await client.connect() + logger.info(" ✓ 币安API连接成功") + except Exception as e: + logger.error(f" ✗ 币安API连接失败: {e}", exc_info=True) + raise # 获取账户余额 - balance = await client.get_account_balance() + logger.info("步骤5: 获取账户余额...") + try: + balance = await client.get_account_balance() + logger.info(" ✓ 账户余额获取成功") + logger.info(f" - 返回数据类型: {type(balance)}") + logger.info(f" - 返回数据内容: {balance}") + if balance: + logger.info(f" - 总余额: {balance.get('total', 'N/A')} USDT") + logger.info(f" - 可用余额: {balance.get('available', 'N/A')} USDT") + logger.info(f" - 保证金: {balance.get('margin', 'N/A')} USDT") + + if balance.get('total', 0) == 0: + logger.warning(" ⚠ 账户余额为0,可能是API权限问题或账户确实无余额") + else: + logger.warning(" ⚠ 返回的余额数据为空") + except Exception as e: + logger.error(f" ✗ 获取账户余额失败: {e}", exc_info=True) + raise # 获取持仓 - positions = await client.get_open_positions() + logger.info("步骤6: 获取持仓信息...") + try: + positions = await client.get_open_positions() + logger.info(" ✓ 持仓信息获取成功") + logger.info(f" - 返回数据类型: {type(positions)}") + logger.info(f" - 持仓数量: {len(positions)}") + + if positions: + logger.info(" - 持仓详情:") + for i, pos in enumerate(positions[:5], 1): # 只显示前5个 + logger.info(f" {i}. {pos.get('symbol', 'N/A')}: " + f"数量={pos.get('positionAmt', 0)}, " + f"入场价={pos.get('entryPrice', 0)}, " + f"盈亏={pos.get('unRealizedProfit', 0)}") + if len(positions) > 5: + logger.info(f" ... 还有 {len(positions) - 5} 个持仓") + else: + logger.info(" - 当前无持仓") + except Exception as e: + logger.error(f" ✗ 获取持仓信息失败: {e}", exc_info=True) + raise # 计算总仓位价值和总盈亏 + logger.info("步骤7: 计算仓位统计...") total_position_value = 0 total_pnl = 0 open_positions_count = 0 @@ -77,21 +156,50 @@ async def get_realtime_account_data(): total_position_value += position_value total_pnl += unrealized_pnl open_positions_count += 1 + + logger.debug(f" - {pos.get('symbol')}: 价值={position_value:.2f}, 盈亏={unrealized_pnl:.2f}") - await client.disconnect() + logger.info(" ✓ 仓位统计计算完成") + logger.info(f" - 总仓位价值: {total_position_value:.2f} USDT") + logger.info(f" - 总盈亏: {total_pnl:.2f} USDT") + logger.info(f" - 持仓数量: {open_positions_count}") - return { - "total_balance": balance.get('total', 0), - "available_balance": balance.get('available', 0), + # 断开连接 + logger.info("步骤8: 断开币安API连接...") + try: + await client.disconnect() + logger.info(" ✓ 连接已断开") + except Exception as e: + logger.warning(f" ⚠ 断开连接时出错: {e}") + + # 构建返回结果 + result = { + "total_balance": balance.get('total', 0) if balance else 0, + "available_balance": balance.get('available', 0) if balance else 0, "total_position_value": total_position_value, "total_pnl": total_pnl, "open_positions": open_positions_count } - except HTTPException: + + logger.info("=" * 60) + logger.info("账户数据获取成功!") + logger.info(f"最终结果: {result}") + logger.info("=" * 60) + + return result + + except HTTPException as e: + logger.error("=" * 60) + logger.error(f"HTTP异常: {e.status_code} - {e.detail}") + logger.error("=" * 60) raise except Exception as e: - logger.error(f"获取账户数据失败: {e}", exc_info=True) - raise HTTPException(status_code=500, detail=f"获取账户数据失败: {str(e)}") + error_msg = f"获取账户数据失败: {str(e)}" + logger.error("=" * 60) + logger.error(f"异常类型: {type(e).__name__}") + logger.error(f"错误信息: {error_msg}") + logger.error("=" * 60, exc_info=True) + raise HTTPException(status_code=500, detail=error_msg) @router.get("/realtime")