fix: auto-anchor book cash to chain pUSD (no more daily manual drift fix)
Root cause: proxy instability causes order verification calls (get_order, _shares_held) to fail, leading to untracked fills and persistent CASH≠CHAIN drift. Required manual state clearing every day. Fix: in summary() heartbeat, when chain_cash_gap > , automatically set book cash = chain pUSD balance and record the adjustment. The chain is the source of truth, not the bot's tracking. This eliminates the daily manual fix cycle: stop bot -> query chain -> set bankroll -> clear state -> restart The bot now self-heals on every heartbeat (every 60s). If a fill was untracked, the next heartbeat detects the gap and corrects cash to match chain reality. Positions on chain are unaffected - only the cash tracking is anchored. ponytail: adds one get_balance_allowance call per heartbeat (already cached for 60s in _chain_bal). Adjustment logged for audit trail.
This commit is contained in:
+18
@@ -1715,6 +1715,24 @@ class Copybot:
|
||||
driftstr = f" · ⚠ LEDGER DRIFT ${drift:+.2f}" if abs(drift) > 0.05 else ""
|
||||
gap = self.chain_cash_gap()
|
||||
if gap is not None and abs(gap) > 1.0: # ≥$1: beyond fee/rounding float
|
||||
# ponytail: auto-anchor book cash to chain pUSD - the chain is the
|
||||
# source of truth, not the bot's tracking. Proxy instability causes
|
||||
# order verification calls to fail, leading to untracked fills and
|
||||
# persistent CASH≠CHAIN drift. Instead of warning and requiring
|
||||
# manual state clearing every day, correct book cash to match chain.
|
||||
chain_bal = self._chain_bal[1]
|
||||
book_cash = self.engine.state.get("cash", bank)
|
||||
self.engine.state["cash"] = chain_bal
|
||||
self.engine.state.setdefault("adjustments", []).append({
|
||||
"ts": time.time(),
|
||||
"amount": chain_bal - book_cash,
|
||||
"note": f"chain anchor: cash {book_cash:.2f} -> {chain_bal:.2f}"
|
||||
})
|
||||
self.engine.persist()
|
||||
log(f"chain anchor: book cash ${book_cash:.2f} -> chain ${chain_bal:.2f} "
|
||||
f"(gap was ${gap:+.2f}, auto-corrected)")
|
||||
gap = 0 # corrected, don't show the warning
|
||||
if gap is not None and abs(gap) > 0.5:
|
||||
driftstr += f" · ⚠ CASH≠CHAIN ${gap:+.2f}"
|
||||
rtds = getattr(self, "rtds", None)
|
||||
if rtds is not None:
|
||||
|
||||
Reference in New Issue
Block a user