> ## Documentation Index
> Fetch the complete documentation index at: https://docs.probalytics.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Markets

> The markets dataset shape, coverage, and venue-specific normalization rules

## Shape

`markets` has one row per normalized market or instrument. Updates reuse the same `id`; in ClickHouse, `indexed_at` selects the newest version.

| Field                            | Type                   | Values and meaning                                                                                                                                                                                                      |
| -------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                             | `UUID`                 | Stable Probalytics market ID. Use this to join fills and orderbook snapshots.                                                                                                                                           |
| `platform`                       | `enum`                 | `POLYMARKET` or `KALSHI`.                                                                                                                                                                                               |
| `platform_id`                    | `string`               | Venue-native market identifier: Polymarket condition ID, Kalshi ticker, or perpetual instrument ID.                                                                                                                     |
| `slug`                           | `string`               | URL-friendly market name from platform metadata. For Kalshi, it is built from the platform's series title.                                                                                                              |
| `url`                            | `string`               | Direct URL to the market on its platform. Always present.                                                                                                                                                               |
| `title`                          | `string`               | Market question, venue title, or instrument symbol.                                                                                                                                                                     |
| `description`                    | `string`               | Market rules or description from platform metadata.                                                                                                                                                                     |
| `category`                       | `string`               | Probalytics market category used for internal classification. Usually empty in the current dataset.                                                                                                                     |
| `tags`                           | `array<string>`        | Probalytics tags used for internal classification. Usually empty in the current dataset.                                                                                                                                |
| `market_type`                    | `enum`                 | `BINARY` — two-sided prediction market<br />`SCALAR` — numeric settlement<br />`PARLAY` — multi-leg market<br />`PERPETUAL` — perpetual or margin instrument<br />`MULTIPLE` — mutually exclusive multi-outcome product |
| `outcomes`                       | `array<Outcome>`       | All normalized outcomes. Each outcome contains `id` (UUID), `platform_id` (string), `name` (string), and zero-based `index` (integer).                                                                                  |
| `created_at`                     | `datetime`             | Source creation time in UTC. Perpetual and margin instruments currently use the product reference epochs documented below.                                                                                              |
| `opened_at`                      | `datetime \| null`     | Time trading opened.                                                                                                                                                                                                    |
| `closes_at`                      | `datetime \| null`     | Time trading closes or closed.                                                                                                                                                                                          |
| `resolves_at`                    | `datetime \| null`     | Expected or recorded resolution time.                                                                                                                                                                                   |
| `end_date`                       | `datetime \| null`     | Event end/reference time. This can be the same source timestamp as `closes_at`.                                                                                                                                         |
| `reset_at`                       | `datetime \| null`     | Reset or void time when supplied.                                                                                                                                                                                       |
| `status`                         | `enum`                 | `PENDING`, `ACTIVE`, `PAUSED`, `CLOSED`, or `RESOLVED`. Venue mappings are listed below.                                                                                                                                |
| `resolution_type`                | `enum \| null`         | `STANDARD`: one winning outcome. `SPLIT`: payouts divided across outcomes. `VOID`: voided/cancelled. `null`: unresolved or unavailable.                                                                                 |
| `resolution_winning_outcome_id`  | `UUID \| null`         | Winning `outcomes.id` for a standard resolution. Usually `null` for split and void resolutions.                                                                                                                         |
| `resolution_outcome_payouts`     | `array<OutcomePayout>` | Exact settlement values. Each item contains `outcome_id` (UUID) and `payout` (decimal). Empty before resolution or when payout data is unavailable.                                                                     |
| `resolution_resolved_by`         | `string \| null`       | Resolver or source identifier, such as `kalshi` or a Polymarket resolver value.                                                                                                                                         |
| `resolution_resolved_at`         | `datetime \| null`     | Recorded resolution time in UTC.                                                                                                                                                                                        |
| `resolution_source_block_number` | `integer \| null`      | Resolution block number when the resolution came from a chain source. API-derived resolutions can contain `0` or `null`.                                                                                                |
| `resolution_source_tx_hash`      | `string \| null`       | Resolution transaction hash when supplied. Empty or `null` for API-derived resolutions.                                                                                                                                 |
| `source_block_number`            | `integer`              | Source block number. `0` for current API-derived market rows.                                                                                                                                                           |
| `source_tx_hash`                 | `string`               | Source transaction hash. Empty when unavailable.                                                                                                                                                                        |
| `indexed_at`                     | `datetime`             | Time Probalytics wrote this version. The newest value wins for the same market ID.                                                                                                                                      |

## Coverage by venue and product

| Venue      | Product                   | `market_type` |    Markets | Coverage starts              |
| ---------- | ------------------------- | ------------: | ---------: | ---------------------------- |
| Polymarket | Binary prediction markets |      `BINARY` |  2,715,016 | 2020-10-02                   |
| Polymarket | Scalar prediction markets |      `SCALAR` |         71 | 2020-10-02                   |
| Polymarket | Perpetuals                |   `PERPETUAL` |         52 | 2026-07-01 (reference epoch) |
| Kalshi     | Binary prediction markets |      `BINARY` | 13,986,711 | 2021-07-02                   |
| Kalshi     | Scalar prediction markets |      `SCALAR` |     30,273 | 2023-11-30                   |
| Kalshi     | Margin instruments        |   `PERPETUAL` |         16 | 2026-06-17 (reference epoch) |

<sub>Counts as of 2026-08-24 17:34 UTC, queried from `markets FINAL` and grouped by `platform` and `market_type`. Coverage starts use the earliest `created_at`; perpetual and margin rows currently use fixed product reference epochs.</sub>

Markets are indexed continuously, so these counts change throughout the day. Query the data warehouse for current values:

```sql theme={null}
SELECT
    platform,
    market_type,
    count() AS markets,
    min(created_at) AS earliest_created_at
FROM markets FINAL
GROUP BY platform, market_type
ORDER BY platform, market_type;
```

## Polymarket prediction markets

### Source

Market and event metadata comes from Gamma. This supplies the question, description, URL slugs, lifecycle dates, outcome names, outcome token IDs, and settled outcome prices.

### Identity and outcomes

* `platform_id` uses the condition ID. If it is missing, the Gamma market ID is used.
* `id` is generated deterministically from `platform_id`.
* Outcomes are sorted reverse-alphabetically before indexes are assigned.
* Each outcome token ID becomes `outcomes.platform_id` and is used to generate the outcome UUID.

For a typical Yes/No market, reverse-alphabetical ordering makes **Yes outcome 0** and **No outcome 1**. Read the stored outcome names and indexes instead of assuming source array order.

### Status mapping

Rules are evaluated from top to bottom:

| Gamma state                 | Probalytics `status` |
| --------------------------- | -------------------- |
| `closed = true`             | `RESOLVED`           |
| otherwise `archived = true` | `CLOSED`             |
| otherwise `active = false`  | `PENDING`            |
| otherwise                   | `ACTIVE`             |

### Lifecycle mapping

| Gamma source                                | Probalytics field |
| ------------------------------------------- | ----------------- |
| `createdAt`                                 | `created_at`      |
| `startDate`                                 | `opened_at`       |
| `endDate`                                   | `end_date`        |
| `endDate`                                   | `closes_at`       |
| `endDate`, with resolved time as a fallback | `resolves_at`     |

### Resolution mapping

Gamma does not expose one normalized winner field. For a closed market, settled `outcomePrices` become payout values:

| Settled payouts              | Result                                      |
| ---------------------------- | ------------------------------------------- |
| One outcome has payout `1`   | `STANDARD`, with that outcome as the winner |
| All payouts sum to `0`       | `VOID`                                      |
| Any other payout combination | `SPLIT`                                     |

These rows come from Gamma rather than market-creation chain events, so `source_block_number` is normally `0` and `source_tx_hash` is normally empty.

## Polymarket perpetuals

Polymarket perpetual instruments use a separate product feed and remain under `platform = 'POLYMARKET'`.

| Field         | Value or rule                                      |
| ------------- | -------------------------------------------------- |
| `platform_id` | Numeric venue instrument ID as a string            |
| `title`       | Instrument symbol; falls back to the instrument ID |
| `market_type` | `PERPETUAL`                                        |
| `outcomes`    | One synthetic `Long` outcome at index `0`          |
| `created_at`  | Fixed product reference epoch: 2026-07-01          |
| `status`      | `ACTIVE`                                           |
| `description` | Empty                                              |

The source also provides base/quote assets, funding interval, and price/quantity decimal metadata. Those attributes are used internally but are not currently columns in the public `markets` table.

## Kalshi prediction markets

### Source

Kalshi market records are enriched with event and series metadata. The result combines the market ticker and rules with the related series title, category, and URL structure.

### Identity and outcomes

* The venue ticker becomes `platform_id`.
* `id` is generated deterministically from the ticker.
* `Yes` is always outcome index `0`; `No` is outcome index `1`.
* Outcome UUIDs are generated deterministically from the market UUID and normalized side name.

### Display-field fallbacks

`title` uses the first non-empty value in this order:

1. title;
2. subtitle;
3. Yes subtitle;
4. No subtitle;
5. ticker.

`description` joins primary and secondary rules. `slug` comes from the series title, and the market URL is constructed from the series and market tickers.

### Type mapping

| Kalshi source                    | Probalytics `market_type` |
| -------------------------------- | ------------------------- |
| MVE collection ticker is present | `PARLAY`                  |
| Market type or result is scalar  | `SCALAR`                  |
| Otherwise                        | `BINARY`                  |

### Status mapping

| Kalshi status                        | Probalytics `status` |
| ------------------------------------ | -------------------- |
| `active`, `open`                     | `ACTIVE`             |
| `initialized`, `inactive`            | `PENDING`            |
| `closed`                             | `CLOSED`             |
| `determined`, `finalized`, `settled` | `RESOLVED`           |
| `paused`, `disputed`, `amended`      | `PAUSED`             |
| Any other value                      | `PENDING`            |

### Lifecycle mapping

| Kalshi source     | Probalytics field |
| ----------------- | ----------------- |
| `created_time`    | `created_at`      |
| `open_time`       | `opened_at`       |
| `close_time`      | `closes_at`       |
| `close_time`      | `end_date`        |
| `expiration_time` | `resolves_at`     |

### Resolution mapping

Resolution uses the most precise available source field:

1. `void` creates zero payouts and `resolution_type = 'VOID'`;
2. `settlement_value_dollars` sets the Yes payout directly and No payout to `1 - value`;
3. a Yes/No result creates `1`/`0` payouts;
4. a scalar result can be derived by comparing expiration value with the strike;
5. if the required scalar inputs are missing, payout data remains empty.

`resolution_resolved_at` uses settlement time when present, otherwise expiration time. `resolution_resolved_by` is `kalshi`.

## Kalshi margin instruments

Kalshi margin instruments use a separate product feed and remain under `platform = 'KALSHI'`.

| Field         | Value or rule                             |
| ------------- | ----------------------------------------- |
| `platform_id` | Venue margin ticker                       |
| `title`       | Venue title; falls back to the ticker     |
| `market_type` | `PERPETUAL`                               |
| `outcomes`    | One synthetic `Long` outcome at index `0` |
| `created_at`  | Fixed product reference epoch: 2026-06-17 |
| `description` | Empty                                     |
| `status`      | Mapped from the margin product state      |

Margin status mapping:

| Kalshi margin status  | Probalytics `status` |
| --------------------- | -------------------- |
| `active`, `open`      | `ACTIVE`             |
| `closed`              | `CLOSED`             |
| `settled`, `resolved` | `RESOLVED`           |
| `paused`, `inactive`  | `PAUSED`             |
| Any other value       | `PENDING`            |

The source contract size, tick size, and fractional-trading flag are used internally but are not currently columns in the public `markets` table.

## Querying the latest market version

ClickHouse replaces rows by `(platform, id)` and keeps the greatest `indexed_at` during background merges. Use `FINAL` when a query must see exactly one current version per market:

```sql theme={null}
SELECT *
FROM markets FINAL
WHERE platform = 'KALSHI'
  AND market_type = 'BINARY'
LIMIT 100;
```

Join fills and orderbook snapshots with `markets.id`. Use `platform_id` when you need the venue's native identifier.

See [Tables & Schemas](/docs/sql-guide/tables#markets) for the ClickHouse column types.
