- Hyperliquid L2Perp feed
crypto_priceSpot stamp- Nearest PRIORJoin rule
- Scale tier +
Access
The same BTC trades in two places at once: as a perpetual future on Hyperliquid and as a spot reference stamped onto every Polymarket snapshot. Both feeds are recorded in UTC at millisecond precision, so they share a clock. This post is about the shape of the join, which fields line up, how the cadences differ, and the one rule that keeps the merge honest.
This is a data-structure piece, not a strategy. The goal is to describe exactly what sits on each side of the join and how to bring them together without leaking the future into the past. The signal you build on top is yours; the plumbing is what we are documenting here.
Two feeds carry a view of the same underlying. The Hyperliquid exchange feed is the perpetual futures L2 book for BTC, ETH, SOL and XRP, sampled to storage at roughly one record per second. The Polymarket snapshot carries a crypto_price field, a spot reference (BTC from Binance, for example), alongside a crypto_price_age_ms that tells you how fresh that stamp was when the snapshot was taken.
The two sides of the join
Hyperliquid perp book
The perpetual L2 book, captured event-driven and sampled to storage at about one record per second per asset.
- Perp bid/ask depth
- ~1/sec to storage
- BTC · ETH · SOL · XRP
Spot reference stamp
crypto_price rides on every Polymarket snapshot, a spot mark for the same coin, with an age field for freshness.
- crypto_price
- crypto_price_age_ms
- Spot, not perp
One shared clock
Both feeds are UTC at millisecond precision, so timestamps from one can be matched directly against the other.
- UTC throughout
- Millisecond precision
- No timezone math
The cadence mismatch is the whole problem
The two feeds do not tick together. Crypto snapshots arrive at roughly 20 Hz; the Hyperliquid perp record lands about once a second. You cannot expect a perp row for every snapshot, so the join is asymmetric: for each snapshot you reach back to the most recent perp record that already existed, and attach it.
Merge on the nearest PRIOR record
For any snapshot at time T, attach the latest perp record whose timestamp is ≤ T, never one stamped after T. Matching to a future perp print would leak information that did not exist yet. Nearest-prior is what keeps the joined panel backtest-safe.
How to assemble the panel
- 1Pull the Polymarket snapshots for your market and window, each row already carries crypto_price, crypto_price_age_ms, and the touch and depth fields.
- 2Pull the Hyperliquid perp records for the same coin and window from the exchange snapshots feed, one stream of ~1/sec L2 books.
- 3Sort both by timestamp, then for each snapshot bind the most recent perp record at or before its timestamp (an as-of, backward join).
- 4Carry crypto_price_age_ms through so you can later drop or down-weight rows where the spot stamp was stale when captured.
The fields that line up
- timestampUTC ms, the join key on both feeds
crypto_priceSpot reference on every snapshotcrypto_price_age_msStaleness of that spot stampbest_bidbest_askPerp touch from the exchange L2 book
Once joined, a single row holds three price views of the same coin: the Polymarket implied probability, the spot reference it was stamped with, and the perpetual book’s touch. That is the structure that lets you compare how the prediction market, spot, and perp move relative to one another, without ever re-fetching or re-aligning by hand.
Honest limits of the join
- The perp feed is sampled to ~1/sec for storage, so between samples you are holding the last known book, fine for a reference, not a tick-by-tick perp replay.
- crypto_price is a spot mark, not the perp mid; treating them as interchangeable hides the basis you may actually want to study.
- crypto_price_age_ms is there for a reason, a snapshot can carry a spot stamp that was already a little stale, and a strict pipeline filters on it.
- Exchange data is a Scale-tier-and-up capability; the spot reference on snapshots is part of the crypto dataset itself.
Two feeds, one clock. The discipline is not in matching them, it is in never matching a snapshot to a record that had not happened yet.
Build the joined panel
The Hyperliquid data page shows the perp coverage; the docs show the exchange snapshots endpoint and the snapshot fields you join on.
Frequently asked questions
What is the crypto_price field on a snapshot?
It is a spot reference for the underlying coin, for example BTC sourced from Binance, stamped onto each Polymarket snapshot at capture time. It travels with the snapshot alongside crypto_price_age_ms, which records how old that spot mark was when the snapshot was taken.
How do I align the Hyperliquid perp feed with the snapshots?
Both feeds are UTC at millisecond precision, so they share a clock. The snapshots arrive at roughly 20 Hz and the perp records at about 1/sec, so for each snapshot you attach the most recent perp record stamped at or before the snapshot’s timestamp, a backward, as-of join. Never attach a perp record stamped after the snapshot, or you leak the future.
Is the spot reference the same as the perp price?
No. crypto_price is a spot mark; the Hyperliquid feed is a perpetual futures book. Keeping them distinct is the point of the join, the gap between them is the basis, which is often exactly what you want to measure rather than smooth away.
Which tier do I need for the Hyperliquid data?
The Hyperliquid exchange data is available on the Scale tier and above. The spot reference (crypto_price) is part of the crypto snapshot schema itself, which all tiers can read for crypto markets.



