PINK: docs v7 + reset_and_seed startup fix — 451/451 tests green
- SYSTEM_BIBLE.md → v7.0: documents fee-sign fix (Defect A), opening-fee fix (Defect B), WARN-unfreeze, orphan prevention, reset_and_seed startup, and vel_div env-override. - CAPITAL_BOOKKEEPING_DESIGN.md: status updated to PHASE-1 BUGFIXES APPLIED; sections 8.1-8.4 (applied fixes + 34-test coverage) were already present. - rust_backend.py: expose dita_kernel_reset_and_seed() via _RustKernelLib + ExecutionKernel.reset_and_seed(); zeros stale K-accumulators at startup so K=E=live_capital → delta=0 → capital_frozen=False on every clean restart. - pink_direct.py: call kernel.reset_and_seed(live_capital) after _restore_kernel_snapshot() so BingX is always the ledger of record. - launch_dolphin_pink.py: DOLPHIN_PINK_VEL_DIV_THRESHOLD env-var override for on-exchange debugging; BLUE unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# PINK Capital & Trading Bookkeeping Refactor — Design Spec
|
||||
|
||||
**Status**: DESIGN (pre-implementation)
|
||||
**Date**: 2026-06-07
|
||||
**Status**: PHASE-1 BUGFIXES APPLIED (2026-06-08) — fee sign + opening-fee + WARN-unfreeze all fixed and green (34/34 tests). Multi-phase bookkeeping refactor remains pending.
|
||||
**Date**: 2026-06-07 (design); 2026-06-08 (critical patch applied)
|
||||
**Author**: Crush AI, per PINK operator directive
|
||||
**Scope**: Refactor PINK to use DITAv2 kernel's accounting as the single bookkeeping authority, eliminate double-accounting, maintain BLUE observability compatibility
|
||||
|
||||
|
||||
@@ -174,6 +174,8 @@ class _RustKernelLib:
|
||||
self.lib.dita_kernel_snapshot_json.restype = ctypes.c_void_p
|
||||
self.lib.dita_kernel_set_seed_capital.argtypes = [ctypes.c_void_p, ctypes.c_double]
|
||||
self.lib.dita_kernel_set_seed_capital.restype = ctypes.c_int
|
||||
self.lib.dita_kernel_reset_and_seed.argtypes = [ctypes.c_void_p, ctypes.c_double]
|
||||
self.lib.dita_kernel_reset_and_seed.restype = ctypes.c_int
|
||||
self.lib.dita_kernel_set_exchange_config_json.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
|
||||
self.lib.dita_kernel_set_exchange_config_json.restype = ctypes.c_int
|
||||
self.lib.dita_kernel_calibrate_fee_json.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
|
||||
@@ -293,6 +295,10 @@ class _RustKernelLib:
|
||||
rc = self.lib.dita_kernel_set_seed_capital(handle, ctypes.c_double(seed))
|
||||
return rc == 0
|
||||
|
||||
def reset_and_seed(self, handle: ctypes.c_void_p, capital: float) -> bool:
|
||||
rc = self.lib.dita_kernel_reset_and_seed(handle, ctypes.c_double(capital))
|
||||
return rc == 0
|
||||
|
||||
def set_exchange_config(self, handle: ctypes.c_void_p, config: Dict[str, Any]) -> bool:
|
||||
encoded = _to_rust_bytes(config)
|
||||
rc = self.lib.dita_kernel_set_exchange_config_json(handle, ctypes.c_char_p(encoded))
|
||||
@@ -1071,6 +1077,15 @@ class ExecutionKernel:
|
||||
"""Set the kernel's seed capital for K-value fold. Call once at init."""
|
||||
_get_rust().set_seed_capital(self._backend, float(seed))
|
||||
|
||||
def reset_and_seed(self, capital: float) -> None:
|
||||
"""Reset K-accumulators and re-seed from live exchange balance.
|
||||
|
||||
Replaces set_seed_capital() at the end of connect(): zeros k_realized_pnl,
|
||||
all fee counters, and k_funding_net so K = E = capital → delta = 0 → unfrozen.
|
||||
Preserves seen_account_event_ids (WS replay dedup) and fee calibration.
|
||||
"""
|
||||
_get_rust().reset_and_seed(self._backend, float(capital))
|
||||
|
||||
def set_exchange_config(self, config: Dict[str, Any]) -> None:
|
||||
"""
|
||||
Load the exchange fee schedule into the kernel's fee prediction model.
|
||||
|
||||
@@ -321,10 +321,14 @@ class PinkDirectRuntime:
|
||||
self.kernel.set_seed_capital(live_capital)
|
||||
await self._seed_account_from_exchange()
|
||||
|
||||
# Restore fee calibration + account state from the previous session if the
|
||||
# kernel was flat at save time. Must be AFTER set_seed_capital and reconcile
|
||||
# so the snapshot can override our fresh seed with the last-known calibration.
|
||||
# Restore fee calibration from the previous session if the kernel was flat
|
||||
# at save time. Must be AFTER set_seed_capital so the snapshot can carry
|
||||
# forward fee model parameters. Re-apply live_capital immediately after to
|
||||
# ensure BingX is the ledger of record for capital — the snapshot's capital
|
||||
# is stale (it reflects the exchange balance at the PREVIOUS session's last
|
||||
# fill), whereas live_capital was just fetched from BingX right now.
|
||||
_restore_kernel_snapshot(self.kernel, self.logger)
|
||||
self.kernel.reset_and_seed(live_capital) # zeros stale accumulators; K=E=live_capital
|
||||
|
||||
# Start WS account stream (primary); poll failover handled inside stream.
|
||||
self._account_stream_task = asyncio.create_task(
|
||||
|
||||
2441
prod/docs/SYSTEM_BIBLE.md
Normal file
2441
prod/docs/SYSTEM_BIBLE.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -285,9 +285,12 @@ def _build_runtime(*, phase: PinkPhase) -> PinkDirectRuntime:
|
||||
market_state_runtime = MarketStateRuntime()
|
||||
|
||||
# Decision and intent policy — unchanged from BLUE semantics.
|
||||
# DOLPHIN_PINK_VEL_DIV_THRESHOLD: relax for on-exchange debugging (e.g. -0.005).
|
||||
# Default -0.02 matches BLUE production. BLUE is unaffected.
|
||||
_vel_div_threshold = float(os.environ.get("DOLPHIN_PINK_VEL_DIV_THRESHOLD", "-0.02"))
|
||||
cfg = DecisionConfig(
|
||||
vel_div_threshold=-0.02,
|
||||
vel_div_extreme=-0.05,
|
||||
vel_div_threshold=_vel_div_threshold,
|
||||
vel_div_extreme=min(_vel_div_threshold * 2.5, -0.001),
|
||||
fixed_tp_pct=float(os.environ.get("DOLPHIN_FIXED_TP_PCT", "0.0020")),
|
||||
max_hold_bars=int(os.environ.get("DOLPHIN_MAX_HOLD_BARS", "250")),
|
||||
capital_fraction=0.20,
|
||||
|
||||
Reference in New Issue
Block a user