diff --git a/backend/api/routes/account.py b/backend/api/routes/account.py index 0b18b00..67d1400 100644 --- a/backend/api/routes/account.py +++ b/backend/api/routes/account.py @@ -1623,8 +1623,8 @@ async def sync_positions( if binance_symbols: logger.info(f" 持仓列表: {', '.join(binance_symbols)}") - # 2. 获取数据库中状态为open的交易记录 - db_open_trades = Trade.get_all(status='open', account_id=account_id) + # 2. 获取数据库中状态为open的交易记录(限制条数防内存暴增) + db_open_trades = Trade.get_all(status='open', account_id=account_id, limit=500) db_open_symbols = {t['symbol'] for t in db_open_trades} logger.info(f"数据库open状态: {len(db_open_symbols)} 个") if db_open_symbols: diff --git a/backend/api/routes/stats.py b/backend/api/routes/stats.py index a2ffd98..1e8cc66 100644 --- a/backend/api/routes/stats.py +++ b/backend/api/routes/stats.py @@ -82,9 +82,16 @@ async def get_performance_stats( # 账户快照 snapshots = AccountSnapshot.get_recent(days, account_id=account_id) - # 交易统计 - start_date = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d') - trades = Trade.get_all(start_date=start_date, account_id=account_id) + # 交易统计(时间范围 + limit 防内存暴增) + start_ts = int((datetime.now() - timedelta(days=days)).timestamp()) + end_ts = int(datetime.now().timestamp()) + trades = Trade.get_all( + start_timestamp=start_ts, + end_timestamp=end_ts, + account_id=account_id, + time_filter="exit", + limit=10000, + ) return { "snapshots": snapshots, @@ -162,7 +169,7 @@ async def get_dashboard_data(account_id: int = Depends(get_account_id)): logger.warning(f"获取币安实时持仓失败,回退到数据库列表: {fetch_err}") open_trades = [] if not open_trades: - db_trades = Trade.get_all(status='open', account_id=account_id) + db_trades = Trade.get_all(status='open', account_id=account_id, limit=500) 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)) diff --git a/backend/api/routes/trades.py b/backend/api/routes/trades.py index 2044299..addbf26 100644 --- a/backend/api/routes/trades.py +++ b/backend/api/routes/trades.py @@ -773,6 +773,7 @@ async def sync_trades_from_binance( end_timestamp=time_window_end, time_filter="entry", reconciled_only=False, + limit=500, ) trades_no_entry_id = [ t for t in trades_in_window @@ -871,6 +872,7 @@ async def verify_trades_against_binance( account_id=account_id, start_timestamp=start_ts, end_timestamp=end_ts, + limit=10000, ) # 只校验「可对账」记录:有 entry_order_id;若已平仓则还须有 exit_order_id def _has_entry(eid): diff --git a/backend/database/models.py b/backend/database/models.py index d9ad695..7e5f512 100644 --- a/backend/database/models.py +++ b/backend/database/models.py @@ -1134,10 +1134,10 @@ class Trade: query += " ORDER BY " + time_col + " DESC, id DESC" else: query += " ORDER BY COALESCE(exit_time, entry_time) DESC, id DESC" - # 未传 limit 时使用默认上限,防止全表加载导致内存暴增 + # 未传 limit 时使用默认上限,防止全表加载导致内存暴增(2 CPU 4G 场景) _limit = limit if _limit is None or _limit <= 0: - _limit = 20000 + _limit = 10000 query += " LIMIT %s" params.append(int(_limit)) logger.debug(f"查询交易记录: time_filter={time_filter}, limit={_limit}, reconciled_only={reconciled_only}, include_sync={include_sync}")