Writing

I Spent $50 and Five Days Proving a 2.7-Second Oracle Lead Is Worth Nothing

The lead was real. It was also already in the price. A negative result with a mechanism, run as a council between me and two AI models.

I Spent $50 and Five Days Proving a 2.7-Second Oracle Lead Is Worth Nothing

Five days, about $50 in discovery capital, and a research council of me plus two AI models. The lead was real. It was also already in the price. Here’s the mechanism that killed it, and the process that stopped me from finding out with real money.


The eight trades that nearly convinced me to size up

I started with $16.37 in a Polymarket account and, over eight discretionary trades on the BTC “Up or Down” 5-minute markets, turned it into $20.95.

A 28% return in an afternoon. Obviously I had found something (or so the poor bloke thought!)

Eight trades is nothing. The danger was never that afternoon’s $4.58. The danger was what a 28% return would have justified doing next, with a real number in the account. The only reason it didn’t end that way is that instead of sizing up, I convened a research council: me, Claude, and ChatGPT. The first thing both models did was tell me to stop trading. ChatGPT’s opening entry:

“Eight trades are encouraging but far too few to separate edge from luck, and a displayed probability is not necessarily a tradable price.”

Five days later the project is formally shut down with a negative result. I’m writing it up anyway, because a negative result with a mechanism is worth more than a positive result without one. And the mechanism turned out to be the most interesting thing I learned all year.

The oracle lag is real, and I measured it three ways

Polymarket’s BTC 5m markets resolve against a Chainlink price feed. Chainlink is an oracle: it aggregates and publishes, which means it lags the exchanges it aggregates. On my recordings its own source-to-receipt time runs a median of 1.63 seconds before you even ask what it’s reporting.

That lag is not subtle. Plot the two together at 100ms resolution and they are visibly the same curve, offset. Here is the sharpest clean move in a twenty-minute window. Coinbase in orange, Chainlink in blue, each shown as change from its own level so the different price levels don’t obscure the shape:

Coinbase and Chainlink BTC/USD over 17 seconds. Coinbase reaches half the move at 10.1 seconds, Chainlink at 13.2 seconds.

Coinbase reaches half the move at 10.1 s. Chainlink gets there at 13.2 s. That is a 3.1-second gap, on the feed that decides who wins the bet.

One chart is an anecdote, so I measured it properly: correlate Chainlink’s one-second rate of change against Coinbase’s, sliding Coinbase forward in time, across all 12,000 buckets in the window.

Correlation between Chainlink and Coinbase rates of change against time shift, rising from near zero to a peak of 0.66 at 2.7 seconds.

Unshifted, r = 0.02. The two feeds look unrelated. Shift Coinbase forward 2.7 seconds and r = 0.66. That is the lead, quantified.

Those three numbers measure different things, so let me separate them. The 1.63 s is pure pipeline latency: how long a Chainlink observation takes to reach me after the timestamp it carries. The 2.7 s is the full effective lead, latency plus however long the oracle’s aggregation takes to reflect a move. That is the one that matters, because it’s what you could actually trade on. The 3.1 s is just one episode; individual moves scatter either side of the 2.7 s average.

The price levels never match (different venues, different books) but the first derivatives line up almost perfectly once you account for the offset. So for a window of two to three seconds, you can know which way the oracle that settles the market is about to move.

This sounds like a license to print money. It is not. Working out exactly why is the point of this post.

Attempt one: take the stale quote

The obvious play: when Coinbase moves and Chainlink hasn’t caught up, cross the spread and buy the outcome that’s about to become more likely.

I preregistered 594 policy variants (venue confirmation rules, signal horizons, price caps, hold times, latency assumptions) and ran them against 118 hours of recorded data. To be precise about the word: preregistration here means the grid and its acceptance gates were frozen before anything touched validation data. Not that I had a single hypothesis. A grid search is a fishing expedition by construction; the holdout is what makes it honest.

343 of the 594 were profitable in-sample. A stricter screen (positive in both chronological halves, positive on 4+ of 6 days, positive after deleting the best 1% of trades) still left 164 survivors.

Then I ran the frozen primary policy on untouched holdout data.

It traded zero times.

Not “lost money.” NEVER FIRED. Of 21 holdout signals: 8 failed the edge requirement, 7 exceeded the price cap, 2 had no executable quote, and 4 passed every gate but the ask moved before a simulated 350ms order could have arrived. The stale quote wasn’t stale by the time I got there.

A later, larger grid (828 policies) produced 117 nominal winners and zero strong ones, and lost $0.98 on untouched data.

343 of 594 profitable in-sample is the number I’d tattoo on anyone starting down this road. That is exactly what noise looks like when you ask it 594 questions.

Attempt two: stop taking, start making

There’s a strong structural reason to prefer resting orders here. I verified the fee schedule against real fills and balance deltas:

  • Takers pay 0.07 × p × (1−p) per share, per leg. About 1.75¢/share at even odds, so ~3.5¢ round trip.
  • Makers pay exactly zero. A 5-share passive bid at 48¢ filled and my balance moved by exactly $2.400000. Not a cent of fee.

Being the maker is worth ~3.5¢/share before you predict anything at all. So: rest a buy just above the bid, let the derivative signal pick the direction, then rest a sell at a price that guarantees $0.20 profit after fees.

All 12 parameter combinations lost money. Here is the default configuration’s entire life, from signal to profit:

Funnel: 2,529 derivative signals, 95 quotes placed, 39 orders filled, 10 profitable trades; of the 39 fills, 10 profitable and 29 losing.

2,529 signals. 95 quotes. 39 fills. Ten of them made money.

The shape of that collapse is the whole story, and the timings underneath it are worse than the counts suggest:

Median winning hold1.77 s
Median losing hold56 ms
Average win+$0.25
Average loss−$0.65

Fifty-six milliseconds. The losing positions were dead on arrival; the fill and the stop-loss were effectively the same event. And the payoff is UPSIDE DOWN: I was risking 65 cents to make 25.

Why resting orders invert your own signal

Here is the mechanism, and it’s the thing worth taking away.

A resting buy order only fills when the price trades down through it.

Now think about what that means when you’re resting orders on a directional signal:

  • Signal right: price runs up and away. Your bid never fills. You earn nothing.
  • Signal wrong: price falls through your bid. You’re filled instantly, at the worst moment.

You never get a representative sample of your signal’s predictions. You get precisely the subset where the market disagreed with you hard enough to run you over. Conditioning on getting filled inverts the signal. 2,529 signals produced 39 fills, and each fill was fresher, better information than the 1.5-second Coinbase regression that triggered it. I was being told “you’re wrong” in real time and had built a system that interpreted it as “you’re in.”

This is textbook adverse selection. Market makers have known it for decades. But there’s a difference between reading about it and watching it eat your own backtest down to a 26% win rate. My preregistered maker study measured it directly across 62,345,768 order-book records, using markouts: the change in fair price in the seconds after you get filled, which tells you whether the market kept moving against you. Negative markouts mean your fills were systematically on the wrong side.

They were negative for all 12 declared policies at 1, 3 and 10 seconds. Roughly −2.6¢ to −4.0¢ per share one second after the fill. The spread you capture does not pay for the information you surrender by capturing it.

The deeper reason both attempts failed is the same one, and it took me embarrassingly long to state plainly.

My edge was over Chainlink. But Chainlink never pays me. Every strategy here exits against a counterparty on the CLOB (the central limit order book, the same bids-and-asks machinery a stock exchange runs on) and the people setting those quotes watch Coinbase too, from better locations with faster hardware. The order book moves with the leader, not the laggard.

A lead over the oracle is only an edge against someone trading off the oracle. That is a retail participant watching Polymarket’s own delayed chart. It is emphatically not the marginal price-setter whose quotes you actually trade against.

An earlier calibration study had already told me this from the other direction: the market’s own quotes beat my Gaussian model on Brier score (the standard accuracy measure for probabilistic forecasts; lower is better) in discovery and holdout, with the holdout confidence interval entirely positive. Polymarket’s prices were better predictions than my model was. The information was already in them.

The lead is real, and it’s already in the price. Both things are true at once, and the second one is the one that matters.

Running a research council with two AI models

Everything above is downstream of a process decision, so let me describe it. It’s the part I’d actually repeat.

I ran the project as an append-only council transcript between three participants: me, Claude (Fable 5 High), and ChatGPT (5.6 Sol Extra High). Every substantive decision had to survive both models. Four things made it work:

It was adversarial by construction. Specs were written by one model and audited by the other. ChatGPT caught bootstrap intervals being reported at sample sizes too small to support them. Claude caught a settlement-watcher that only detected wins, because it waited for a balance change, and a loss looks like silence. Neither model had authorship of the other’s design, so neither was defending it.

Preregistration was enforced with hashes. The maker study’s specification was frozen and SHA-256 hashed before a single record was replayed. Twelve policies, declared in advance. When all twelve lost, there was no room to go discover a thirteenth.

The stopping rule was agreed before the answer was known. From Claude’s entry, written before the maker study ran:

“If the maker study also fails untouched validation, the honest council conclusion is: no accessible edge at our scale and latency, on either side of the book… we should commit to accepting it now, because it is much harder to accept after another month of searching.”

ChatGPT accepted it. Two days later it fired, and there was nothing left to argue about. The policy lock file records selectedPolicy: null.

The models would say the unflattering thing. Claude’s own entry naming its own process failure: it had declared the maker study “the highest-value simulation” and then let a shinier pivot consume the build queue for a week. That’s in the permanent record, written by the party at fault.

I don’t think two models were smarter than one good human collaborator would have been. What they were was available at 2am, tireless about auditing 600-line specifications, and (this is the whole thing) completely unattached to the outcome. I wanted the edge to be real. Neither of them did. When you’re the one holding the position, that asymmetry is the whole value proposition.

Things I verified

Hard-won, and free to you:

  • Taker fee: 0.07 × p × (1−p) per share per leg. Peaks at 1.75¢/share at 50¢, vanishes at the extremes.
  • Maker fee: zero. Verified against an exact balance delta.
  • Trade records report fee_rate_bps: "0" even on fills that were definitely charged. Balance reconciliation is the only honest fee evidence. Do not trust the field.
  • There’s a ~1.0 to 1.3 second settlement gate before freshly bought shares can be sold. This alone kills fast taker scalps.
  • Order minimums: ~$1 notional floor on marketable buys, 5-share minimum on sells. Below that you can create dust you cannot exit.
  • The coarse geoblock boolean and the documented restrictions table can disagree. The table is the authoritative one. If you’re building anything that needs to fail closed on jurisdiction, read the published restrictions rather than trusting a single boolean, and check where your own infrastructure is allowed to operate before you write a line of order-placement code.
  • Ties resolve Up (close ≥ strike).

What $50 bought

About $50 of discovery capital across five days, most of it spent on deliberate experiments rather than losing trades. A controlled taker round-trip to measure fees. A passive fill to prove makers pay nothing. One coin-flip position held to resolution to test redemption.

In exchange: a 118-hour synchronized dataset across four exchange feeds plus the oracle, 62 million order-book records, a replay engine, and a definitive answer to a question I would otherwise still be paying to ask.

If you take one thing from this, take this: “my signal predicts X” and “I can make money on X” are entirely different claims, and the gap between them is called microstructure. The check that would have saved me the most time costs nothing. Before building anything, ask who is on the other side of my fill, and what do they know that I don’t?

For a resting order, the answer is always the same. They know the price is coming to them. You don’t.