Files

165 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# research/ — the edge factory (SILO)
Standing rules (user directive 2026-07-20: "built in a silo to not affect
anything on the live bot"):
- **Nothing here is imported by, or imports, the bot** (`copybot.py`,
`copytrade.py`, their configs). The Fly workers run pinned entrypoints;
this directory is inert to them.
- **Tape access is read-only** (`duckdb.connect(..., read_only=True)`).
- The ONE shared write: `live/cache.duckdb::resolutions` via `live/payouts.py`
— append-only immutable chain facts, the same store the daily pipeline
already feeds. Nothing else in `live/` is touched.
- The existing paper bot is the live test's CONTROL — graduated edges get
their own paper harness here, never that one.
- Studies are pre-registered (GitHub issue per study: hypothesis, params,
verdict + kill criteria) BEFORE their forward window opens. Exploration
happens on already-collected tape; **verdicts only come from
`forward_ledger.jsonl` rows dated after the params freeze commit.**
- **SCORER LAW (2026-07-22, FINDINGS "round three"): every scorer resolves
outcomes through `forward.payouts_for()` — tape proxy first, CTF chain
overlay for the remainder. A "pending" bucket is NEVER ignorable on
Polymarket: market liveness encodes the outcome (a losing bet's winning
sibling keeps trading, so losses hide in pending while wins score).
This bug inflated Study A from a true $6/fill to +$46/fill.**
- **Every study gets one instrument that does not share the scorer's
assumptions** — the surge paper harness (chain-graded from day one) is
what caught the bug. Divergence between instruments is signal, not noise.
- **DATA LAW (2026-07-22): tests are additive, never subtractive.** Raw
streams (tape, attempts, markouts, settles, meta snapshots) are
append-only; analysis opens them read-only; no script rewrites or
rotates a raw stream. Bot-state trims exist ONLY where an append-only
log on the volume carries the same rows durably (settles) or the nightly
pull archives them (attempts/markouts). A study that would need to
mutate a stream records a NEW stream instead.
Layout:
tape.py read-only loaders · tape proxy-resolution (terminal-VWAP +
sibling veto — exact per-bet, but resolution TIMING is
win-biased; see SCORER LAW) · title parsers · chain_overlay()
sim.py execution replayer calibrated on OUR live fills ledger
(lag, FAK no-match, protected band, 3% taker fee)
study_flow.py Study A — surge momentum (#16 CLOSED 2026-07-23; A2
chain grade $7.54/fill × 1,344 independently confirms)
study_oracle.py Study B — crypto oracle fair value (#17: E0.04 killed;
E≥0.07/0.1 ledger-positive but the harness chain grade
2026-07-23 reads $8.51/$5.90 per fill at real latency
— taker arm evidence-dead, tiers accrue to their formal
bars, maker pivot is the successor hypothesis)
copy_edge_slices.py T5 — parity-era copy edge by niche/lag/band/wallet
(esports carries it; feeds #14)
copy_maker_entry.py T3 — resting-bid copy entries beat taker FAKs
(+$17.45 vs +$12.86/signal; basis of #20)
sell_mirror_study.py sharp exits are bankroll ops, not signal
(basis of #21 hold-through)
maker_sharps.py T2 — 673 improbably-winning MAKERS in
orders_matched (86% invisible to taker screens);
follow-on: inventory-lean signal
sibling_sum_scan.py T4 — print-substrate sum-arb scan (artifact-
dominated; needs standing-book data; parked)
maker_lean.py T6 — WALK-FORWARD POSITIVE: follow small maker
inventory leans (+$2.51/lean, 59% hit, positive
all 3 days) → STUDY C #22 PRE-REGISTERED
(params/study_lean.json frozen 052eda0; follow
arm verdict-gated, fade $2k+ FAILED its
event-concentration gate — report-only; nightly
rows via forward.py score_lean, study:"lean")
event_leadlag.py T9 — POSITIVE: same-outcome siblings reprice
slowly after leader bursts (+$9.73/$100 chain,
n=2,028; stale-print entry optimism stated) →
STUDY D #23: wwf-lagbot harness (below) is the
Stage-2 execution-realism instrument
settle_discount.py T7 — settlement-discount niche: industrialized
by incumbents (+2-3%/hold for the good ones);
residual unproven (63% of vol outside
tape-resolution); parked at our scale
miss_audit.py T8 — guard counterfactual: guards earn their
keep; crater-rejects were GOOD misses (retry EV
follow-up queued)
copy_age_slices.py T10 — market-age gradient inconclusive at
n<=15/cell (6-24h positive both books;
age~market-type confound); reruns as fills accrue
maker_quote_sim.py T1 — crypto maker quoting at fairm: STAGE-1
KILL 2026-07-23 (best cell +$0.37/fill at
m=4c/R=1s under queue-front optimism; every
R=4s cell $7-9/fill — staleness IS the
adverse selection; ~31-50k graded fills/cell)
copy_maker_patience.py T11 — #20's 60s maker TTL is ALREADY OPTIMAL:
touches land in 1-2s, fill rate flat after 5m,
and the marginal late fills lower EV (loser
fill-rate 100% at 5m+ — patience past a minute
only harvests adverse selection)
maker_unwind.py T12 — maker-sharp unwinds are NOT exit signals:
STAY +$5.95/unwind (n=265, 2.6x the bar) vs
FADE -$5.22 — #21 one species over; Study C
keeps NO exit rule (concentration caveat in
the header; --grade-only re-grades the dump)
depth_imbalance.py T14 — book imbalance at fill is a BAND: extremes
adverse both ways, balanced 0.25-0.47 least-bad
in BOTH harnesses (portable #23 guard
candidate); slope "gate" = quantile-tie
artifact — check feature variance first
sharp_halflife.py T15 — published-set churn is violent: 49% of
detected sharps gone in 1 day, ~10% at 28d
(real as-of git history of watch_sharps.json);
EV-by-age = churn's meaning — pending its
81k-cond chain-ensure
requote.py crater→requote timing (feeds the bots' per-niche retry)
forward.py scores frozen studies on new tape days → forward_ledger
(payouts_for chain overlay mandatory; controls + sub5c
exploratory arm — 0-for-38, dead)
informed_set.py publishes params/informed_set.json nightly (surgebot input)
surgebot.py A2 MEASUREMENT harness (wwf-surgebot → jaxperro.com/test):
every cooldown-passed trigger paper-FAK'd at $100 against
the live asks; v1's cash-gated $100/5% book (halted at its
50% line 2026-07-22) is replayed offline instead —
surge_book_replay.py → surge_book.json. v1 artifacts
frozen: surge_paper_ledger.jsonl + /data/surge_state.json.
oraclebot.py Study B real-time PAPER harness (wwf-oraclebot →
jaxperro.com/test): fair value tick-by-tick on the venue's
own settlement feed, all E-tiers tracked, three settle
layers (own-feed tick → CLOB flags → nightly chain truth)
lagbot.py Study D real-time PAPER harness (wwf-lagbot →
jaxperro.com/test, deployed 2026-07-23, SEM_VER l1):
leader bursts ≥10¢/120s → paper-FAK $100 on ≤2 lagging
same-outcome siblings at ≤ stale+4¢; DOWN-moves buy the
sibling's COMPLEMENT token; cooldown 600s/event, 30-min
warmup (leader maps built live from the stream). Every
attempt logs the ask premium over the stale print — the
observational kill-switch (median ≥+8¢ over 3 days =
mirage) can kill #23 without a paper sample
grade_surge.py / grade_oracle.py / grade_lag.py nightly chain-truth
re-grades → surge_meas / oracle_paper / lag_paper
ledgers (grade_lag also prints EV per episode AND
%-of-staked — partial fills can't flatter the verdict —
plus the median-premium kill-switch read); all three
pull the raw volume streams to local .pull copies
markout_flow.py exploratory markout-exit curve (chain-truth verdict: NO
scalp inside the dead surge signal — losers bleed from
minute one; v0's res_tok version was round-3-biased)
meta_snap.py nightly gzipped snapshot of ALL active markets (~12k/day,
research/meta/, local-only) — τ knowable at trigger for
every tape trigger; token→outcome maps close the
label-gap artifact class
params/ frozen study parameters (committed = frozen)
nightly.sh launchd runner (fires 09:15, then WAITS for fresh tape —
Stage 0 keeps the tape ~15-min fresh whenever the Mac is
awake; deadline 8h, then scores anyway and logs staleness)
Data streams (the moat — all append-only, per DATA LAW):
Fly volumes (accrue 24/7, Mac-independent; daily Fly snapshots ×5):
wwf-recorder /data full firehose → Parquet folds (25GB, ~3+ weeks of
Mac-offline headroom before the 85% disk guard)
wwf-surgebot /data surge_attempts.jsonl (every attempt + top-5 asks +
top-3 bids + latency) · surge_markouts.jsonl (book
re-reads +60/300/1800s per fill) · surge_settles
.jsonl (durable settles) · surge2_state.json
wwf-oraclebot /data oracle_attempts / oracle_markouts / oracle_settles
.jsonl + oracle_state.json (same shapes)
wwf-lagbot /data lag_attempts.jsonl (every attempt + top-5 asks +
premium vs stale + latency) · lag_settles.jsonl
(durable settles) · lag_state.json
Mac (nightly pulls + git): ledgers + params committed; raw .pull copies
and meta/ gzips local. forward.py backfills any tape-covered day the
ledger has never seen — a Mac gap > RESCORE_DAYS leaves no holes.