From 29ebb8e2c957a4b51f640881d1889a89047d921d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Sat, 14 Feb 2026 11:49:51 +0800 Subject: [PATCH] 1 --- backend/api/routes/stats.py | 160 ++++++++++++------------------------ 1 file changed, 52 insertions(+), 108 deletions(-) diff --git a/backend/api/routes/stats.py b/backend/api/routes/stats.py index a8d3276..64de3db 100644 --- a/backend/api/routes/stats.py +++ b/backend/api/routes/stats.py @@ -105,118 +105,62 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)): account_data = None account_error = None - # 优先尝试获取实时账户数据 - try: - from api.routes.account import get_realtime_account_data - logger.info(f"调用 get_realtime_account_data(account_id={account_id})") - account_data = await get_realtime_account_data(account_id=account_id) - logger.info(f"成功获取实时账户数据,返回的 total_balance={account_data.get('total_balance', 'N/A') if account_data else 'N/A'}") - except HTTPException as e: - # HTTPException 需要特殊处理,提取错误信息 - account_error = e.detail - logger.warning(f"获取实时账户数据失败 (HTTP {e.status_code}): {account_error}") - # 回退到数据库快照 - try: - snapshots = AccountSnapshot.get_recent(1, account_id=account_id) - if snapshots: - account_data = { - "total_balance": snapshots[0].get('total_balance', 0), - "available_balance": snapshots[0].get('available_balance', 0), - "total_position_value": snapshots[0].get('total_position_value', 0), - "total_pnl": snapshots[0].get('total_pnl', 0), - "open_positions": snapshots[0].get('open_positions', 0) - } - logger.info("使用数据库快照作为账户数据") - else: - logger.warning("数据库中没有账户快照数据") - except Exception as db_error: - logger.error(f"从数据库获取账户快照失败: {db_error}") - except Exception as e: - account_error = str(e) - logger.warning(f"获取实时账户数据失败: {account_error}", exc_info=True) - # 回退到数据库快照 - try: - snapshots = AccountSnapshot.get_recent(1, account_id=account_id) - if snapshots: - account_data = { - "total_balance": snapshots[0].get('total_balance', 0), - "available_balance": snapshots[0].get('available_balance', 0), - "total_position_value": snapshots[0].get('total_position_value', 0), - "total_pnl": snapshots[0].get('total_pnl', 0), - "open_positions": snapshots[0].get('open_positions', 0) - } - logger.info("使用数据库快照作为账户数据") - except Exception as db_error: - logger.error(f"从数据库获取账户快照失败: {db_error}") + # [EMERGENCY FIX] 强制使用数据库快照,停止实时API请求以解决 -1003 IP Ban 问题 + logger.warning(f"检测到潜在的 API 限流风险,强制使用数据库快照 (account_id={account_id})") - # 获取持仓数据(优先实时,回退到数据库) + # 回退到数据库快照 + try: + snapshots = AccountSnapshot.get_recent(1, account_id=account_id) + if snapshots: + account_data = { + "total_balance": snapshots[0].get('total_balance', 0), + "available_balance": snapshots[0].get('available_balance', 0), + "total_position_value": snapshots[0].get('total_position_value', 0), + "total_pnl": snapshots[0].get('total_pnl', 0), + "open_positions": snapshots[0].get('open_positions', 0) + } + logger.info("使用数据库快照作为账户数据") + else: + logger.warning("数据库中没有账户快照数据") + # 构造一个空的账户数据结构,避免前端报错 + account_data = { + "total_balance": 0, + "available_balance": 0, + "total_position_value": 0, + "total_pnl": 0, + "open_positions": 0 + } + except Exception as db_error: + logger.error(f"从数据库获取账户快照失败: {db_error}") + + # 获取持仓数据(强制使用数据库记录) open_trades = [] positions_error = None try: - from api.routes.account import get_realtime_positions - logger.info(f"调用 get_realtime_positions(account_id={account_id})") - positions = await get_realtime_positions(account_id=account_id) - # 转换为前端需要的格式 - open_trades = positions - logger.info(f"成功获取实时持仓数据: {len(open_trades)} 个持仓 (account_id={account_id})") - except HTTPException as e: - positions_error = e.detail - logger.warning(f"获取实时持仓失败 (HTTP {e.status_code}): {positions_error}") - # 回退到数据库记录 - try: - db_trades = Trade.get_all(status='open', account_id=account_id)[:10] - # 格式化数据库记录,添加 entry_value_usdt 字段 - open_trades = [] - for trade in db_trades: - entry_value_usdt = float(trade.get('quantity', 0)) * float(trade.get('entry_price', 0)) - leverage = float(trade.get('leverage', 1)) - pnl = float(trade.get('pnl', 0)) - - # 数据库中的pnl_percent是价格涨跌幅,需要转换为收益率 - # 收益率 = 盈亏 / 保证金 - margin = entry_value_usdt / leverage if leverage > 0 else entry_value_usdt - pnl_percent = (pnl / margin * 100) if margin > 0 else 0 - - formatted_trade = { - **trade, - 'entry_value_usdt': entry_value_usdt, - 'mark_price': trade.get('entry_price', 0), # 数据库中没有标记价,使用入场价 - 'pnl': pnl, - 'pnl_percent': pnl_percent # 使用重新计算的收益率 - } - open_trades.append(formatted_trade) - logger.info(f"使用数据库记录作为持仓数据: {len(open_trades)} 个持仓") - except Exception as db_error: - logger.error(f"从数据库获取持仓记录失败: {db_error}") - except Exception as e: - positions_error = str(e) - logger.warning(f"获取实时持仓失败: {positions_error}", exc_info=True) - # 回退到数据库记录 - try: - db_trades = Trade.get_all(status='open', account_id=account_id)[:10] - # 格式化数据库记录,添加 entry_value_usdt 字段 - open_trades = [] - for trade in db_trades: - entry_value_usdt = float(trade.get('quantity', 0)) * float(trade.get('entry_price', 0)) - leverage = float(trade.get('leverage', 1)) - pnl = float(trade.get('pnl', 0)) - - # 数据库中的pnl_percent是价格涨跌幅,需要转换为收益率 - # 收益率 = 盈亏 / 保证金 - margin = entry_value_usdt / leverage if leverage > 0 else entry_value_usdt - pnl_percent = (pnl / margin * 100) if margin > 0 else 0 - - formatted_trade = { - **trade, - 'entry_value_usdt': entry_value_usdt, - 'mark_price': trade.get('entry_price', 0), # 数据库中没有标记价,使用入场价 - 'pnl': pnl, - 'pnl_percent': pnl_percent # 使用重新计算的收益率 - } - open_trades.append(formatted_trade) - logger.info(f"使用数据库记录作为持仓数据: {len(open_trades)} 个持仓") - except Exception as db_error: - logger.error(f"从数据库获取持仓记录失败: {db_error}") + db_trades = Trade.get_all(status='open', account_id=account_id) + # 格式化数据库记录,添加 entry_value_usdt 字段 + open_trades = [] + for trade in db_trades: + entry_value_usdt = float(trade.get('quantity', 0)) * float(trade.get('entry_price', 0)) + leverage = float(trade.get('leverage', 1)) + pnl = float(trade.get('pnl', 0)) + + # 数据库中的pnl_percent是价格涨跌幅,需要转换为收益率 + # 收益率 = 盈亏 / 保证金 + margin = entry_value_usdt / leverage if leverage > 0 else entry_value_usdt + pnl_percent = (pnl / margin * 100) if margin > 0 else 0 + + formatted_trade = { + **trade, + 'entry_value_usdt': entry_value_usdt, + 'mark_price': trade.get('entry_price', 0), # 数据库中没有标记价,使用入场价 + 'pnl': pnl, + 'pnl_percent': pnl_percent # 使用重新计算的收益率 + } + open_trades.append(formatted_trade) + logger.info(f"使用数据库记录作为持仓数据: {len(open_trades)} 个持仓") + except Exception as db_error: + logger.error(f"从数据库获取持仓记录失败: {db_error}") # 最近的扫描记录 recent_scans = []