Root README now leads with what actually runs (Mac daily pipeline, Railway
copybot worker, Discord watcher, static dashboard), the July live test, the
realism model (fees/lag/dynamic sizing/missed-bet ledger), a new-developer
quickstart, secrets map, and file map; research story condensed with current
numbers (12 fee-aware sharps, +531% in-sample backfill clearly labeled).
live/README: fee-aware selection, dynamic-sizing portfolio, three dashboard
feeds, copybot now 24/7 on Railway (was "in progress").
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- bets table gains asset (token id = position identity), src/ts (endpoint
provenance + close time), resolved (False = early-sold in an unended market;
won is a curPrice mark). Auto-migrates v1 in place (~8s, 3,697 exact dupes
merged); legacy rows carry NULLs until their wallet refreshes.
- refresh is now an upsert by token instead of a wallet wipe: rows sliding out
of the rolling pull window survive, so per-wallet history accumulates into a
permanent archive. Same-asset rows from both endpoints (partially-closed
positions) dedupe to the larger-stake row - kills the two-endpoint
double-count class (~35k suspect pairs found in the audit).
- p stored raw (0 = avgPrice missing), clamped on read by get_bets, so missing
prices stay distinguishable from real 0.1c longshots; insider CLI + oos clamp
their own direct use.
- resolved_bets(strict=True): a failed page raises instead of returning a
silently truncated history; get_bets no longer caches or marks failed pulls
(pre-v2 an API error cached the wallet as empty-and-fresh for 14 days -
Kruto2027 was a live victim of this last night).
Verified: migration 18,289,320 -> 18,285,623 rows; forced refreshes of two
sharps show 0 same-asset dups, 0 legacy/new mixing, clamped reads, conviction
stats intact (Kruto conv win 73%).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Update the dev-facing docs so others can follow the current system:
- live/README: copy-positive-holder selection (replaces lead-time gate),
Copy P&L as the copyability metric, new Paper portfolio (portfolio.py)
+ Dashboard feeds (watch_sharps.json / portfolio.json) sections, the
full 8-step daily flow, the cache rolling-180d/replace retention gotcha,
and a Copy execution (copybot/sync_floors, separate WIP) note.
- README: top portfolio is now precomputed off the cache (correct
recycling), judge by Copy P&L not win%, copy execution is separate.
- FINDINGS: capital-recycling / $1k-book section + repo-layout refresh.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
README/FINDINGS/live/README updated for today's discovery: the sharps
win% is a position snapshot that over-counts scalpers; copy_pnl (flat-$50
replay, authoritative clob resolution) is the real copyability signal.
Most "sharps" lose copied; only Kruto2027 + fortuneking are copy-positive
(now the tracked pair). Refreshed stale counts (50 -> ~31 after the
30d-active filter) and noted position-level conviction.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The lead-time gate in validate_timing.py is a COPYABILITY heuristic, not
proof of inside information: a short entry->resolution lead can be a
genuine insider OR just someone who trades fast-resolving markets (live
sports, hourly) well — indistinguishable, and irrelevant for copy
purposes since either way the window is too tight to mirror. Rename the
verdict accordingly. Gate unchanged (median lead >=24h to count as a
copyable sharp; 50 sharps). Docs updated to current p80 numbers
(218 profile matches, 62/83 forward-profitable, 50 sharps).
The genuine insider-detection scanner (insider.py, z-score / Bubblemaps
fingerprint) keeps its name — that's a different, correctly-named thing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Swap the flat $200 conviction cutoff for a per-wallet percentile (top
20% of each wallet's own stake sizes) everywhere it was used:
- cache.py: canonical CONV_PCTILE=0.80 + conv_cutoff() helper (matches
the dashboard's pctl: filter >0, sort, linear interp)
- conviction_scan.py: per-wallet quantile_cont(size,0.8) in SQL, was
`size >= 200`
- validate_timing.py, pnl_focused.py: use cache.conv_cutoff
Rationale + validation: p80 reproduces flat-$200's win-rate lift on the
sharps while adapting to scale (a whale's $200 isn't conviction, a
minnow's is). Re-running the pipeline under p80: scan finds 218 profile
wallets (was 69), forward 62/83 profitable (p~0), +16% pooled ROI — edge
persists out-of-sample. Regenerated conviction_wallets.json /
watch_sharps.json; docs updated. skill.py/strategy.py/insider.py
untouched (score over all bets / size as copyability heuristic only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
README/FINDINGS/live-README now cover the repeatable find: score high-conviction
(>=$200) bets, validate forward (25/37 profitable, p=0.024), then a lead-time
gate drops uncopyable insiders -> 23 validated copyable sharps shown live on
jaxperro.com/trading.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
live/: operationalizes the LBS/Yale "skilled ~3%" result against the live
data-api. Enumerate recent liquid markets -> top traders -> candidate pool;
cache every wallet's resolved bets once in DuckDB (~26k wallets / 12.5M bets,
keyed by per-bet resolution time so any cutoff re-scores in seconds); 5-gate
skill funnel (n>=15, z>0, BH-FDR, split-half OOS, MM/bot cap); dashboard +
daily refresh.
Key finding: copying the high-win-rate "favorite-rider" cohort looks +23.6%
in-sample but loses -7.4% once selected on pre-June-1 data only (99% -> 68%
win rate) — selection bias, reproducing the paper's "lucky winners revert"
result on live data. Win rate != edge, again.
wide/: bulk subgraph->DuckDB scanner (survivorship-bias-free over all wallets),
but the public subgraph is frozen at Jan 2026 -> historical tool only.
Large local data (*.duckdb, candidates.json, *_scored.json, history/) gitignored.
README + FINDINGS updated with the current logic and the clean result.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>