copybot: wallet classes replace raw multipliers — 'volume' 4% / 'whale' 12%

follow.wallet_class marks each wallet (default: volume); follow.class_pct
maps class -> equity fraction. Stavenson + 0x4bFb-whale are whales at 12%,
everyone else rides volume at 4%. Drawdown brake, stake cap, and the
base-fraction sweep threshold unchanged. Verified: $120 whale / $40 volume.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jaxperro
2026-07-04 19:14:46 -04:00
parent b6b2e6baf6
commit 5c0e50efb2
2 changed files with 32 additions and 22 deletions
+25 -19
View File
@@ -267,36 +267,42 @@ class CopyTrader:
DD_THRESHOLD = 0.80 # below 80% of the high-water mark…
DD_FACTOR = 0.5 # …bet half size until equity recovers
def stake_mult(self, wallet=None):
"""Per-wallet stake multiplier from follow.stake_mult ({address: mult}) —
lets high-conviction wallets bet a larger equity fraction (e.g. 3.0 turns
a 4% book into 12% for that wallet). Defaults to 1."""
mults = (self.cfg.get("follow") or {}).get("stake_mult") or {}
return float(mults.get((wallet or "").lower(), 1.0))
def wallet_class(self, wallet=None):
"""'volume' (default) or 'whale', from follow.wallet_class ({address: class})."""
classes = (self.cfg.get("follow") or {}).get("wallet_class") or {}
return classes.get((wallet or "").lower(), "volume")
def stake_frac(self, wallet=None):
"""Equity fraction for this wallet's signals, by class:
follow.class_pct maps class -> fraction (e.g. volume 0.04, whale 0.12).
A class missing from class_pct falls back to bankroll_pct."""
pcts = (self.cfg.get("follow") or {}).get("class_pct") or {}
pct = pcts.get(self.wallet_class(wallet))
return self.cfg["bankroll_pct"] if pct is None else float(pct)
def stake_usd(self, wallet=None):
"""Next bet size = bankroll_pct × current WORKING equity (cash + open cost
basis), so stakes compound with the book in both directions; halved while
in a >20% drawdown from the high-water mark. Falls back to the flat static
stake when cash isn't tracked (legacy poll CLI). A per-wallet
follow.stake_mult scales the fraction for that wallet's signals (the
sweep threshold below stays on the BASE fraction so which wallet happens
to trade doesn't change when profits get banked).
"""Next bet size = the wallet's class fraction (stake_frac) × current
WORKING equity (cash + open cost basis), so stakes compound with the book
in both directions; halved while in a >20% drawdown from the high-water
mark. Falls back to the flat static stake when cash isn't tracked
(legacy poll CLI). The sweep threshold below stays on the BASE
bankroll_pct so which wallet happens to trade doesn't change when
profits get banked.
stake_cap_usd (profit ratchet): once working equity exceeds
cap/bankroll_pct — the level where stakes hit the cap — the surplus CASH
is swept into state["reserve"]: banked, never bet, immune to drawdowns.
Stakes stay pinned ~at the cap, where marketable fills are still inside
typical book depth."""
mult = self.stake_mult(wallet)
frac = self.stake_frac(wallet)
cash = self.state.get("cash")
if cash is None:
return self.cfg["bankroll_usd"] * self.cfg["bankroll_pct"] * mult
frac = self.cfg["bankroll_pct"]
return self.cfg["bankroll_usd"] * frac
base = self.cfg["bankroll_pct"]
cap = self.cfg.get("stake_cap_usd") or 0
eq = cash + self.open_exposure()
if cap and frac > 0 and eq > cap / frac:
sweep = min(cash, eq - cap / frac)
if cap and base > 0 and eq > cap / base:
sweep = min(cash, eq - cap / base)
if sweep > 0:
self.state["cash"] = cash = cash - sweep
self.state["reserve"] = self.state.get("reserve", 0.0) + sweep
@@ -305,7 +311,7 @@ class CopyTrader:
self.state["hwm"] = hwm
if eq < self.DD_THRESHOLD * hwm:
frac *= self.DD_FACTOR
stake = frac * eq * mult
stake = frac * eq
return min(stake, cap) if cap else stake
def record_miss(self, wallet, token, cond, title, outcome, price, want, reason):
+7 -3
View File
@@ -62,9 +62,13 @@
},
"min_entry": 0.0,
"max_entry": 0.95,
"stake_mult": {
"0xf5fe759cece500f58a431ef8dacea321f6e3e23d": 3.0,
"0x73afc8160c17830c0c7281a7bf570c871455b880": 3.0
"wallet_class": {
"0xf5fe759cece500f58a431ef8dacea321f6e3e23d": "whale",
"0x73afc8160c17830c0c7281a7bf570c871455b880": "whale"
},
"class_pct": {
"volume": 0.04,
"whale": 0.12
}
},
"risk": {