Prediction Markets

Polymarket, Kalshi, and cross-platform prediction market data — trades, market details, prices, volume, and open interest.

17 tables in this category.

Tables

View NameDatabaseSourceORDER BY
agent.polymarket_tradesagentpolymarket_polygon.market_tradesblock_time, tx_hash, evt_index
agent.polymarket_market_detailsagentpolymarket_polygon.market_detailscondition_id, token_id
agent.polymarket_eventsagentpolymarket_polygon.events
agent.polymarket_prices_dailyagentpolymarket_polygon.market_prices_daily
agent.polymarket_prices_hourlyagentpolymarket_polygon.market_prices_hourly
agent.polymarket_prices_latestagentpolymarket_polygon.market_prices_latesttoken_id
agent.polymarket_volume_dailyagentpolymarket_polygon.market_volume_dailycondition_id, block_date
agent.polymarket_volume_hourlyagentpolymarket_polygon.market_volume_hourlycondition_id, block_hour
agent.polymarket_rolling_metricsagentpolymarket_polygon.market_rolling_metrics
agent.polymarket_open_interest_dailyagentpolymarket_polygon.market_open_interest_dailycondition_id, block_date
agent.polymarket_user_activityagentpolymarket_polygon.user_activity_v2account, token_id, block_time
agent.kalshi_market_detailsagentkalshi.market_detailsmarket_ticker
agent.kalshi_tradesagentkalshi.tradesticker, created_time, trade_id
agent.prediction_markets_dailyagentprediction_markets.daily
agent.prediction_markets_matched_marketsagentprediction_markets.matched_markets
agent.prediction_markets_matched_dailyagentprediction_markets.matched_daily
agent.polymarket_positionsagentNone
  • agent.kalshi_daily_categorized
  • agent.kalshi_market_report
  • agent.prediction_category_daily

Sample Queries

1. Daily volume by platform

SELECT date, source,
       sum(notional_volume_usd) AS volume,
       sum(open_interest_usd) AS oi
FROM agent.prediction_markets_daily
WHERE date >= today() - 30
GROUP BY date, source
ORDER BY date DESC, source

Table Schemas

agent.polymarket_trades

Individual Polymarket trade events (OrderFilled) with USD amounts, maker/taker addresses, condition IDs, and outcome context. One row per trade event. The primary source for Polymarket volume and trading activity analysis.

Engine: MergeTree | Partition: toYYYYMM(block_date) | ORDER BY: block_time, tx_hash, evt_index

ColumnTypeDescription
block_dateDatePartition key. Always filter on this.
block_timeDateTime64(3)Trade timestamp.
block_numberUInt64Block number
tx_hashStringTransaction hash
evt_indexUInt32Event log index in transaction
exchange_addressString
protocolString
projectStringProtocol name
order_hashString
maker_addressStringMaker (liquidity provider) address.
taker_addressStringTaker (liquidity consumer) address.
maker_asset_idString
taker_asset_idString
maker_amount_filledUInt256
taker_amount_filledUInt256
fee_rawUInt256
outcome_token_idString
sharesFloat64
amount_usdFloat64Trade notional value in USD (one-sided).
priceFloat64Token price in USD
fee_usdFloat64
condition_idStringUnique market condition identifier. Links to market_details.
questionString
outcome_indexUInt8
outcome_labelString
categoryStringMarket category
market_slugString
market_end_dateDateTime
neg_riskUInt8
question_idString
event_slugString
event_titleStringEvent title
💡 Tip
  • account = maker captures both sides of a trade — do NOT fan out to both maker and taker
  • This follows Paradigm methodology: each OrderFilled with account=maker is one-sided volume
  • 934M rows — always filter on block_date or block_time ranges
  • condition_id links to market_details for market question and metadata
  • JOIN with polymarket_market_details ON condition_id for market enrichment
⚠️ Warning
  • On-chain trades only — off-chain order book and cancellations not included
  • Pipeline lag: Polygon BQ export runs every 1h, typical lag ~1 hour
  • No aggregator/frontend attribution — all trades appear as CTF Exchange events

agent.polymarket_market_details

Polymarket market metadata dimension table. Contains market questions, descriptions, event groupings, resolution status, end dates, tags, and Polymarket links. One row per (condition_id, outcome_index) — use outcome_index=0 for one row per condition.

Engine: MergeTree | ORDER BY: condition_id, token_id

ColumnTypeDescription
condition_idStringPrimary market identifier. Links to all other Polymarket tables.
question_idStringGroups related conditions into a single question (e.g., 'Will X win?' has Yes/No conditions).
questionStringMarket question text (e.g., 'Will Bitcoin reach $100K by December 2026?').
market_descriptionStringLonger market description with resolution criteria.
token_idString
outcome_indexUInt80 or 1. Use 0 for deduplication (one row per condition).
outcome_labelString
token_outcome_nameString
categoryStringMarket category
market_slugString
event_slugStringURL-safe event identifier for Polymarket links.
event_titleStringParent event title grouping multiple markets.
market_end_dateDateTimeScheduled market end date.
neg_riskUInt8Boolean. True = this is a neg-risk (multi-outcome) market.
activeUInt8Boolean. True = market is currently open for trading.
closedUInt8Boolean. True = market has been closed (trading halted).
archivedUInt8
volume_totalFloat64
liquidityFloat64
resolved_atDateTime64(3)Resolution timestamp. Null if unresolved.
created_atDateTime
updated_atDateTime
market_idUInt64
start_timeDateTime
close_timeDateTime
game_start_timeDateTime
tagsStringArray of category tags.
volume_1wkFloat64
volume_1moFloat64
volume_1yrFloat64
resolution_sourceString
imageString
iconString
neg_risk_market_idString
event_descriptionString
event_start_timeDateTime
event_imageString
event_resolution_sourceString
statusStringMarket status (active, closed, resolved)
winning_outcome_indexInt8
polymarket_linkStringDirect URL to this market on polymarket.com.
💡 Tip
  • Filter outcome_index = 0 for one row per condition (avoids duplicates)
  • question is the market title/question text
  • active=true means the market is currently tradeable
  • closed=true means the market has stopped trading (may or may not be resolved)
  • Tags is an array — use hasAny(tags, ['politics']) for tag filtering
  • condition_id is the primary join key to trades, positions, volume, and OI tables
⚠️ Warning
  • Metadata reflects current state — does not track historical changes to descriptions or end dates
  • category/subcategory not directly in this table — join with curated ranking or category tables

agent.polymarket_events

Polymarket event-level metadata. Events group related markets (conditions) under a single theme (e.g., "2026 US Presidential Election" groups multiple candidate-specific markets). Useful for navigating the market hierarchy.

💡 Tip
  • Events contain multiple conditions — join with market_details on event_slug for full expansion
  • Useful for building hierarchical market browsers (event -> conditions -> trades)
⚠️ Warning
  • Not all markets belong to events — some standalone markets have no parent event

agent.polymarket_prices_daily

Daily outcome token prices for Polymarket markets. Tracks the probability (price) of each outcome over time. Useful for building price charts and tracking market sentiment evolution.

💡 Tip
  • Price represents implied probability (0-1 range, where 1.0 = 100% chance)
  • Combine with market_details for market question context
  • For binary markets, only one outcome price is needed (the other is 1 - price)
⚠️ Warning
  • Daily granularity only — no intraday price snapshots available in this table
  • Prices reflect last trade of day, not volume-weighted average

agent.polymarket_prices_hourly

Hourly CLOB mid-prices per Polymarket outcome token. Provides intraday price (implied probability) resolution for building higher-frequency charts and detecting rapid sentiment shifts.

💡 Tip
  • Prices represent implied probability (0-1 range). Multiply by 100 for percentage.
  • Filter on block_date first for partition pruning, then narrow by hour if needed
  • For binary markets, one outcome price is sufficient — the other is 1 - price
  • JOIN with polymarket_market_details ON condition_id for market question context
⚠️ Warning
  • Mid-prices from CLOB — may be stale for illiquid markets with wide spreads
  • Not volume-weighted — reflects order book mid, not trade-weighted average

agent.polymarket_prices_latest

Latest snapshot price per Polymarket outcome token. A convenience view that returns the most recent price for each condition, eliminating the need for argMax() queries against the full prices table.

Engine: MergeTree | ORDER BY: token_id

ColumnTypeDescription
token_idString
condition_idStringPolymarket condition ID
questionString
outcome_indexUInt8
outcome_labelString
last_updatedDate
latest_priceFloat64
💡 Tip
  • One row per condition — no time filter needed
  • Equivalent to argMax(price, timestamp) from the full prices table but pre-computed
  • JOIN with polymarket_market_details ON condition_id for enrichment
⚠️ Warning
  • Point-in-time snapshot — reflects the most recent pipeline run, not tick-level
  • Stale for markets with no recent trading activity

agent.polymarket_volume_daily

Daily aggregated trading volume per Polymarket market condition. Pre-computed from individual trades for efficient time-series queries. One row per (condition_id, block_date).

Engine: MergeTree | Partition: toYYYYMM(block_date) | ORDER BY: condition_id, block_date

ColumnTypeDescription
block_dateDateDate of the volume observation.
condition_idStringMarket condition identifier.
trade_countUInt64
notional_volume_usdFloat64Daily notional trading volume (one-sided, USD)
💡 Tip
  • Much faster than aggregating polymarket_trades for daily volume — prefer this table
  • JOIN with market_details ON condition_id for market context
  • For platform-level total volume, sum across all conditions per day
⚠️ Warning
  • Granularity is daily only — for intraday volume, use polymarket_trades directly

agent.polymarket_volume_hourly

Hourly trading volume per Polymarket condition. Pre-aggregated from individual trades for efficient intraday volume analysis without scanning the full trades table.

Engine: MergeTree | Partition: toYYYYMM(toDate(block_hour)) | ORDER BY: condition_id, block_hour

ColumnTypeDescription
block_hourDateTime
condition_idStringPolymarket condition ID
trade_countUInt64
notional_volume_usdFloat64Daily notional trading volume (one-sided, USD)
💡 Tip
  • Filter on block_date for partition pruning, then refine by hour
  • Much faster than aggregating polymarket_trades hourly
  • JOIN with polymarket_market_details ON condition_id for market context
⚠️ Warning
  • Hourly granularity only — for sub-hour analysis, use polymarket_trades

agent.polymarket_rolling_metrics

Pre-computed rolling window metrics for Polymarket markets (e.g., 7-day volume, 30-day volume, trailing unique traders). Useful for ranking and screening markets by recent activity without expensive window function queries.

💡 Tip
  • Pre-computed rolling windows are much faster than manual window functions on trades
  • Use for market ranking and filtering — then drill into volume_daily or trades for details
⚠️ Warning
  • Rolling window definitions are fixed — cannot customize the window period
  • Updated periodically, not real-time

agent.polymarket_open_interest_daily

Cumulative open interest per Polymarket condition derived from on-chain events (splits, merges, redemptions, conversions). SPARSE: only has rows on days with events, not every calendar day. Requires gap-fill logic for time series.

Engine: MergeTree | Partition: toYYYYMM(block_date) | ORDER BY: condition_id, block_date

ColumnTypeDescription
block_dateDateDate of the OI change event. SPARSE — not every day has a row.
condition_idStringMarket condition identifier.
daily_net_change_rawInt256
daily_net_change_usdFloat64
open_interest_rawInt256
open_interest_usdFloat64Cumulative OI in USD for this condition on this date. Can be negative for neg-risk conditions.
💡 Tip
  • SPARSE data — use argMax(open_interest_usd, block_date) per condition to gap-fill (carry forward)
  • Do NOT use HAVING last_oi > 0 — some conditions legitimately have negative OI (neg-risk markets)
  • Do NOT filter by market resolution status — resolved markets' OI decreases naturally via PayoutRedemption
  • For global OI: sum(argMax(open_interest_usd, block_date)) across all conditions
  • Neg-risk markets: individual conditions can have large negative OI — the group total across sibling conditions is correct
  • Do NOT apply neg_risk correction (sum/count(DISTINCT condition_id)) — the raw sum is already correct
⚠️ Warning
  • Sparse — only rows on days with OI-affecting events, not a continuous daily series
  • ~5% undercount vs Polymarket subgraph due to ~97K conditions missing from decoded events
  • Individual neg-risk condition OI can be large negative — always sum across sibling conditions for market-level OI

agent.polymarket_user_activity

Per-user trade activity on Polymarket including buy/sell counts, volume, and realized PnL. Aggregated by (address, condition_id) to show each user's activity within each market.

Engine: MergeTree | Partition: toYYYYMM(block_date) | ORDER BY: account, token_id, block_time

ColumnTypeDescription
block_dateDateUTC block date
block_timeDateTime64(3)UTC block timestamp
block_numberUInt64Block number
tx_hashStringTransaction hash
evt_indexUInt32Event log index in transaction
accountString
token_idString
event_typeString
sideString
amountFloat64Amount in display units (decimal-adjusted)
priceFloat64Token price in USD
amount_usdFloat64USD value of transfer
💡 Tip
  • Filter by address for single-wallet analysis
  • account = maker follows Paradigm methodology — captures both sides correctly
  • JOIN with polymarket_market_details ON condition_id for market context
  • Aggregated per (address, condition_id) — sum across conditions for total user activity
⚠️ Warning
  • Uses proxy wallet addresses — no mapping to user identities
  • PnL is realized only — does not include unrealized gains on open positions

agent.kalshi_market_details

Kalshi market metadata and snapshot data. Contains market tickers, titles, categories, settlement details, and status. Kalshi uses a three-level hierarchy: series -> events -> markets. MVE (parlay) markets skip the event layer.

Engine: MergeTree | ORDER BY: market_ticker

ColumnTypeDescription
market_tickerStringUnique market identifier (Kalshi)
event_tickerStringParent event ticker. Empty for MVE (parlay) markets.
event_titleStringEvent title
event_subtitleString
titleStringMarket title/question text.
start_timeDateTime64(3)
end_timeDateTime64(3)
close_timeDateTime64(3)
categoryStringMarket category
subcategoryStringMarket subcategory
payout_typeString
statusStringMarket status: 'active', 'closed', 'settled', etc.
last_priceFloat64
total_volumeUInt64Cumulative total volume
daily_volumeUInt64Daily contract volume
open_interestFloat64End-of-day open interest (contracts)
resultStringMarket result (if resolved)
yes_bidFloat64
yes_askFloat64
no_bidFloat64
no_askFloat64
last_day_open_interestFloat64
💡 Tip
  • Kalshi hierarchy: series -> events -> markets. MVE markets skip the event layer
  • event_ticker links to events; series_ticker from events links to series
  • For MVE markets, derive series_ticker from splitByChar('-', ticker)[1]
  • Use FINAL if the underlying table is ReplacingMergeTree
⚠️ Warning
  • Large table (55.6M rows) due to historical snapshots — filter by status or date range
  • MVE (parlay) markets have different structure than regular markets — see Kalshi data model docs
  • Centralized exchange data — no on-chain verification possible

agent.kalshi_trades

Individual Kalshi trade events. Each row represents a single fill on the Kalshi exchange with price, quantity, side, and market ticker. The raw trade-level data source for Kalshi volume analysis.

Engine: ReplacingMergeTree | Partition: toYYYYMM(trade_date) | ORDER BY: ticker, created_time, trade_id

ColumnTypeDescription
trade_idString
tickerString
num_contractsUInt32
taker_sideString
maker_sideString
yes_priceFloat64
no_priceFloat64
trade_dateDate
created_timeDateTime64(3)
💡 Tip
  • Filter on date or created_time for partition pruning
  • ticker links to kalshi_market_details for market metadata
  • Price is in cents (0-100 range for binary markets)
  • count is the number of contracts in the fill
⚠️ Warning
  • Centralized exchange data — no on-chain verification
  • Trade history depth depends on Kalshi API availability
  • No user/wallet attribution — trades are anonymous

agent.prediction_markets_daily

Unified daily prediction market volume and open interest across Kalshi and Polymarket. One row per (date, source, category, subcategory). Uses Paradigm-compatible category taxonomy. Only includes dates where BOTH platforms have data to avoid partial comparisons.

💡 Tip
  • source is 'Kalshi' or 'Polymarket' — filter for single-platform or compare both
  • Both platforms must have data for a date to appear — gaps mean one platform had no data
  • notional_volume_usd is one-sided volume in USD
  • open_interest_usd is cumulative OI in USD
  • For total market volume: sum both sources
⚠️ Warning
  • Only dates with data from BOTH platforms — single-platform activity on gap days is lost
  • Category taxonomy depends on upstream categorization models — some markets may be 'UNKNOWN'
  • Volume methodology may differ slightly between platforms (both aim for one-sided)

agent.prediction_markets_matched_markets

Polymarket-to-Kalshi matched market pairs. Each row is a strict one-to-one (condition_id, market_ticker) pair linking the same event across platforms. Enriched with live volume and OI from both sides. Generated via LLM matching (Grok) with confidence scoring.

💡 Tip
  • match_type is 'exact' (same question) or 'related' (same event, different angle)
  • confidence ranges from 75-100 — higher is more reliable
  • One-to-one mapping — no fan-out or duplication
  • JOIN with platform-specific tables for additional enrichment
⚠️ Warning
  • Coverage depends on LLM matching quality — not all markets are matched
  • Confidence threshold at 75+ — some lower-confidence matches may be excluded
  • Seed-based — new markets require re-running the matching pipeline

agent.prediction_markets_matched_daily

Daily volume and open interest comparison for matched Polymarket-Kalshi market pairs. One row per (condition_id, market_ticker, date) with side-by-side volume and OI from both platforms. The time-series companion to matched_markets.

💡 Tip
  • Filter on date for partition pruning
  • Compare polymarket_volume_usd vs kalshi_volume_usd for platform share on matched events
  • JOIN with prediction_markets_matched_markets for match metadata (confidence, match_type)
⚠️ Warning
  • Only includes matched markets — unmatched markets on either platform are excluded
  • Date coverage limited to overlap period where both platforms have data

agent.polymarket_positions

Current Polymarket user positions with market context. A custom view that JOINs user_positions_v2 (on-chain position tracking) with market_details for enrichment. Shows open positions with balance, PnL, cost basis, and market metadata. Filters to positions with net_shares > 0.000001 (non-dust).

💡 Tip
  • Filter by address for wallet-specific portfolio view
  • holdings_usd = net_shares * value_per_share (current market value of position)
  • pnl is the realized + unrealized PnL for this position
  • cost_basis is the total USD spent acquiring the position
  • avg_buy_price is the volume-weighted average entry price
  • resolution_status shows if the market has resolved (won/lost/open)
⚠️ Warning
  • Current state snapshot — does not track historical position changes
  • Only shows positions with net_shares > 0.000001 — fully closed positions are excluded
  • Proxy wallet address, not the user's main wallet — address mapping not included