PINK: reconcile guard — refuse to silently drop orphan positions on restart
_reconcile_position_slot passed all N BingX positions (all slot_id=0) to reconcile_from_slots; with N>1 the kernel silently took one and forgot the rest. Now: sort by size desc, take only the largest, log ERROR naming every ignored orphan symbol. Caller must flatten exchange to 0 before restarting. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -180,6 +180,7 @@ def _reconcile_position_slot(
|
||||
# Build TradeSlot[] from exchange positions
|
||||
from prod.clean_arch.dita_v2.contracts import TradeSlot, TradeSide
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
reconciled = []
|
||||
if positions:
|
||||
for row in positions if isinstance(positions, list) else (
|
||||
@@ -234,6 +235,19 @@ def _reconcile_position_slot(
|
||||
reconciled.append(slot)
|
||||
|
||||
if reconciled:
|
||||
if len(reconciled) > 1:
|
||||
# Single-slot kernel: multiple open positions = orphan contamination from
|
||||
# prior retry-duplicate bug. Take the largest by size so the kernel can
|
||||
# exit it; the rest must be flattened manually before restart.
|
||||
reconciled.sort(key=lambda s: float(s.size or 0), reverse=True)
|
||||
orphan_syms = [s.asset for s in reconciled[1:]]
|
||||
_log.error(
|
||||
"RECONCILE WARNING: %d BingX positions found for single slot_id=%d. "
|
||||
"Taking largest (%s size=%.4f). ORPHANS IGNORED (must flatten manually): %s",
|
||||
len(reconciled), slot_id, reconciled[0].asset, float(reconciled[0].size or 0),
|
||||
orphan_syms,
|
||||
)
|
||||
reconciled = reconciled[:1]
|
||||
kernel.reconcile_from_slots(reconciled)
|
||||
else:
|
||||
# No open positions — ensure slot is idle
|
||||
|
||||
Reference in New Issue
Block a user