THE CLAIM
Finding one live edge takes hundreds of honest rejections. I build the system that runs them.
Evgenii Bondarev · Bond Labs
The scarce part is not generating strategy ideas - an LLM does that in bulk. It is not rejecting them either; it is rejecting them in a way you can still believe six months later, so a no stays settled instead of being re-litigated. Everything below runs unattended, generation through verdict, so the 220 entries are what the system got through rather than what I had time to grind by hand.
THE RECORD
What the search has cost
Each mark below is an entry that went the whole way through the protocol and received a verdict. The 116 kills are what the search cost; the 6 survivors are what it was for, and they are only worth looking at because the other 214 entries were run and written down. A diagnostic answers a question with a number rather than producing a PnL stream, which is why it is counted apart from the 153 strategy hypotheses.
116 DEAD67 DIAGNOSTIC22 MARGINAL6 CANDIDATE9 OTHER
THE PROTOCOL
How a rejection gets cheap enough to trust
All six steps run without supervision, one entry after another. I choose the direction the search works in; everything inside it - proposing, screening, killing, deciding what runs next - is the system’s.
- STEP 1
Hypothesis generation
Candidate ideas are proposed in bulk and pre-registered - written down, with the statistics that will judge them, before anything is measured - so a verdict attaches to a claim that was fixed in advance.
- STEP 2
Screen
The hypothesis becomes a rule over already-ingested data and runs on a coarse grid, against the same per-year and deflated-Sharpe checks the later stages apply at full resolution. Most ideas end here, and that is the point: a screen spends compute, the stages behind it spend weeks.
- STEP 3
Statistical gate
Every backtest appends one row to the sharpe-gate registry, keyed by a config hash, so the trial count the gate deflates against is the real one and not the remembered one. The thresholds themselves have been revised where they proved too strict; the count they spend is what stays honest.
- STEP 4
Adversarial review
Independent reviewers, none with a stake in the hypothesis surviving, argue for killing it: look-ahead, survivorship, selection on the same data, a sample too thin to support the claim.
- STEP 5
Verdict, logged
One label, dated and appended to the corpus. The record above is the whole log rather than a selection from it, which is what makes the 116 a denominator and not a highlight.
- STEP 6
Next hypotheses, derived from the kills
Every kill records why it died, and a new hypothesis has to dodge every reason on record - one walking into a documented cause of death is rejected before it costs a run. That is what makes the corpus compound: each rejection narrows the next search.
- RETURNS TO STEP 1 · NARROWER
What the protocol does with its own mistakes
When a screen fools itself, the rule that would have caught it is written down with the case that produced it, and every later screen reads it first. Where the mistake was mechanical - a look-ahead in an index lookup, a rolling gate switched off by its own NaN warm-up - it becomes a check that fires before the simulation spends anything. The method gets harder to fool the same way twice.
VERDICTS
Three of them, start to finish
Nothing here is a strategy that is traded, which is why these can be shown whole - what was claimed, what was measured, the numbers, and the rule that came out of it.
PUBLISHED
What is on PyPI
Published under Bond Labs and installable from PyPI: what pulls venue history into Parquet, what simulates on it, and what keeps the trial count behind a Sharpe ratio honest.
hyperliquid-data0.1.0INGEST
Pulls Hyperliquid history - candles, funding, L2 book, trades, fills, liquidations - into Parquet. Both HL buckets are requester-pays, so hl-data cost lists the exact prefixes a pull would touch and prints the egress bill before the pull, not after: all-coin fills alone run 0.8–1.0 GiB per day.
GitHubPyPI
lighter-data0.1.0INGEST
Pulls Lighter funding history, candles, L2 book and trades into Parquet, plus a WebSocket recorder for what no archive sells yet. It exists because the venue ships no historical tooling and truncates quietly: numeric market indices for symbols, silent per-response caps, and a funding rate whose sign lives in another field. Public REST and WebSocket, no key, no account.
GitHubPyPI
explicit-backtest0.1.0SIMULATE
A candle-driven backtest engine that states the assumptions it cannot derive from the data instead of implying them: which of two things inside one bar resolves first, that a signal fills on the next bar’s open, that a stop is checked against the entry bar too. Funding is off by default and refuses to run on thin coverage rather than quietly taking a default rate. Zero runtime dependencies.
GitHubPyPI
sharpe-gate0.1.1GRADE
Everyone computes a Sharpe ratio; almost nobody stores the trial count behind it. Without an honest N, the Deflated Sharpe Ratio deflates by the trials you remembered rather than the ones you ran across every session, notebook and sweep. This is the registry that keeps N honest - one append-only row per backtest, keyed by a code-agnostic config hash - and the gates that spend it.
GitHubPyPI
CONTACT
If your research generates hypotheses faster than your people can falsify them, that is the gap I work on: the discipline has to fire without a human in the path. Built into a loop you already run, or an audit of one. Write and say so.