Commit Graph

1024 Commits

Author SHA1 Message Date
jaxperro 0feb1e94fe copybot state: remove phantom orphan + finalize ghost (ledger drift 36.35 -> 0)
The Set D restart surfaced a $36.35 ledger drift (self-check working). Two
residues from the _record_lag skip on ArbTrader (now dropped): (1) an orphan
Total-Sets position in my_pos whose cost was never debited from cash — the
book held a position it never paid for; removed as unpaid bug residue; (2) a
fully-sold ITF Wuning position still marked open — finalized to closed (pnl
+0.37). Drift back to 0.00. Paper book; no real money touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:18:53 -04:00
jaxperro 3adf157f9d docs: P&L survivorship correction + Set D follow set (FINDINGS + README)
FINDINGS: new sections on the realizedPnl backbone (killed 4 P&L bugs) and
the anti-survivorship abandoned-loser fold-in (PM /profit is itself biased;
our All-Time is the honest number where it reads below PM), plus the Set D
follow-set selection by simulation. README: follow set is now Set D (6
moderate-bet volume wallets); whale follow-all class retired.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:13:43 -04:00
jaxperro 041f1c4291 follow set -> Set D: LSB1, imwalkinghere, Kruto2027, 42021, 0xbadaf319, BikesAreTheBikes
Rebuilt the live follow set from the corrected data. Dropped fortuneking
(weak copy P&L), iohihoo (negative 30d form), and Stavenson/0x4bFb-whale/
ArbTrader (no longer qualify as sharps post-truth-scoring). Added 42021,
0xbadaf319, BikesAreTheBikes. All 6 clear the 2-month copy P&L signal + the
30d conviction form + copyable lead, and are moderate-bet (fit a $1k book,
0 missed). 30d backtest: $27,799 (+2680%, 279W/75L) vs the old set's $16k.
backtest.json matched so the dashboard replays the live set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:11:49 -04:00
copybot[bot] 5347b9fc2c copybot: live paper feed [skip ci] 2026-07-08 02:09:47 +00:00
jaxperro ed3880bf71 copybot: follow-set update (deploy_bot.sh) 2026-07-07 22:09:25 -04:00
copybot[bot] 19a4c402d6 copybot: live paper feed [skip ci] 2026-07-08 02:07:49 +00:00
copybot[bot] db39bc1616 copybot: live paper feed [skip ci] 2026-07-08 02:05:42 +00:00
copybot[bot] 25ef0e3ea7 copybot: live paper feed [skip ci] 2026-07-08 02:03:35 +00:00
copybot[bot] f61712a442 copybot: live paper feed [skip ci] 2026-07-08 01:51:15 +00:00
jaxperro 09e511cc2e backtest: fold in-window abandoned losers into the replay (consistency with sharps)
The replay selected trusted conviction bets + sold round-trips + chain
settlement, but abandoned losers (bets held to a decided outcome, never
redeemed — /positions at curPrice 0, not in /closed-positions, not trusted
rows on operator-resolved markets) fell out entirely, reading optimistic.
resolved_unredeemed() now pulls them; window_bets folds in the in-window,
conviction-size ones at their decided outcome (loser pays 0). Same anti-
survivorship correction as the sharps table's _open_split.

Impact on the follow-set 30d backtest is ~0 ($16,255->$16,260): those 8
wallets are clean, AND abandoned-loser survivorship is an all-time
ACCUMULATION (oliman2: 1123 losers lifetime, only 2 in any 30d window), so a
30d period metric structurally can't surface much of it. The fix guarantees
no in-window loss is dropped and keeps the backtest consistent with the
all-time sharps view where survivorship actually lives. Verified the fold-in
fires (oliman2's 2 in-window conviction losers identified).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 21:44:52 -04:00
jaxperro c647e569c0 feeds: capped-exit sharps + backtest refresh; pinned paper-bot floors
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 21:23:33 -04:00
jaxperro c6ca8ad82c P&L: fold abandoned losers into realized (anti-survivorship) — All-Time is the truth, not PM
Resolved-but-unredeemed positions (bets that lost, went to $0, never
redeemed) were sitting in Open P&L, breaking the All-Time+Open=PM reconcile
and — worse — hiding real losses. _open_split now routes decided positions
(curPrice pinned 0/1) into the REALIZED total at their outcome, leaving only
genuinely in-flight positions in Open P&L. This is the project's founding
survivorship insight applied to P&L: PM /profit under-counts abandoned
losers unevenly, so where our All-Time reads lower than PM, PM is biased and
ours is honest. oliman2 $181k->$20k (walked from $161k of losers),
JuiceFarm $380k->$32k; clean wallets unchanged (ewww1 $409k, KBO30 ~PM).
Win% now counts abandoned losers too. Verified: Coteykens/imwalkinghere/KBO30
now ~PM; oliman2/JuiceFarm correctly far below their flattering PM.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 21:19:07 -04:00
copybot[bot] c3e1c36562 copybot: live paper feed [skip ci] 2026-07-08 01:06:28 +00:00
jaxperro 7b1e86685a copybot: feed reconciles my_pos -> bets so open_count matches the visible table
A position can land in my_pos without a bet record when its buy fill is
drained in a context where _record_lag doesn't fire (e.g. a second market on
the same event in one batch): cash-correct (open_count/deployed read my_pos)
but INVISIBLE in the feed table — the header showed '2 open / $75 deployed'
while only 1 bet rendered. write_feed now synthesizes a bet record from any
open my_pos position lacking one, so the count always equals what's shown.
Ledger was unaffected (drift -0.0) — display-only. my_pos entries now carry
'wallet' for proper name attribution on the synthesized record.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 21:05:47 -04:00
jaxperro b2a4a03d5b feeds: capped-exit sharps + backtest refresh; pinned paper-bot floors
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 20:57:17 -04:00
jaxperro 6fd2e30752 sharps: add Open P&L (unrealized open-book exposure) column
_open_pnl(w) sums cashPnl over the wallet's current positions (full paging).
Surfaces the sells-winners-holds-losers risk that the realized track record
hides: All-Time (realized) + Open P&L reconciles to PM P&L. A wallet with a
strong realized record but a large negative open book flatters live-follow
experience — now visible instead of inferred from the PM gap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 20:42:55 -04:00
jaxperro 2395024a8f P&L mirrors PM: All-Time/Conv P&L = realized track record (realizedPnl)
The sharps table's P&L was reconstructed from won×entry×size and diverged
from PM /profit by up to 10x, with sign flips — four root causes found by
decomposing outliers against PM:
  1. bets pull capped at 2000 rows/180d -> high-volume wallets truncated
     (ewww1: 740 of 4088 positions cached -> k shown vs k real)
  2. both-sides (hedged) markets: one-per-market dedup dropped the paired
     side (suraxy: -k of dropped losing legs -> overcount)
  3. initialValue=0 on big longshot winners -> mis-sized reconstruction
  4. corrupt near-epoch res_t rows polluting sums

Fix: All-Time/Conv/30d P&L are now the sum of Polymarket's OWN realizedPnl
per closed position over FULL history (cache.closed_exits, extended to store
realized_pnl; smart_money.closed_exits captures it + relaxes the avg/tb
guard). This is the wallet's realized track record — what a copier mirroring
buy/sell/hold banks — and sums to PM. Immune to all four bugs (each asset is
its own realized row; no size/entry/res_t needed). Win% = share of closed
positions that made money. Verified vs PM: ewww1 1.00x, KBO30 0.0x->0.97x,
suraxy 2.7x->1.03x, sign flip fixed; oliman2 1.63x is correct-by-design
(realized track record vs PM's open-book unrealized marks). README gotcha 11
rewritten; dashboard tooltips reframed off the copy-ceiling language.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 20:28:09 -04:00
copybot[bot] c90c501eb3 copybot: live paper feed [skip ci] 2026-07-07 23:44:31 +00:00
jaxperro bb4ec2b905 feeds: capped-exit sharps + backtest refresh; pinned paper-bot floors
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 19:42:44 -04:00
copybot[bot] 873f4efa6c copybot: live paper feed [skip ci] 2026-07-07 22:07:52 +00:00
copybot[bot] 796149b36b copybot: live paper feed [skip ci] 2026-07-07 21:14:38 +00:00
copybot[bot] 0e57b9fd03 copybot: live paper feed [skip ci] 2026-07-07 20:53:50 +00:00
copybot[bot] b5db8f4602 copybot: live paper feed [skip ci] 2026-07-07 20:49:38 +00:00
copybot[bot] c2fdc4a888 copybot: live paper feed [skip ci] 2026-07-07 20:05:58 +00:00
copybot[bot] 3f3986c1bb copybot: live paper feed [skip ci] 2026-07-07 19:49:11 +00:00
copybot[bot] b5fc1c8480 copybot: live paper feed [skip ci] 2026-07-07 18:59:03 +00:00
copybot[bot] 0de8770800 copybot: live paper feed [skip ci] 2026-07-07 18:40:13 +00:00
copybot[bot] 905203f169 copybot: live paper feed [skip ci] 2026-07-07 18:38:04 +00:00
copybot[bot] 3e1e0a2e95 copybot: live paper feed [skip ci] 2026-07-07 18:29:47 +00:00
copybot[bot] 8d001d6ad2 copybot: live paper feed [skip ci] 2026-07-07 18:27:36 +00:00
copybot[bot] f3a1a9acbb copybot: live paper feed [skip ci] 2026-07-07 18:25:33 +00:00
copybot[bot] b0a4ef46ea copybot: live paper feed [skip ci] 2026-07-07 18:06:33 +00:00
copybot[bot] aaddee4330 copybot: live paper feed [skip ci] 2026-07-07 17:58:13 +00:00
copybot[bot] 369dbbfd9d copybot: live paper feed [skip ci] 2026-07-07 17:47:49 +00:00
copybot[bot] 495511014f copybot: live paper feed [skip ci] 2026-07-07 17:43:40 +00:00
copybot[bot] 70b8400036 copybot: live paper feed [skip ci] 2026-07-07 17:33:24 +00:00
copybot[bot] cce9adf0ae copybot: live paper feed [skip ci] 2026-07-07 16:21:44 +00:00
copybot[bot] a15da180b3 copybot: live paper feed [skip ci] 2026-07-07 16:11:32 +00:00
copybot[bot] 36c5855fa6 copybot: live paper feed [skip ci] 2026-07-07 15:57:17 +00:00
jaxperro 2b33ec5683 exits: FULL history, no window, no cap (holistic data > speed)
Per the data-completeness call: closed_exits pulls each wallet's ENTIRE
closed-position history, not a 180d window. smart_money.closed_exits returns
(exits, reached_end) — reached_end True only when the pull hits the true
start of history (empty/short page), so the cache's  flag tells a
finished backfill from an interrupted one and a killed deep pull re-completes
instead of falsely reporting done. One-time deep cost, amortized by the
incremental cache (later runs page only new closes). Verified: imwalkinghere
full 65d lifetime (879 exits, its real age not a cap), complete=True, 2nd
call 0.00s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:49:17 -04:00
jaxperro 6d59b354ee exits: bound by the 180d SCORED WINDOW, not a row cap (holistic + fast)
The row cap was the wrong instrument — it could truncate a hyperactive
wallet's window (compromising data) while the real fix is bounding by DATE.
cache.closed_exits now pulls exactly the 180d window the bets cache scores,
so the exit overlay COMPLETELY covers every bet the sharps/backtest stats
touch. Tracks oldest_ts so an interrupted backfill re-completes instead of
falsely reporting done; once complete, refreshes only page new closes.
since_ts (180d/30d per caller) is the real bound — this fixes completeness
AND the runtime stall (the old since_ts=0 pulled all-history). Verified:
imwalkinghere full window in 9s, 2nd call 0.00s cached.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:45:04 -04:00
copybot[bot] 3b6ab663e8 copybot: live paper feed [skip ci] 2026-07-07 15:40:58 +00:00
jaxperro 5a7434c374 closed_exits: cap first-backfill depth 25k->4k rows (bounded daily runtime)
The 25k-row (500-page) full-history backfill × 90 sharp wallets stalled the
daily pipeline for 4+ hours on its first uncached pass. 4000 rows (80 pages)
covers the 30d backtest and most of the 180d display window; the exits cache
is incremental so the horizon extends on later runs. Extreme scalpers keep a
hold-to-res ceiling on their deepest history (honest, and none are followed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:40:15 -04:00
copybot[bot] a62cbf0985 copybot: live paper feed [skip ci] 2026-07-07 15:34:50 +00:00
jaxperro 972b32e8f0 CRITICAL: fix their_prev crash that silently killed all new opens since 07-05
_handle_their_buy referenced their_prev in the fresh-OPEN branch but only
assigned it in the is_add branch — every new position crashed with
UnboundLocalError the moment the their-bet ceiling landed 2026-07-06. The
webhook/heartbeat try/except swallowed it as 'handler error', so the bot
logged FOLLOW then silently placed NOTHING (last real fill 07-05 23:17;
live Fly logs show FOLLOW ArbTrader ... -> heartbeat error: their_prev).
This is the primary cause of 'live bot missing bets'. Fix: hoist their_prev
above the if/else so both branches see the signal's prior position.

Also (the user's two asks):
- copybot on_wallet_activity: a QUALIFYING bet we were too slow to catch
  (webhook missed / bot down / fast market resolved before we polled) is now
  recorded as a missed bet 'too slow to follow (Nm late)' instead of silently
  dropped; below-floor dust stays console-only. Filter runs before the stale
  gate so we know if it would have qualified.
- sync_floors.py rewritten: PIN each paper-bot wallet's floor to the trusted
  cache p80 (identical to the backtest's conv_thr), written to
  copybot.paper.json, wired into daily.sh + committed. Kills the boot-time
  data-api floor drift (fortuneking $1,498 boot vs $892 backtest) that made
  the live bot filter out bets the backtest kept.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:33:36 -04:00
copybot[bot] c002c45e5b copybot: live paper feed [skip ci] 2026-07-07 15:06:01 +00:00
jaxperro b6cb2e53b2 SECURITY: drop leaked alchemy_key from config.live.example.json
The key does not belong in any committed file — the worker reads the RPC
from ALCHEMY_RPC_URL env (or the gitignored config.json locally). Rotating
the key is the real fix (it hit the public repo history); this removes it
from HEAD.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:02:14 -04:00
jaxperro 686c1cfcce config.live.example.json: committed secret-free live-test config (Phase 1.7)
config.live.json is gitignored (holds the key) so the Fly worker can't see
it. This committed twin carries the synced 8-wallet follow set + $5 test
caps + separate feed/fills; the worker reads it and injects the key via
LIVE_PRIVATE_KEY env (copybot 1.2). Mac path: cp to config.live.json, fill
the key. Fixes 'stale shisan888 follow set' + the cloud-config gap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:01:27 -04:00
jaxperro 0e95ab1bf3 live-rollout Phase 1 (partial) + discord ping post-wake retry
copybot.py:
- 1.1 feed_path/fill_log are config-driven (live run won't clobber the
  paper book's feed or fills ledger)
- 1.2 LIVE_PRIVATE_KEY / LIVE_FUNDER_ADDRESS / LIVE_SIGNATURE_TYPE env
  overrides (Fly worker has no gitignored config.live.json)
- 1.4 chain_cash_gap(): live-only book-cash vs CLOB USDC balance, logged
  as ⚠ CASH≠CHAIN (the real-money ledger_drift)
- 1.5 geo-gate is FATAL in live mode — unauth order probe; refuses to arm
  from a 403-geo-blocked box before the confirm phrase (verified: refuses
  from this US Mac)
- 1.6 mirror-exit retry: FAK sells that fill 0 on thin books retry each
  backstop poll, ⚠ EXIT STUCK alert after 10 unfilled attempts

discord_daily.py: --ping retries 4x (5/10/15s) — launchd wakes the Mac to
run daily.sh and the heads-up ping was racing DNS/WiFi coming up after
sleep (getaddrinfo 'nodename nor servname'); the end-of-run digest always
landed, only the start ping lost the race.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:59:07 -04:00
copybot[bot] 1608b5b06a copybot: live paper feed [skip ci] 2026-07-07 14:20:18 +00:00