PINK Phase 0: FET -$5,990 fix batch — leverage-free PnL, true fill prices, reconcile baseline anchors
Defects fix (FET -$5,990 replay, 2026-06-11): - realized_pnl() and mark_price(): PnL = qty × Δprice, side-signed; no ×leverage inflation (was 3× every leg). - BingX MARKET fill events carry true fill price (avgPrice/lastFillPrice), never the order's nominal price (protective bound ±20-25% from mark, poisoned PnL to -$5,990 on a +$164 round-trip). - Fill routing by ORDER IDENTITY first, FSM state second — late entry-remainder fills during EXIT_WORKING no longer misclassify as exits. - Entry basis = VWAP across entry fills, not last fill price. - reconcile_from_slots / restore_state: re-anchor _last_settled_pnl / _slot_was_closed to adopted slot state (cross-restart double-book of carried PnL). - ACCOUNT_UPDATE with wallet_balance=0 dropped (margin-only frames no longer zero e_available_margin). - Foreign-fill skip on shared VST account (PRODGREEN collision filter). - exec_router TTL: entry-requote venue-truth gate (recent own fill + live exchange position probes prevent double-entry). - bingx_direct: openOrders fetched BEFORE positions (sequential ordering prevents dangerous tear → double-entries). - Dual-leverage translation via map_internal_conviction_to_exchange_leverage() (strategy conviction → integer at-exchange leverage, bankers rounding). - BLUE-parity alpha components wired: asset picker (IRP universe ranking) + alpha sizer (cubic-convex dynamic leverage, 0.5-8.0 range). - ch_writer: date_time_input_format=best_effort on insert URLs; flush error logging at WARNING with counter. - blue_parity.price_of(): hyphen-tolerant fallback (FET-USDT → FETUSDT). - Fill test updated to incremental filled_size semantics (BingX WS lastFilledQty). - Env-override base URLs, supervisord autorestart, per-asset DC histories, single-slot invariant, fill-attribution filter. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
@@ -1080,6 +1080,13 @@ class ExecutionKernel:
|
||||
slots = [self._get_slot(i) for i in range(self.max_slots)]
|
||||
self.account.observe_slots(slots)
|
||||
for current in slots:
|
||||
# Anchor the settle baseline to the adopted slot's realized_pnl.
|
||||
# _last_settled_pnl starts empty each process; without this, the
|
||||
# first venue event on a reconcile-adopted slot settles the slot's
|
||||
# ENTIRE carried realized_pnl into AccountProjection as if it were
|
||||
# new PnL (cross-restart double-book class, 2026-06-11).
|
||||
self._last_settled_pnl[current.slot_id] = float(current.realized_pnl or 0.0)
|
||||
self._slot_was_closed[current.slot_id] = bool(current.closed)
|
||||
self.projection.write_slot(current)
|
||||
self.zinc_plane.write_slot(current)
|
||||
return outcome
|
||||
@@ -1175,9 +1182,18 @@ class ExecutionKernel:
|
||||
Safe to call on a fresh kernel (e.g. after startup) before any trades.
|
||||
"""
|
||||
try:
|
||||
return _get_rust().restore_state(self._backend, json_str)
|
||||
ok = _get_rust().restore_state(self._backend, json_str)
|
||||
except (ValueError, json.JSONDecodeError):
|
||||
return False
|
||||
if ok:
|
||||
# Re-anchor settle baselines to restored slot state (same
|
||||
# cross-restart double-book guard as reconcile_from_slots).
|
||||
self.state.refresh()
|
||||
for slot_id in range(self.max_slots):
|
||||
restored = self._get_slot(slot_id)
|
||||
self._last_settled_pnl[slot_id] = float(restored.realized_pnl or 0.0)
|
||||
self._slot_was_closed[slot_id] = bool(restored.closed)
|
||||
return ok
|
||||
|
||||
def is_capital_frozen(self) -> bool:
|
||||
"""Return True if the kernel's capital is frozen (reconcile ERROR active).
|
||||
|
||||
Reference in New Issue
Block a user