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

# prediction_markets.trades

> Cross-venue trade table, one row per taker fill with prices normalized to P(Yes) in [0, 1].

export const TableSample = ({tableName, tableSchema}) => <>
    <div className="hidden dark:block">
      <iframe src={`https://dune.com/embeds/3419983/5785629?table_schema_t6f0df=${tableSchema}&table_name_t6f0df=${tableName}&darkMode=true`} style={{
  width: '100%',
  height: '500px',
  border: 'none',
  marginTop: '10px'
}} />
    </div>
    <div className="dark:hidden">
      <iframe src={`https://dune.com/embeds/3419983/5785629?table_schema_t6f0df=${tableSchema}&table_name_t6f0df=${tableName}`} style={{
  width: '100%',
  height: '500px',
  border: 'none',
  marginTop: '10px'
}} />
    </div>
  </>;

The `prediction_markets.trades` table is the cross-venue trade table. Grain: one row per taker fill, including Polymarket Combos (multi-leg parlays; `is_parlay = TRUE` in the markets dimension). Each match appears once, so `SUM(amount_usd)` is venue volume without any filter. Polymarket maker legs stay in the venue table ([`polymarket_polygon.market_trades`](/data-catalog/curated/prediction-markets/polymarket/market_trades), `is_taker_side = FALSE`).

Three columns describe every fill:

* `price` is always the **probability of Yes** in `[0, 1]`, comparable across venues and sides.
* `outcome_side` is the side of the market the traded contract belongs to (`yes` or `no`).
* `taker_side` is whether the taker bought or sold that contract (`BUY` or `SELL`).

`taker_fill_price` is the price of the contract actually traded (`price` for a Yes contract, `1 - price` for a No contract), so `taker_fill_price × num_contracts = amount_usd` on every row.

<Note>
  Kalshi nets positions and reports every fill as a buy of the side the taker ends up long, so `taker_side` is always `BUY` on Kalshi and closing a Yes position appears as a `BUY` with `outcome_side = 'no'`. Kalshi also reports one row per taker-maker match, so row counts are not comparable across venues; sums are.
</Note>

## Table Schema

| Column | Type | Description |
| - | - | - |
| `venue` | `VARCHAR` | `polymarket` or `kalshi` |
| `executed_at` | `TIMESTAMP` | When the trade executed |
| `block_month` | `DATE` | First day of the calendar month of `executed_at` (partition key) |
| `trade_id` | `VARCHAR` | Trade identifier, unique within a venue. On Polymarket `tx_hash:evt_index` |
| `market_id` | `VARCHAR` | Market traded: Polymarket `condition_id` (combo condition ID for Combos), Kalshi ticker. Joins `prediction_markets.markets` on `(venue, market_id)` |
| `event_id` | `VARCHAR` | Parent event of the market. Always populated on Kalshi; on Polymarket only for markets in a multi-outcome (neg-risk) event, NULL for Combos |
| `outcome_id` | `VARCHAR` | Identifier of the side traded: the token on Polymarket, the market itself on Kalshi. Keep it as text; Polymarket token IDs do not fit a numeric type. To label the side, join `prediction_markets.markets` and pick `yes_outcome_name` or `no_outcome_name` using `outcome_side` |
| `outcome_side` | `VARCHAR` | Side of the market the contract in `outcome_id` belongs to: `yes` (the side `price` refers to) or `no`. Same meaning on both venues |
| `taker_side` | `VARCHAR` | Whether the taker bought or sold the contract in `outcome_id`: `BUY` or `SELL`. Always `BUY` on Kalshi |
| `price` | `DOUBLE` | Probability of Yes at which the trade executed, in `[0, 1]` |
| `taker_fill_price` | `DOUBLE` | Price per contract of the contract traded: `price` when `outcome_side = 'yes'`, `1 - price` when `'no'`. Times `num_contracts` it equals `amount_usd` |
| `num_contracts` | `DOUBLE` | Contracts traded. One contract pays \$1 if its side wins |
| `amount_usd` | `DOUBLE` | Cash that changed hands, in USD: the buyer's cost and the seller's proceeds. Use it for volume |
| `fee_usd` | `DOUBLE` | Taker fee in USD. Reported on-chain for Polymarket; estimated from Kalshi's published fee formula for Kalshi, NULL where the series has no fee terms |
| `trader_address` | `VARCHAR` | The taker's wallet (0x-hex). Polymarket only; NULL on Kalshi |
| `tx_hash` | `VARCHAR` | Transaction hash (0x-hex). Polymarket only; NULL on Kalshi |
| `_updated_at` | `TIMESTAMP` | When the trade was last written by the pipeline |

## Table sample

<TableSample tableSchema="prediction_markets" tableName="trades" />

## Query performance

`block_month` is the partition key. Always include a `block_month` or `executed_at` filter.

```sql theme={null}
-- ✅ Good: time-bounded
SELECT * FROM prediction_markets.trades
WHERE block_month >= DATE '2026-05-01'
  AND venue = 'kalshi'
```

## Example queries

```sql theme={null}
-- Top markets by USD volume across both venues (last 7 days)
SELECT
  t.venue,
  t.market_id,
  m.question,
  COUNT(*) AS num_trades,
  SUM(t.amount_usd) AS total_volume_usd
FROM prediction_markets.trades t
JOIN prediction_markets.markets m
  ON m.venue = t.venue
  AND m.market_id = t.market_id
WHERE t.block_month >= DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1' MONTH
  AND t.executed_at >= NOW() - INTERVAL '7' DAY
GROUP BY 1, 2, 3
ORDER BY 5 DESC
LIMIT 20
```

```sql theme={null}
-- Taker flow by side over the last 24 hours
SELECT
  venue,
  outcome_side,
  taker_side,
  SUM(amount_usd) AS volume_usd,
  SUM(num_contracts) AS contracts
FROM prediction_markets.trades
WHERE block_month >= DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1' MONTH
  AND executed_at >= NOW() - INTERVAL '1' DAY
GROUP BY 1, 2, 3
ORDER BY 1, 2, 3
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.