feat(trades): 增强交易同步逻辑以优化记录查询和错误处理

在 `trades.py` 中更新了 `sync_trades_from_binance` 方法,新增时间范围内记录的查询逻辑,确保能够补全缺失的历史订单号。引入了更详细的日志记录,提升了错误处理的可追溯性,确保在获取交易对列表失败时提供清晰的反馈。此改动提升了交易记录的完整性和系统的稳定性。
This commit is contained in:
薇薇安 2026-02-17 22:46:33 +08:00
parent 01b8a4932f
commit ac1336dab8

View File

@ -426,33 +426,50 @@ async def sync_trades_from_binance(
start_ts_sec = start_time_ms // 1000
end_ts_sec = end_time_ms // 1000
# 仅对 DB 中在时间范围内有 open/closed 记录的 symbol 拉取订单WS 已回写订单号,大幅减少请求)
# 获取需要同步的 symbol 列表
# 策略:先查时间范围内的记录,如果没有,则查所有有记录的 symbol用于补全历史订单号
symbol_list = []
try:
# 先尝试用 "both" 过滤确保能找到所有相关记录包括3天前开仓但最近平仓的
trades_in_range = Trade.get_all(
start_timestamp=start_ts_sec,
end_timestamp=end_ts_sec,
account_id=account_id or DEFAULT_ACCOUNT_ID,
time_filter="both", # 使用 both 确保能找到所有相关记录
)
symbol_list = list({t.get("symbol") for t in (trades_in_range or []) if t.get("symbol")})
logger.info(f"从 DB 查询到 {len(trades_in_range or [])} 条记录,涉及 {len(symbol_list)} 个交易对")
# 如果时间范围内没有记录,尝试获取所有有记录的 symbol用于补全历史订单号
if not symbol_list:
logger.info(f"时间范围内({days}天)无记录,尝试获取所有有记录的 symbol 用于补全订单号")
all_trades = Trade.get_all(
account_id=account_id or DEFAULT_ACCOUNT_ID,
)
symbol_list = list({t.get("symbol") for t in (all_trades or []) if t.get("symbol")})
logger.info(f"获取到所有有记录的 symbol: {len(symbol_list)}")
except Exception as e:
logger.warning(f"从 DB 获取 symbol 列表失败,将跳过同步: {e}")
logger.warning(f"从 DB 获取 symbol 列表失败,将跳过同步: {e}", exc_info=True)
return {
"success": True,
"message": "未获取到需同步的交易对跳过WS 正常时订单号已由推送回写)",
"success": False,
"message": f"从数据库获取交易对列表失败: {str(e)}",
"total_orders": 0,
"updated_trades": 0,
"entry_order_id_filled": 0,
"exit_order_id_filled": 0,
"close_orders": 0,
"open_orders": 0,
}
if not symbol_list:
logger.info("DB 内在时间范围内无交易记录跳过全量拉取订单WS 为主时无需频繁同步)")
logger.info(f"DB 中无任何交易记录,跳过同步")
return {
"success": True,
"message": "近期无交易记录未请求币安订单WS 正常时订单号已由推送回写",
"message": f"数据库中没有交易记录,无法同步订单",
"total_orders": 0,
"updated_trades": 0,
"entry_order_id_filled": 0,
"exit_order_id_filled": 0,
"close_orders": 0,
"open_orders": 0,
}
@ -470,7 +487,7 @@ async def sync_trades_from_binance(
# 仅对上述 symbol 拉取订单
all_orders = []
try:
logger.info(f"仅对 {len(symbol_list)} 个有 DB 记录的 symbol 拉取订单(已跳过全市场请求")
logger.info(f"仅对 {len(symbol_list)} 个有 DB 记录的 symbol 拉取订单(时间范围: {days}天,{datetime.fromtimestamp(start_ts_sec)}{datetime.fromtimestamp(end_ts_sec)}")
for symbol in symbol_list:
try:
orders = await client.client.futures_get_all_orders(
@ -479,12 +496,14 @@ async def sync_trades_from_binance(
endTime=end_time_ms
)
filled_orders = [o for o in orders if o.get('status') == 'FILLED']
if filled_orders:
logger.debug(f" {symbol}: 获取到 {len(filled_orders)} 个已成交订单")
all_orders.extend(filled_orders)
await asyncio.sleep(0.1)
except Exception as e:
logger.debug(f"获取 {symbol} 订单失败: {e}")
logger.warning(f"获取 {symbol} 订单失败: {e}")
continue
logger.info(f"从币安获取到 {len(all_orders)} 个已成交订单")
logger.info(f"从币安获取到 {len(all_orders)} 个已成交订单(涉及 {len(symbol_list)} 个交易对)")
except Exception as e:
logger.error(f"获取币安订单失败: {e}")
raise HTTPException(status_code=500, detail=f"获取币安订单失败: {str(e)}")