Free data · no key

Bitcoin prediction market order book data

The full L2 order book of every Bitcoin Up or Down round on Lucyd, from 5 minutes to a day, tick by tick, as Parquet files. Free to download, no API key, no sign-up. Built for backtesting prediction market strategies and research.

Browse the files →

What is included

  • Order books: every change of the bids and asks of both outcomes, Up and Down, from the first order to the end of the round. One file per round.
  • Rounds: strike, settlement price, winner, start and end time of every round, from the API.
  • Trades: every fill with price, size, side and wallet, as JSON or CSV.

History starts on October 7, 2026 and grows by about 3,200 rounds a week. Rounds settle on the Pyth BTC/USD price.

License: CC BY 4.0. Free for any use, including commercial, with credit to Lucyd.

Files by series

Files are grouped by round length and by the UTC date the round started:

File format

Parquet, zstd-compressed. Rows with the same timestamp and kind snapshot are the complete book of both outcomes; a delta row sets one price level. The book at any moment is the last snapshot before it plus the deltas after it.

ColumnTypeMeaning
timestamptimestamp, ms, UTCWhen the book change was received
state_sequenceuint64Order of publication by the exchange
kindstringsnapshot (full book) or delta (one level changed)
asset_idstringOutcome token: Up or Down
sidestringbid or ask
pricedouble0.0025 to 0.9975, on a 0.0025 tick
sizeuint64Total tokens at that price, 6 decimals; 0 = level removed

Load a round in Python

Find a round with the API, build its file URL and read it straight over HTTPS with DuckDB (pip install duckdb requests pandas):

import duckdb, requests
r = requests.get("https://api.testnet.lucyd.trade/markets",
                 params={"state": "settled", "period": "5m", "limit": 1}).json()[0]
url = (f"https://data.testnet.lucyd.trade/books/updown/5m/btc/"
       f"{r['start_date'][:10]}/{r['address']}.parquet")
book = duckdb.sql(f"SELECT * FROM read_parquet('{url}') ORDER BY timestamp").df()
print(r["winner"], r["strike"] / 1e8, r["resolved_value"] / 1e8)
print(book.head())

Rounds and trades

# every trade of the last 24 hours as CSV
curl "https://api.testnet.lucyd.trade/trades?from=$(( $(date +%s) - 86400 ))&format=csv" -o trades.csv
# rounds of one series with strike, settlement price and winner
curl "https://api.testnet.lucyd.trade/markets?state=settled&period=15m&limit=1000"

All endpoints and fields are in the API docs. Live data streams over WebSocket: the order book, and every trade as it happens.

What people use it for

  • Backtesting bots for 5-minute and 15-minute Bitcoin Up or Down markets: how to build one.
  • Studying how prediction market prices converge as a round ends.
  • Market making research: spreads, depth and fills at every round length.
  • Statistics of Bitcoin moves: what 8,000 rounds say.

Questions

Is the data free?

Yes. Every file is free to download without an API key or an account.

Can I use it commercially?

Yes. The data is licensed under CC BY 4.0: use it for anything, including commercial work, and credit Lucyd as the source.

How detailed is it?

Every change of the L2 book of both outcomes, coalesced by the exchange into windows of about 100 ms, plus a full snapshot at least once a minute while the book changes.

When does a new file appear?

A few minutes after a round ends and is removed from the order book. Rounds that never had an order have no file.

How do I match a file to its result?

The file name is the market address. GET /markets?address=<address> on the API returns its strike, settlement price and winner.

Is it Polymarket data?

No. It is the order book of Lucyd Bitcoin Up or Down markets, which ask the same question as Polymarket and Kalshi rounds and settle on the Pyth BTC/USD price.