> ## 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.

# kalshi.ohlcv_hourly

> Kalshi hourly OHLCV candles — per-market open/high/low/close/volume with VWAP and trade count.

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 `kalshi.ohlcv_hourly` table provides hourly OHLCV (Open-High-Low-Close-Volume) candles per Kalshi market. Grain: one row per `(hour, market_id, outcome)`. Candles are built on the Yes price (the No price is `1 - Yes`). Hours without trades are a **flat bar at the carried close** with volume and trade count set to zero, flagged via `is_forward_filled`. Only markets with at least one fill have candles.

**Settlement.** Once a market settles, the bar at its settlement hour is pinned to the settled payout per contract: `close` becomes `1` for `yes`, `0` for `no`, or the scalar payout; `high`/`low` widen to include it; `open` keeps the last traded price. Forward-fill stops at that bar, while real trades after settlement keep their actual prices. Until a market settles, its candle series runs to its `expected_expiration_time` without resolving it, and later trades extend it.

<Note>
  `market_outcome` is **point-in-time per bar**: `unresolved` until the market has settled and the bar is at or after the settlement hour, then the settled result from that bar onward. Historical bars are never relabeled, and the other metadata columns keep the values they were written with. [`kalshi.market_details`](/data-catalog/curated/prediction-markets/kalshi/market_details) is the authoritative source for a market's *current* state.
</Note>

## Table Schema

| Column | Type | Description |
| - | - | - |
| `block_month` | `DATE` | First day of the UTC month of `hour` (partition key) |
| `hour` | `TIMESTAMP` | UTC hour bucket for the candle |
| `market_id` | `VARCHAR` | Kalshi market ticker. Joins `kalshi.market_details` on `market_id` |
| `market_name` | `VARCHAR` | Market question text |
| `outcome` | `VARCHAR` | Always `Yes`. Candles are built on the Yes price; the No price is `1 - Yes` |
| `yes_outcome_name` | `VARCHAR` | Human-readable label for the Yes side, such as a team, candidate or price range. Falls back to a label built from the market's strike, then to `Yes`. Use this as the outcome label; `outcome` is only the side flag |
| `category` | `VARCHAR` | Unified category (`sports`, `crypto`, `politics`, `finance`, `technology`, `culture`, `weather`, `world`, `health`, `other`, `mixed`) as written with the bar. `kalshi.market_details` carries the current value |
| `open` | `DOUBLE` | First trade price in the hour. Equal to the carried close on forward-filled hours. On the settlement bar it keeps the last traded price; settlement pins only the close |
| `high` | `DOUBLE` | Highest trade price in the hour. Equal to the carried close on forward-filled hours. On the settlement bar, widened to include the settled payout |
| `low` | `DOUBLE` | Lowest trade price in the hour. Equal to the carried close on forward-filled hours. On the settlement bar, widened to include the settled payout |
| `close` | `DOUBLE` | Last trade price in the hour, carried forward through no-trade hours. On the settlement bar, pinned to the settled payout per contract (`1` for yes, `0` for no, the scalar payout otherwise); bars from real trades after settlement keep their actual close |
| `vwap` | `DOUBLE` | Volume-weighted average price. NULL for forward-filled hours |
| `volume_contracts` | `DOUBLE` | Contracts traded in the hour, counting each fill once. Zero for forward-filled hours |
| `volume_usd` | `DOUBLE` | USD traded in the hour. Zero for forward-filled hours |
| `trade_count` | `BIGINT` | Number of trades in the hour. Zero for forward-filled hours |
| `market_end_time` | `TIMESTAMP` | End of the candle series: the market's settlement (or determination) time once known, otherwise its expected expiration time. Trades after an unsettled market's expected expiration extend the series past it |
| `expected_expiration_time` | `TIMESTAMP` | When the outcome is expected to be known, from `kalshi.market_details`. Bounds the candle series until the market resolves |
| `market_outcome` | `VARCHAR` | The market's state at this hour (point-in-time): `unresolved` until the market has settled and this bar is at or after the settlement hour, then the settled `result` from `kalshi.market_details` from that bar onward. Reaching the expected expiration does not resolve a market |
| `event_market_name` | `VARCHAR` | Parent event title, falling back to the market title |
| `is_forward_filled` | `BOOLEAN` | TRUE when the bar has no trades and was carried forward |
| `_updated_at` | `TIMESTAMP` | When this row was last written by the pipeline |

## Table sample

<TableSample tableSchema="kalshi" tableName="ohlcv_hourly" />

## Query performance

`block_month` is the partition key. Always include a `block_month` or `hour` filter for time-series queries.

## Example query

```sql theme={null}
-- Hourly price path for a single market
SELECT
  hour,
  open,
  high,
  low,
  close,
  volume_contracts,
  market_outcome
FROM kalshi.ohlcv_hourly
WHERE market_id = 'KXNHLGAME-26MAY03MINCOL-MIN'
  AND block_month >= DATE '2026-05-01'
ORDER BY hour
```


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