This commit is contained in:
薇薇安 2026-02-15 14:24:09 +08:00
parent 9cd39c3655
commit f6f4ca11ae

View File

@ -854,68 +854,58 @@ class PositionManager:
position_info = self.active_positions[symbol]
trade_id = position_info.get('tradeId')
if trade_id:
try:
logger.info(f"{symbol} [平仓] 更新数据库状态为已平仓 (ID: {trade_id})...")
# 获取当前价格作为平仓价格
ticker = await self.client.get_ticker_24h(symbol)
exit_price = float(ticker['price']) if ticker else float(position_info['entryPrice'])
# 确保所有值都是float类型
entry_price = float(position_info['entryPrice'])
quantity = float(position_info['quantity'])
if position_info['side'] == 'BUY':
pnl = (exit_price - entry_price) * quantity
pnl_percent = ((exit_price - entry_price) / entry_price) * 100
else:
pnl = (entry_price - exit_price) * quantity
pnl_percent = ((entry_price - exit_price) / entry_price) * 100
# 同步平仓时没有订单号设为None
# 计算持仓持续时间和策略类型
entry_time = position_info.get('entryTime')
duration_minutes = None
if entry_time:
try:
if isinstance(entry_time, str):
entry_dt = datetime.strptime(entry_time, '%Y-%m-%d %H:%M:%S')
else:
entry_dt = entry_time
exit_dt = get_beijing_time() # 使用北京时间计算持续时间
duration = exit_dt - entry_dt
duration_minutes = int(duration.total_seconds() / 60)
except Exception as e:
logger.debug(f"计算持仓持续时间失败: {e}")
strategy_type = position_info.get('strategyType', 'trend_following')
# 网络/DB 超时时可重试,避免 TimeoutError 导致状态未更新
db_update_retries = 3
for db_attempt in range(db_update_retries):
try:
Trade.update_exit(
trade_id=trade_id,
exit_price=exit_price,
exit_reason=reason,
pnl=pnl,
pnl_percent=pnl_percent,
exit_order_id=None, # 同步平仓时没有订单号
strategy_type=strategy_type,
duration_minutes=duration_minutes
logger.info(f"{symbol} [平仓] 更新数据库状态为已平仓 (ID: {trade_id})...")
ticker = await self.client.get_ticker_24h(symbol)
exit_price = float(ticker['price']) if ticker else float(position_info['entryPrice'])
entry_price = float(position_info['entryPrice'])
quantity = float(position_info['quantity'])
if position_info['side'] == 'BUY':
pnl = (exit_price - entry_price) * quantity
pnl_percent = ((exit_price - entry_price) / entry_price) * 100
else:
pnl = (entry_price - exit_price) * quantity
pnl_percent = ((entry_price - exit_price) / entry_price) * 100
entry_time = position_info.get('entryTime')
duration_minutes = None
if entry_time:
try:
if isinstance(entry_time, str):
entry_dt = datetime.strptime(entry_time, '%Y-%m-%d %H:%M:%S')
else:
entry_dt = entry_time
exit_dt = get_beijing_time()
duration = exit_dt - entry_dt
duration_minutes = int(duration.total_seconds() / 60)
except Exception as e:
logger.debug(f"计算持仓持续时间失败: {e}")
strategy_type = position_info.get('strategyType', 'trend_following')
db_update_retries = 3
for db_attempt in range(db_update_retries):
try:
Trade.update_exit(
trade_id=trade_id,
exit_price=exit_price,
exit_reason=reason,
pnl=pnl,
pnl_percent=pnl_percent,
exit_order_id=None,
strategy_type=strategy_type,
duration_minutes=duration_minutes
)
logger.info(f"{symbol} [平仓] ✓ 数据库状态已更新")
updated = True
break
except Exception as e:
err_msg = str(e).strip() or f"{type(e).__name__}"
if db_attempt < db_update_retries - 1:
wait_sec = 2
logger.warning(
f"{symbol} [平仓] 更新数据库失败 (第 {db_attempt + 1}/{db_update_retries} 次): {err_msg}"
f"{wait_sec}秒后重试"
)
logger.info(f"{symbol} [平仓] ✓ 数据库状态已更新")
updated = True
break
except Exception as e:
err_msg = str(e).strip() or f"{type(e).__name__}"
if db_attempt < db_update_retries - 1:
wait_sec = 2
logger.warning(
f"{symbol} [平仓] 更新数据库失败 (第 {db_attempt + 1}/{db_update_retries} 次): {err_msg}"
f"{wait_sec}秒后重试"
)
await asyncio.sleep(wait_sec)
else:
logger.error(f"{symbol} [平仓] ❌ 更新数据库状态失败: {err_msg}")
await asyncio.sleep(wait_sec)
else:
logger.error(f"{symbol} [平仓] ❌ 更新数据库状态失败: {err_msg}")
# 清理本地记录
await self._stop_position_monitoring(symbol)
@ -1157,6 +1147,11 @@ class PositionManager:
logger.error(f" 错误类型: {type(e).__name__}")
import traceback
logger.error(f" 错误详情:\n{traceback.format_exc()}")
except Exception as db_error:
logger.error(f"{symbol} [平仓] 更新平仓记录到数据库时发生异常: {db_error}")
logger.error(f" 错误类型: {type(db_error).__name__}")
import traceback
logger.error(f" 错误详情:\n{traceback.format_exc()}")
else:
logger.warning(f"{symbol} 没有关联的数据库交易ID无法更新平仓记录")
elif not DB_AVAILABLE: