# Polymarket sample — BTC Up or Down 4h

Hour: **2026-05-19 14:00–15:00 UTC**
Series: **BTC Up or Down 4h** (`series_id=10331`, slug `btc-up-or-down-4h`)
Counts: **64** events · **63** markets · **126** tokens

This bundle is a one-hour slice of a single Polymarket series, cut from
TickFoundry's archived collection. It contains the exact inbound websocket
messages we recorded plus the normalized analytical layer derived from them.

## Files

| File | What it is |
|---|---|
| `raw.jsonl` | Exact inbound Polymarket market-websocket messages, one per line. **71885** lines. |
| `l1.parquet` | Top-of-book updates (best bid/ask, sizes, spread). **10474** rows. |
| `l2.parquet` | Orderbook snapshots, 25 levels per side. **137034** rows. |
| `trades.parquet` | Last-trade updates from `price_change` events. **168** rows. |
| `reference/series.{json,csv}` | The series metadata (1 row). |
| `reference/events.{json,csv}` | Events under this series. |
| `reference/markets.{json,csv}` | Markets (condition_ids) under those events. |
| `reference/tokens.{json,csv}` | Outcome tokens for those markets (yes/no token_ids). |

## Timestamps

Every record has two timestamps:

- `ts_recv_ns` — local receive time in **nanoseconds since the Unix epoch**,
  captured as close to socket-read as possible. Authoritative for ordering.
- `ts_src_ms` — upstream timestamp from Polymarket in **milliseconds since the
  Unix epoch**, when present in the payload.
- `ts_recv_iso` — ISO-8601 UTC string mirror of `ts_recv_ns`, for convenience.

## raw.jsonl — schema

Each line is a JSON object with capture envelope + the verbatim payload:

```json
{
  "source": "polymarket_market_ws",
  "collector_id": "collector-cloud-main-g2",
  "run_id": "run-...",
  "conn_id": "conn-...",
  "msg_seq": 545692077,
  "ts_recv_ns": 1779235200081988852,
  "ts_recv_iso": "2026-05-20T00:00:00.081988Z",
  "ts_src": "1779235200023",
  "event_type": "price_change" | "book" | "tick_size_change" | "last_trade_price",
  "token_id": null,
  "condition_id": "0x...",
  "parse_ok": true,
  "parse_error": null,
  "payload_sha256": "...",
  "payload_text": "{...JSON string of the original message...}"
}
```

`payload_text` is the **original Polymarket message as a JSON string**,
preserved byte-for-byte (apart from being re-encoded into JSON-safe form).
Parse it again to recover the upstream object.

## l1.parquet — columns

`ts_src_ms, ts_recv_ns, ts_recv_iso, condition_id, token_id,
best_bid, best_bid_size, best_ask, best_ask_size, spread,
source_event_type, msg_seq`

`source_event_type` indicates which upstream event triggered the L1 update
(`book`, `price_change`, etc.).

## l2.parquet — columns

`ts_src_ms, ts_recv_ns, ts_recv_iso, condition_id, token_id, event_kind,
source_event_type, msg_seq, bid_levels, ask_levels, best_bid, best_ask,
payload_best_bid, payload_best_ask, bid_ask_reconciles,
bid_px_1..bid_px_25, bid_sz_1..bid_sz_25,
ask_px_1..ask_px_25, ask_sz_1..ask_sz_25`

Each row is a **full snapshot** of the orderbook for one token after the
update, padded with NaN past the deepest level present. `bid_ask_reconciles`
flags rows where our reconstructed top-of-book matches what the payload
declared.

## trades.parquet — columns

`ts_src_ms, ts_recv_ns, ts_recv_iso, condition_id, token_id,
price, size, side, fee_rate_bps, transaction_hash, msg_seq`

Derived from `last_trade_price` events; one row per matched fill.

## Joining

- A `token_id` joins to `tokens.token_id` → `tokens.market_id` →
  `markets.market_id` → `markets.event_id` → `events.event_id`.
- A `condition_id` joins to `markets.condition_id` directly.
- Each market's two outcome tokens are listed in
  `markets.yes_token_id` / `markets.no_token_id`.

## Source

Captured by TickFoundry from Polymarket's public market websocket
(`wss://ws-subscriptions-clob.polymarket.com/ws/market`). This is a static
hour-long sample published for evaluation; for full historical coverage
contact us at tickfoundry.com.
