fix: remove broken auto-absorb (caused exponential drift feedback loop)
The auto-absorb added -drift to adjustments, but adjustments are part of the ledger_drift calculation, so each absorb DOUBLED the drift next heartbeat: -> -> -> -> ... -> ,139,590 in 20 minutes. Reverted to only anchoring cash to chain (CASH≠CHAIN fix), which works correctly. LEDGER DRIFT is now just a warning (cosmetic accounting issue that doesn't affect trading). If it bothers you, the manual fix (stop, query chain, clear state, restart) still works. Added NOTE comment explaining why auto-absorbing ledger_drift via adjustments creates a feedback loop.
This commit is contained in:
+7
-20
@@ -1713,16 +1713,15 @@ class Copybot:
|
||||
bankstr = f" · banked ${reserve:,.0f}" if reserve else ""
|
||||
drift = self.ledger_drift()
|
||||
gap = self.chain_cash_gap()
|
||||
# ponytail: auto-anchor to chain - proxy instability causes untracked
|
||||
# fills leading to LEDGER DRIFT and CASH≠CHAIN. Two corrections:
|
||||
# 1. If chain cash differs from book cash -> set book cash = chain
|
||||
# 2. If ledger still drifts after cash correction -> absorb into adjustments
|
||||
# Ceiling: this masks real bugs if a position is truly untracked, but
|
||||
# the chain balance already reflects all real positions' cost.
|
||||
if self.engine.ex.live and gap is not None:
|
||||
# ponytail: auto-anchor cash to chain when CASH≠CHAIN > $1. Proxy
|
||||
# instability causes untracked fills; the chain is the source of truth.
|
||||
# NOTE: do NOT try to auto-fix LEDGER DRIFT via adjustments - it creates
|
||||
# a feedback loop (adjustment changes the drift calc, which doubles the
|
||||
# drift next heartbeat, exponentially). LEDGER DRIFT is a cosmetic
|
||||
# accounting issue that doesn't affect trading; just warn on it.
|
||||
if self.engine.ex.live and gap is not None and abs(gap) > 1.0:
|
||||
chain_bal = self._chain_bal[1]
|
||||
book_cash = self.engine.state.get("cash", bank)
|
||||
# 1. anchor cash to chain
|
||||
if chain_bal is not None and abs(chain_bal - book_cash) > 1.0:
|
||||
self.engine.state["cash"] = chain_bal
|
||||
self.engine.state.setdefault("adjustments", []).append({
|
||||
@@ -1734,18 +1733,6 @@ class Copybot:
|
||||
log(f"chain anchor: book cash ${book_cash:.2f} -> chain ${chain_bal:.2f} "
|
||||
f"(gap ${gap:+.2f}, auto-corrected)")
|
||||
gap = 0
|
||||
drift = self.ledger_drift()
|
||||
# 2. absorb residual ledger drift into adjustments
|
||||
if abs(drift) > 0.50:
|
||||
self.engine.state.setdefault("adjustments", []).append({
|
||||
"ts": time.time(),
|
||||
"amount": -drift,
|
||||
"note": f"auto-absorb ledger drift ${drift:+.2f}"
|
||||
})
|
||||
self.engine.persist()
|
||||
log(f"auto-absorb ledger drift ${drift:+.2f} (untracked fill, "
|
||||
f"chain cash OK at ${chain_bal:.2f})")
|
||||
drift = 0
|
||||
driftstr = f" · ⚠ LEDGER DRIFT ${drift:+.2f}" if abs(drift) > 0.05 else ""
|
||||
if gap is not None and abs(gap) > 0.5:
|
||||
driftstr += f" · ⚠ CASH≠CHAIN ${gap:+.2f}"
|
||||
|
||||
Reference in New Issue
Block a user