config format matches backtest.json — one entry per wallet:
wallets: [{wallet, name, class: volume|whale, floor?}]
normalize_follow_config expands it into the legacy watchlist/watch/
floors/classes structures (old-format configs like config.live.json
pass through untouched). Volume wallets without an explicit floor get
an auto p80 derived from the data-api at boot (the worker has no cache),
logged and published in the feed. live/deploy_bot.sh = validate ->
preview -> commit -> push -> railway redeploy -> confirm boot.
Promotion workflow: prove a wallet in backtest.json, copy the same
entry into copybot.paper.json, run deploy_bot.sh.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* validate_timing.display_stats adds all_win/all_won/all_lost/all_pnl —
the wallet's record and own P&L over EVERY resolved bet ever cached,
trusted rows only, deduped one-per-market (feeds the dashboard's new
All-Time columns); consensus temp table now built before the pool
* copybot write_feed adds classes {name: volume|whale} so the dashboard
can badge whale-class wallets
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
portfolio.py now replays ANY wallet set over a rolling N-day window
(default 30) instead of the hardcoded four-from-June-1:
* live/backtest.json: {days, stake_cap_usd, class_pct, wallets:[{wallet,
name, class}]} — edit to add/remove/swap wallets; seeded with the paper
bot's current 7-wallet follow set
* class parity with the bot: 'whale' replays EVERY trusted bet at
class_pct.whale of equity; 'volume' replays conviction bets at
class_pct.volume, p80 threshold from PRE-window bets only (no peeking)
* outcomes read through trust.py (trusted rows) so any pasted-in wallet
is scored honestly, not on cache marks
* ad-hoc CLI that leaves the dashboard feed alone:
python3 portfolio.py --wallets 0xabc,0xdef:whale --days 14 --out /tmp/t.json
* fix: open positions with unknown entry time used to sort at t=0 and
drain the bankroll before any historical bet ran; they now queue at the
end (and pre-window entries are excluded)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirror-exits were correct at book level (cash/fees) but invisible per bet:
a fully mirror-sold bet went to 'closed' with pnl null, and a TRIMmed bet
that later resolved subtracted its ORIGINAL cost+fee while ignoring the
sold leg's proceeds — understating whole-bet pnl on the feed.
* _drain_fills links every SELL fill to its bet record
(sold_shares / sold_proceeds, net of taker fee)
* write_feed: full mirror-sell -> pnl = sold_proceeds − cost − entry fee,
plus exit_price; dashboard's existing 'mirror-sold with recorded P&L'
branch picks it up
* settle_resolved: pnl = resolution proceeds + sold leg − original cost −
entry fee (pos.cost is trim-reduced; bet.cost is the original)
Sandbox-tested: TRIM cash+record, TRIM->WIN whole-bet truth, full EXIT
feed reconcile all agree to the cent.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Whale-class wallets bypass min_their_usd and per-wallet floors entirely:
both current whales win ~92% across their ENTIRE book (Stavenson 469-39,
0x4bFb 862-72 all-time trusted; 99.2% last 30d for the whale), so
size-filtering them only costs flow. The 0.95 entry cap stays (execution
guard, validated). Floors removed from the paper config for both.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
follow.stake_mult ({address: mult}) scales the equity fraction for that
wallet's signals; drawdown brake and stake cap still apply, and the
profit-ratchet sweep threshold stays on the BASE fraction so which wallet
happens to trade doesn't change when profits get banked. Verified: $40
base stake -> $120 for the two, $40 for everyone else, case-insensitive.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The list is for wallets a copier gets real flow from; dormant or
low-frequency edges (however good) don't belong on it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* per-trade Discord pings removed everywhere: copybot placement/settle/startup
alerts silenced (engine.webhook forced off), webhook_receiver.py archived,
Procfile removed. The ONLY Discord output is now live/discord_daily.py at the
end of the daily pipeline: one embed listing every watch_sharps wallet with a
Polymarket profile link + 30D conviction win% / record / P&L.
* trust.py fixes found on the first scheduled run (sharp list collapsed 25->7):
- Polymarket rewrites endDate after resolution, so freshly re-pulled wallets'
corrected res_t stopped matching the stale cross-wallet consensus
(374/454 of iohihoo's rows wrongly distrusted). v2 rows with resolved=TRUE
are now self-certifying (resolved=TRUE implies endDate-based res_t observed
post-end) — consensus only gates legacy rows.
- daily.sh invalidates watchlist wallets by DELETING their pulled row; a
transiently failed re-pull then dropped the wallet's entire history from
the trusted set (the 0x73afc816 whale vanished). Legacy rows of wallets
missing from pulled now fall back to trusting markets resolved >=14d ago.
Re-run: 85 conviction wallets, 34 copy-positive sharps — whale/iohihoo/
Stavenson/LSB1/Kruto all recovered.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>