feat(account, position_manager): 优化持仓同步逻辑与日志记录
在持仓同步功能中,增加了对系统订单前缀的默认处理,确保在无配置时使用默认前缀 "ats_"。同时,调整了日志记录逻辑,明确区分系统单与手动单的补建条件,提升了日志的可读性与准确性。这一改动旨在增强系统的可用性与用户友好性,确保持仓与数据库记录的一致性。
This commit is contained in:
parent
6a9fcddfdc
commit
81747c4eef
|
|
@ -1920,12 +1920,15 @@ async def sync_positions(
|
|||
or ""
|
||||
)
|
||||
system_order_prefix = (system_order_prefix or "").strip()
|
||||
# 无配置时用默认前缀 ats_,与 position_manager 一致,便于补建「系统限价/条件单事后成交」的记录
|
||||
if not system_order_prefix:
|
||||
system_order_prefix = "ats_"
|
||||
except Exception:
|
||||
pass
|
||||
system_order_prefix = "ats_"
|
||||
if missing_in_db:
|
||||
logger.info(f"发现 {len(missing_in_db)} 个持仓在币安存在但数据库中没有记录: {', '.join(missing_in_db)}")
|
||||
if system_order_prefix:
|
||||
logger.info(f" → 仅对开仓订单 clientOrderId 前缀为「{system_order_prefix}」的持仓补建(系统单标识)")
|
||||
logger.info(f" → 对开仓订单 clientOrderId 前缀为「{system_order_prefix}」的持仓补建(系统单);匹配到则不再要求有止损/止盈单")
|
||||
elif only_recover_when_has_sltp:
|
||||
logger.info(" → 仅对「存在止损/止盈单」的持仓补建记录(视为系统单),避免手动单误建")
|
||||
for symbol in missing_in_db:
|
||||
|
|
@ -2022,7 +2025,12 @@ async def sync_positions(
|
|||
pass
|
||||
if is_clearly_manual:
|
||||
continue
|
||||
elif only_recover_when_has_sltp:
|
||||
# 已通过系统前缀匹配到开仓订单的,直接补建,不要求有止损/止盈单(系统单一定能对应 DB)
|
||||
is_system_order_by_prefix = bool(
|
||||
system_order_prefix and client_order_id
|
||||
and str(client_order_id).strip().startswith(system_order_prefix)
|
||||
)
|
||||
if only_recover_when_has_sltp and not is_system_order_by_prefix:
|
||||
has_sltp = False
|
||||
try:
|
||||
normal = await client.get_open_orders(symbol)
|
||||
|
|
@ -2039,7 +2047,7 @@ async def sync_positions(
|
|||
except Exception as e:
|
||||
logger.debug(f"检查 {symbol} 止盈止损单失败: {e}")
|
||||
if not has_sltp:
|
||||
logger.debug(f" {symbol} 无止损/止盈单,跳过补建(视为非系统单)")
|
||||
logger.debug(f" {symbol} 无止损/止盈单且未匹配到系统前缀,跳过补建")
|
||||
continue
|
||||
if entry_order_id and hasattr(Trade, 'get_by_entry_order_id'):
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -4,6 +4,15 @@
|
|||
|
||||
---
|
||||
|
||||
## 〇、常见误解:为什么「持仓 5 单、订单记录只有 1 单」?
|
||||
|
||||
- **持仓列表**:数据来自**币安 API**(`get_open_positions()`),是交易所上真实存在的持仓,与 DB 无关。
|
||||
- **订单记录**:数据来自**本系统数据库 `trades` 表**,只有「本系统开仓并成功写库」或「同步/补建」时才会有一条记录。
|
||||
|
||||
因此**不是**「持仓存在就一定先在 DB 有了」——恰恰相反:币安上可以有 5 个持仓(本系统开的、手动在 App 开的、其它工具开的,或本系统开了但当时写库失败),而 DB 里只有我们成功写入或补建的那几条,所以订单记录会少于或等于持仓数。要对齐做法:使用**持仓同步**(见下文「补建」)或**同步币安订单**,把「币安有仓、DB 无记录」的持仓补建到 DB,订单记录就会和持仓一致。
|
||||
|
||||
---
|
||||
|
||||
## 一、数据模型(与币安对应的关键字段)
|
||||
|
||||
| 字段 | 含义 | 与币安对应 |
|
||||
|
|
|
|||
|
|
@ -490,13 +490,12 @@ class PositionManager:
|
|||
filled_quantity = 0.0
|
||||
entry_mode_used = "limit-only" if not smart_entry_enabled else ("limit+fallback" if allow_market_fallback else "limit-chase")
|
||||
|
||||
# 生成 client_order_id:先落库 pending,WS 按 o.c 匹配完善,减少对 REST 同步依赖
|
||||
# 生成 client_order_id:先落库 pending,WS/对账 按 client_order_id 匹配完善,确保限价/条件单事后成交也能对应 DB
|
||||
prefix = (config.TRADING_CONFIG.get("SYSTEM_ORDER_ID_PREFIX") or "").strip()
|
||||
client_order_id = None
|
||||
if prefix:
|
||||
prefix = prefix or "ats_" # 无配置时用默认前缀,保证系统单始终有 pending 可对账
|
||||
client_order_id = f"{prefix}_{int(time.time() * 1000)}_{random.randint(0, 0xFFFF):04x}"[:36]
|
||||
pending_trade_id = None
|
||||
if DB_AVAILABLE and Trade and client_order_id:
|
||||
if DB_AVAILABLE and Trade:
|
||||
try:
|
||||
pending_trade_id = Trade.create(
|
||||
symbol=symbol,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user