This commit is contained in:
薇薇安 2026-02-14 11:59:29 +08:00
parent 29ebb8e2c9
commit 6da90babe9
3 changed files with 25 additions and 15 deletions

View File

@ -1629,8 +1629,8 @@ async def sync_positions(account_id: int = Depends(get_account_id)):
except Exception:
latest_close_order = None
# 获取该交易对的所有open记录
open_trades = Trade.get_by_symbol(symbol, status='open')
# 获取该交易对的 open 记录(仅当前账号,避免误更新其他账号)
open_trades = Trade.get_by_symbol(symbol, status='open', account_id=account_id)
for trade in open_trades:
trade_id = trade['id']

View File

@ -759,18 +759,25 @@ class BinanceClient:
try:
# 增加 recvWindow 以避免 -1021 错误
positions = await self.client.futures_position_information(recvWindow=20000)
open_positions = [
{
# 只保留真实持仓:非零且名义价值 >= 1 USDT避免灰尘持仓被当成“有仓”导致同步时批量创建假 manual_entry
min_notional = 1.0
open_positions = []
for pos in positions:
amt = float(pos['positionAmt'])
if amt == 0:
continue
entry_price = float(pos['entryPrice'])
notional = abs(amt) * entry_price
if notional < min_notional:
continue
open_positions.append({
'symbol': pos['symbol'],
'positionAmt': float(pos['positionAmt']),
'entryPrice': float(pos['entryPrice']),
'positionAmt': amt,
'entryPrice': entry_price,
'markPrice': float(pos.get('markPrice', 0)),
'unRealizedProfit': float(pos['unRealizedProfit']),
'leverage': int(pos['leverage'])
}
for pos in positions
if float(pos['positionAmt']) != 0
]
})
return open_positions
except (asyncio.TimeoutError, BinanceAPIException) as e:
last_error = e

View File

@ -2799,12 +2799,15 @@ class PositionManager:
quantity = abs(position_amt)
side = 'BUY' if position_amt > 0 else 'SELL'
notional = (float(entry_price) * float(quantity)) if entry_price and quantity else 0
if notional < 1.0:
logger.debug(f"{symbol} [状态同步] 跳过灰尘持仓 (名义 {notional:.4f} USDT < 1),不创建记录")
continue
logger.info(
f"{symbol} [状态同步] 检测到手动开仓,创建数据库记录... "
f"({side} {quantity:.4f} @ {entry_price:.4f})"
)
# 创建数据库记录
# 创建数据库记录(显式传入 account_id避免多账号混用
trade_id = Trade.create(
symbol=symbol,
side=side,
@ -2812,9 +2815,9 @@ class PositionManager:
entry_price=entry_price,
leverage=binance_position.get('leverage', 10),
entry_reason='manual_entry', # 标记为手动开仓
# 手动开仓无法拿到策略侧ATR/分步止盈,这里尽量补齐“规模字段”
notional_usdt=(float(entry_price) * float(quantity)) if entry_price and quantity else None,
margin_usdt=((float(entry_price) * float(quantity)) / float(binance_position.get('leverage', 10))) if entry_price and quantity and float(binance_position.get('leverage', 10) or 0) > 0 else None,
notional_usdt=notional,
margin_usdt=(notional / float(binance_position.get('leverage', 10) or 10)) if float(binance_position.get('leverage', 10) or 0) > 0 else None,
account_id=self.account_id,
)
logger.info(f"{symbol} [状态同步] ✓ 数据库记录已创建 (ID: {trade_id})")