Three fixes from the 2026-07-08 alignment audit (bot feed vs replay,
row-by-row):
1. sold-detection no longer trusts res_t alone — for in-play markets
res_t is endDate metadata (game-DAY midnight, pre-dates the entry) so
the timestamp test never fired and every in-play sell booked as
held-to-resolution. Price is the fallback truth: a redeem prints
exactly the payout, a real sell prints a mid price (>2c off payout).
2. round trips on resolved-on-chain markets are booked, not dropped —
when the trusted cache row never qualifies (bogus forward res_t:
Chidekh 'unresolved until Jul 14' on a Jul-5 match) the bet used to
vanish; now redeem-closes book at chain truth, sell-closes mirror.
3. Set-D wallets gate on the bot's PINNED floors (copybot.paper.json),
not a recomputed p80 that drifts a few % and takes different bets.
Also: resolved display slice 60 -> 250 rows.
Cross-check: 9 settled Set-D bot bets -> 7 agree, 0 absent, 2 diffs that
are real execution gaps (bot missed the sharp's exit, rode to
resolution) — each book records what actually happened to IT.
Equity 30d: $29.1k -> $17.4k (+1636%) — the flattering artifacts are gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The daily freshen reset the bets + exits cursors but never pulled_entries,
so a watchlist wallet's first_buy map went up to 14 days stale and
portfolio.py silently dropped every bet on conds entered since the last
pull (`if not et: continue`) — neither resolved nor open. Kruto2027's
Jul-7 Brewers bets (visible SOLD in the live bot) and two losing bets
were absent from the backtest for exactly this. Entries re-pulled for
Set D + portfolio regenerated: Kruto 43->49 bets, both Brewers rows
booked, hidden losses folded in.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
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>
/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>
The replay held everything to resolution while the live bot mirrors exits —
two different strategies wearing one dashboard. Now, when a followed wallet
fully closed a position pre-resolution, the replay sells there too: close
time from /closed-positions, exit price reconstructed as
avgPrice + realizedPnl/totalBought, exit taker fee + slippage haircut paid.
Complete in-window round trips on unresolved markets (entered AND exited —
previously invisible to the replay) are included; on-chain-resolved conds
are excluded from round-trip synthesis so redeems can't masquerade as
sells. Sold legs count apart from W/L/R (they're price events, not
outcomes): 30d now 226W/55L/84R/31S, $12,730 (+1173%) — mirrored exits
bank the wallets' early profit-taking that hold-to-resolution left behind.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The honest 30d backtest: $1k -> $2,538 (+154%), 78W/18L/112R — not the
refund-inflated +8,627%. Sharp list: 33 copy-positive holders under truth
gates; 0x4bFb-whale and ArbTrader no longer qualify (their conviction
records were carried by 50/50 refunds counted as wins). portfolio.py now
reports refunds as R, not L (a scratch is not a loss).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cur_stake = class % of equity (drawdown-braked), then min(their stake):
a copy is never bigger than what the wallet actually bet. No reserve
sweep, no $250 pin — the their-bet ceiling is the liquidity bound now
(fills stay within size the market demonstrably absorbed).
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>
Once working equity exceeds stake_cap/pct ($6,250 at 4%), surplus cash sweeps
to state["reserve"]/portfolio reserve - banked, never bet, immune to drawdown
- keeping stakes at the $250 level where marketable fills sit inside typical
book depth. Feed/summary gain reserve; realized = cash+exposure+reserve-bank.
June backfill: equity $15,684 (+1468%), $9,185 banked, next stake pinned $250.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
+$2,454 copy P&L, 72.4% conviction win (144-55), $257 avg bet, 2.1h median
lead. Added to bot configs (p80 floor $115.27) + backtest set. June backfill
with him: +2677% (in-sample selection bias + compounding, next stake $1,070 -
treat as a ceiling; depth-aware fills become necessary at these clip sizes).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- guard: by rule, a price BELOW the sharp's fill always passes (strictly
better odds; the symmetric guard once skipped a 0.70->0.51 improvement that
won +$36). Only adverse drift is gated by price_guard_pct.
- entry cap: June sweep (0.75-1.0) peaked at max_entry 0.95 - >95c favorites
added ~23 wins yet lowered final equity (slip+fee eat 1-3% payouts, capital
compounds better elsewhere); deep caps cut real winners. Set in all configs
+ portfolio MAX_ENTRY (env-overridable for sweeps; PORTFOLIO_OUT added).
Canonical June backfill: +716%, 219W/52L, $374 fees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
max_trade/max_position guards lifted in both paper configs; backtest STAKE_CAP
-> inf. June backfill uncapped: +531%, next stake $252, $195 fees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Engine default + both bot configs + backtest set to 0 (cap logic stays, opt-in
via risk.max_per_event). June backfill without the cap: +465%, 237 resolved
(202W/35L), 22 missed, $170 fees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- engine (copytrade): stake_usd() = bankroll_pct x current equity (cash + open
cost basis) - Kelly-style compounding both directions - halved while equity
sits below 80% of its high-water mark; new risk.max_per_event (default 2)
blocks stacking correlated markets on one real-world event (dated-slug prefix
grouping; LSB1 once put 6 conviction bets on a single match).
- copybot: feed/summary report the dynamic stake, stake_pct, event_cap, hwm.
- portfolio backtest mirrors the exact same rule (PCT 4%, clamp $5-$150,
EVENT_CAP 2, brake 80%/half), with per-bet stakes in every table row and a
persistent CLOB slug cache for event grouping. June backfill: +426% vs +168%
flat - compounding amplifies the in-sample month; July live is the test.
Misses fell 62 -> 19 cash-missed (+26 deliberate event-cap skips): smaller
early stakes capture more signals.
- configs: bankroll_pct 0.04, max_trade/max_position 150 (runaway guards),
max_per_event 2.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>