9 Commits

Author SHA1 Message Date
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
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
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
jaxperro fb462b7168 exits: fix the 50-row page cap + incremental exits cache in duckdb
/closed-positions serves 50-row pages regardless of limit; stepping by the
requested size truncated every wallet's exit history to its most recent ~50
closes (1% coverage for hyperactive wallets) — sold-mirroring was silently
falling back to the hold-to-res ceiling almost everywhere. Now: page by
returned size, cache exits incrementally in duckdb (immutable events —
deep backfill once, a page or two per refresh; title/outcome columns for
display). Deep-exit 30d replay: $18,270 (+1727%), 259W/79L/29R/284S,
misses 253 -> 1 (mirrored exits recycle capital as fast as the signal does).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:27:30 -04:00
jaxperro 72245e4053 sharps stats mirror exits too (SOLD) — one exit model across all three books
smart_money.closed_exits() is now the shared implementation (backtest +
sharps): close time from /closed-positions, exit price reconstructed from
realized P&L. validate_timing's conv/conv30/all-time/realized tallies count
a bet the wallet sold pre-resolution at its exit price (conv_sold /
conv30_sold / all_sold fields) instead of pretending it rode to resolution.
Beyond the ~4000-row data horizon exits fall back to hold-to-res.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 03:18:41 -04:00
jaxperro 29a4bcca9e harden pipeline against dropped connections; publish fee-aware sharps
- get_json: catch OSError + http.client.HTTPException (RemoteDisconnected/
  IncompleteRead escaped the retry loop and killed last night's validate_timing
  run on a single dropped keep-alive).
- validate_timing: per-wallet retry+exclude guard so one bad wallet can't take
  out the whole selection; regenerated watch_sharps.json — the first fee-aware,
  resolved-only sharp list (10 copy-positive holders of 254).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 09:15:42 -04:00
jaxperro a426b8bb05 Fix survivorship-biased win rate; add backtest, per-position cap, Discord alerts
The scanner measured win rate over /closed-positions only, but Polymarket
only redeems winning shares — losers sit unredeemed in /positions at
curPrice 0 and never enter closed-positions. That made win rates wildly
inflated (e.g. 90.6% vs a true 48.3%). Win rate now unions both endpoints
over a 90-day window. With the honest metric, ~no top wallet exceeds ~60%;
true rates cluster near 50%.

Also:
- backtest.py: replay a watchlist over a recent window, fill at historical
  price, mark outcomes from resolution. A 7d run of 4 top wallets returned
  -48%, confirming flat-size entry-copying is -EV at ~50% hit rates.
- copytrade.py: add max_position_usd cap (proportional adds could otherwise
  balloon one position to the whole exposure limit) and Discord webhook
  alerts on every would-be trade.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 23:25:59 -04:00
jaxperro 5ed55009b5 Polymarket smart money tracker: find >75% win-rate wallets betting weekly
Dashboard + terminal tool that pulls the 7d/30d/all leaderboards, measures
each wallet's win rate over its most recent resolved bets, and its distinct
markets traded per week. Zero dependencies (Python 3 stdlib only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 22:03:00 -04:00