BTC Hourly
# BTC Hourly
A binary option on the price of the Hyperliquid BTC perp, settled from **the
perp's own trades**. One market every hour, including 06:00 UTC: **24 scheduled
expiries per day**. The [BTC Daily](/markets/btc-daily) ladder now expires at
08:00 UTC and does not displace the hourly.
The strike is derived from the opening reference and fixed when the market
mints. The payout is decided by a volume-weighted average of every print in
the 90 seconds ending precisely on the hour. The number that pays is the book a maker hedges
on: no oracle, no index basis.
## At a glance
| | |
|---|---|
| Question | Will BTC be above the strike at the top of the hour? |
| Settlement measure | The [perp trade stream](/price-feeds/perp) — every print on the book, weighted by size. Not an oracle, not the mark formula: the tape itself. |
| Strike | Whole-dollar threshold derived from the trailing-90s trade VWAP at mint; read the fixed threshold on the market |
| Cadence | Every hour on the hour, including 06:00 UTC: 24 expiries/day. Expiries are minute-exact. |
| Settlement window | `(x:58:30 → x+1:00:00]`, ending exactly at expiry |
| Payout | Strict-above. Yes redeems 1 USDC if VWAP > strike; VWAP ≤ strike (equality included) pays No. |
| Sides | Yes/No trade as Hyperliquid spot books, USDC-quoted, on outcome dex `skew` |
| Fees | `deployerFeeScale` 1 **doubles your normal spot fee** — at tier 0 that is **14 bps taker / 8 bps maker**, charged only on close or settlement, never on open. See [Fees](#fees). |
| Concurrency | One hourly market at a time; the next round opens after its predecessor settles. |
| Cancellation | **None.** A minted market always settles: 1, 0, or 0.5. HIP-4 has no cancel. |
## Naming and identity
The chain renders the market's name from the validator-voted `binaryPrice`
template:
```text
name BTC above {strike} at {YYYYMMDD-HHMM}?
example BTC above 78174 at 20260831-1500?
```
The on-chain description, with the template's keywords filled:
```text
The market resolves to Yes if the BTC price is above 78174 at
20260831-1500, and otherwise resolves to No. Settlement is according
to the 90-second TWAP of the Hyperliquid BTC perp trade price ending
at 20260831-1500. If BTC is delisted before this market settles,
settlement is instead according to the BTC settlement price at delisting.
```
Five identity keywords are stamped on-chain at mint and are immutable:
`perp:BTC`, `priceDescription:the Hyperliquid BTC perp trade`, `seconds:90`,
`threshold:`, `time:`.
> The template's fixed word is "TWAP". The defined measure behind it is the
> **size-weighted average of the window's trade prices** — a VWAP over the
> window's own tape. [Resolution](#resolution) describes that computation;
> the deployed market's immutable terms remain authoritative.
### Tradeable instruments
Every market `N` (its outcome id) exposes two spot instruments, derived
arithmetically. The platform API serves all four values per market, so nothing
needs deriving by hand.
| Side | Encoding | Spot coin | Asset id |
|---|---|---|---|
| Yes | `10·N` | `"#" + 10·N` | `100,000,000 + 10·N` |
| No | `10·N + 1` | `"#" + (10·N+1)` | `100,000,000 + 10·N + 1` |
Outcome `16029` → Yes coin `#160290`, asset id `100160290`; No coin `#160291`.
Books, orders and fills use these like any Hyperliquid spot pair.
## Lifecycle
Taking the 15:00 market as the example hour:
| Time | Event | Detail |
|---|---|---|
| `14:00:00–00:30` | **Minted and open** | First reconcile tick after the hour (30s cadence). Strike = the trade VWAP of the trailing 90s at the read — the same measurement settlement will make, so open and close are priced identically. |
| `14:00 → 15:00` | **Trading** | ~59+ minutes of book time. Quoting into the close is quoting against the forming settlement VWAP. |
| `14:58:30` | **Settlement window opens** | Every trade on the BTC perp from here to expiry enters the settlement VWAP, weighted by its size. |
| `15:00:00` | **Expiry** | The window closes exactly here. Minute-exact; no drift, no per-market variation. |
| `15:00:05+` | **Settlement eligible** | A 5s floor, then the engine waits for **proof the window closed**: a trade printing later than 15:00:00. One ordered socket delivers everything before that print first, so its arrival means nothing earlier is still in flight — evidence, not a guess. |
| `~15:00:50` | **Settled, and replaced** | The winning side is paid and the 16:00 market is minted **in the same reconcile pass**. The archive row gains `settledAt`, `resolvedValue` and `settleReason`. |
At the August 2026 mainnet measurement, settlement landed **48–68 seconds
after expiry**. These timings are observations, not a guaranteed settlement SLA.
**One market at a time, so the roll is a handover rather than an overlap.** The
replacement cannot be minted while its predecessor is unsettled, so the book is
briefly empty — measured at **1 second**. An earlier configuration ran two
overlapping hourlies to remove even that; it was dropped deliberately, because
two strikes on one asset split the book and the liquidity, which costs a maker
more than a one-second gap. The current hourly includes 06:00 UTC, so its
scheduled deploy cost is 24 mints/day.
After a pod restart, the first mint waits about two minutes for the stream
buffer to cover its trailing window, then lands.
## The price feed
| | |
|---|---|
| Feed | The Hyperliquid BTC perp `trades` channel — every print, as it happens |
| Live endpoint | `wss://api.hyperliquid.xyz/ws`, subscription `{"type":"trades","coin":"BTC"}` — public, no auth |
| Per print | `px`, `sz` (base size), `time` (ms), `tid`. Price and size are all the resolution uses. |
| Historical | Hyperliquid's published trade archive; plus per-bucket settlement traces in the oracle logs and the final value on the archive row |
| Measured flow | **165–627 trades, $0.2M–$5.6M notional** per 90s window (live, 2026-08-30) |
**The tape decides — the same book a maker hedges on.** Settlement is computed
from actual prints on the BTC perp, so the settling number and a perp hedge
move print-for-print. There is no index in the path and therefore no basis
between two different price sources: the market resolves on the venue's own
book. Its binary payout still requires a hedge that accounts for the threshold;
sharing a price source does not make one perp a fixed one-for-one hedge.
The delisting fallback in the contract text is unchanged: if the BTC perp were
delisted, settlement is its delisting settlement price.
**A live feed has no replay, and the oracle treats that honestly.** The engine
holds one continuous subscription and refuses to price any window its
subscription did not fully cover. Finished coverage spans are remembered, so a
blip *after* expiry never strands a watched window. A window that a real outage
overlaps can never be re-observed — it follows the void path below rather than
being priced on partial evidence.
## Resolution
The same computation, with the same parameters, at both ends of the market's
life: the strike at mint and the verdict at expiry. Every settlement is logged
with per-bucket traces, so the verdict is re-derivable line by line.
### 1 · Bucketing
```text
window (T−90s, T] sliced into 18 buckets of 5s (T = expiry)
bucket_b every trade with time in (b_start, b_end]:
vwap_b = Σ(px·sz) / Σ(sz) over the bucket's prints
vol_b = Σ(sz)
drop a bucket in which nothing traded — no sample, no carry-forward,
no interpolation (measured live: 18/18 buckets fill every tick)
need ≥ 12 traded buckets of the 18 (min_samples)
```
### 2 · The settlement value — a true window VWAP
```text
VWAP = Σ vol_b·vwap_b / Σ vol_b
= Σ(px·sz) / Σ(sz) over EVERY print in the window — exactly.
```
Bucketing loses nothing; it only gives `min_samples` something honest to count.
Weight is traded size: a print is not an estimate with a confidence, it is a
price somebody paid, so how much traded is the only honest weight.
### 3 · The verdict
```text
diff = VWAP − strike (full precision, no rounding)
diff > 0 → settle 1 (Yes pays)
diff ≤ 0 → settle 0 (No pays — EQUALITY IS NO, per the contract text:
"above X ... otherwise resolves to No")
stream outage over the final 90s (< 12 traded buckets, or a
subscription gap the window overlaps — a live feed has no replay)
→ retry next tick, up to 3 attempts, then settle 0.5
(VOID: each side pays 0.50 USDC per token before fees;
a price that was never measured cannot be compared)
```
**This market always resolves on price.** Both decision bands are zero: the
settlement value is defined as the computed window VWAP, and the rule is
strict-above on that number. There is no "too close to call". This matches the
on-chain contract text exactly, which contains no closeness clause.
**The window never moves.** Retries — the outage case only — re-read the same
`(T−90s, T]` window. The settlement instant is `T`, full stop.
**No rounding at the close.** The VWAP is compared to the strike at full decimal
precision. Only the strike itself was quantized, to the dollar, at the open.
## Verifying a settlement
The inputs are the public tape: every BTC perp print in `(T−90s, T]`, where `T`
and the window length are on the market itself (`time`, `seconds`).
A maker recording the trades websocket — or reading Hyperliquid's published
trade history — reproduces the verdict from the math above alone. The oracle
logs every settlement with per-bucket traces (bucket VWAP, base volume,
notional, trade count), and the archive row stores the final value as
`resolvedValue`. A maker's replication and the platform's number should agree
to the decimal.
## Getting it from the APIs
### Discovery — the platform API
```http
GET https://api.skew.trade/api/v1/markets?status=MARKET_STATUS_LIVE&network=mainnet
Authorization: Bearer
```
```json
{ "markets": [{
"outcome": 16029,
"network": "mainnet", "venue": "skew",
"title": "Bitcoin above 78174",
"shape": "MARKET_SHAPE_BINARY",
"status": "MARKET_STATUS_LIVE",
"threshold": "78174",
"expiry": "2026-08-31T15:00:00Z",
"twapSeconds": 90,
"feeScale": "10",
"yesCoin": "#160290", "noCoin": "#160291",
"yesAssetId": 100160290, "noAssetId": 100160291,
"underlying": {
"symbol": "BTC", "displayName": "Bitcoin", "assetClass": "crypto",
"chartSource": "CHART_SOURCE_HYPERLIQUID", "chartSymbol": "BTC"
},
"schedule": {
"cadence": "0 * * * *",
"description": "every hour at :00 UTC",
"upcoming": [ { "opensAt": "...", "expiresAt": "..." } ]
}
}]}
```
Render `title`; never build a label from `perp`. Group by
`underlying.displayName`, and draw upcoming-but-unminted slots from
`schedule.upcoming`.
**Settled history:** the same endpoint with `status=MARKET_STATUS_SETTLED`, or
`GET /api/v1/markets/{outcome}?network=mainnet` for one id. The archive keeps
every market forever, with `resolvedValue` and a `settleReason` spelling out
the verdict.
**Charts:** read `underlying.chartSource`. For this market it is
`CHART_SOURCE_HYPERLIQUID` with `chartSymbol: BTC` — candles come straight from
the public Hyperliquid info API (`candleSnapshot`, coin `BTC`), which is the
same book that settles it. Skew's own marketdata service serves assets
Hyperliquid does not carry; the row tells you which applies, so there is no
client-side mapping.
### Books, orders, fills — straight Hyperliquid, no auth
```bash
# the live outcome set, chain-truth (public):
POST https://api.hyperliquid.xyz/info {"type":"outcomeMeta"}
# → filter venue "skew"; each entry carries the keywords above
# order book on a side (spot semantics, USDC quote):
POST https://api.hyperliquid.xyz/info {"type":"l2Book","coin":"#160290"}
# orders via the standard /exchange spot flow on assetId 100160290;
# ws subscriptions (l2Book, trades, bbo) take the same "#" coin names.
```
## Fees
**`deployerFeeScale` is 1, which doubles your normal spot fee.** You pay your
usual rate to Hyperliquid and an equal amount to the venue:
```
fee = (your spot tier rate) × (1 + deployerFeeScale) × (1 − your discounts)
```
| Action | Fee | At tier 0 |
|---|---|---|
| **Open** a position (buy Yes or No) | none | **0 bps** |
| **Close** early, crossing the spread | taker | **14 bps** |
| **Close** early, resting | maker | **8 bps** |
| **Settlement** at expiry | taker | **14 bps** of payout notional |
| **Merge** Yes+No back to collateral | taker | **14 bps** |
Since these markets are held to expiry rather than traded out, the practical
reading is that **the fee lands once, at settlement, on whatever you are
holding** — there is no entry cost.
Your own rate depends on your VIP tier and any referral or staking discounts, so
compute from the formula rather than the table. Verified against live fills: a
$186 settlement by a tier-1 taker with a 4% referral discount was charged
$0.21427199 — exactly 6 bps × 2 × 0.96.
**There are no maker rebates on outcome trading.** Traders who would earn rebates
on spot or perps pay zero on maker orders here instead.
**Check it yourself.** `recentTrades` on an outcome coin returns both
counterparties; `userFills` on either address gives the real `fee` per fill, with
`dir` naming the action. No authentication required.
## Notes for makers
**Every hour, with a handoff at the roll.** A fresh near-the-money market every
hour, including 06:00 UTC. Strike distance
from spot at open is ≈ 0 by construction, so the first quotes each hour are
near 50/50 by design.
**The settlement and perp hedge share a price source.** The settling number is
the VWAP of the same book a perp hedge trades on. That removes the mismatch
between an external index and the perp tape. The binary payoff is nonlinear,
so position size, rebalancing and execution still matter.
**Minute risk at the close.** The final 90 seconds are the settlement window,
and weight is traded size. Moving the VWAP means trading real size against the
whole window's flow — measured at $0.2M–$5.6M notional per window — on a public
tape, into 18 buckets. A single print moves it only in proportion to what it
paid.
**Void behaviour.** The market always resolves on price: quiet hours pay whoever
was right, and an exact tie pays No. The only void is a stream outage over the
final 90 seconds, paying 0.50 USDC per token on both sides before fees. A trader
who paid more than 0.50 can still lose money on that result.
**No cancel, no re-strike.** Once minted, parameters are immutable. A mis-minted
market can only settle by its own published terms.
**Fees are frozen per market.** The fee scale is stamped at mint and echoed on
every row as `feeScale`; a schedule change never applies retroactively. Read the
row rather than assuming the venue-wide value.
**Timing sync.** Everything is UTC and expiries are minute-exact. Settlement
follows expiry after the engine has enough evidence; the replacement market
appears after its predecessor settles.
## Status
**Launched on mainnet on 2026-08-30.** The current schedule has an expiry at
every UTC hour, including 06:00. Mainnet terms were rechecked on October 28,
2026; read the live set for the current outcome ID and strike.
**The initial settlement verification covered both outcomes** — Yes and No —
each on a size-weighted VWAP of the perp tape, and independently reproduced
from a second recording of the same public trades. Those checks agreed with the oracle to
the last published decimal, which is the property the market's text promises:
anyone recording the tape can compute the settlement themselves.
Read the live set from the markets API rather than inferring the current market
from this page — the strike changes every hour.
The same product runs on the testnet venue `pewt` — `network=testnet` on every
call above, hosts unchanged except `api.hyperliquid-testnet.xyz`. It is
identical except for `min_samples: 1`, because the testnet tape prints about 3
trades per 90 seconds against mainnet's 165–627. The per-network floors are
pinned by a guard test.
### The dials, as set
Everything above is deployed config or measured behaviour. These are the
judgment calls embedded in it, listed so a review is of choices rather than
archaeology.
| Dial | Set to | Note |
|---|---|---|
| Settlement source | perp trade stream | The Hyperliquid BTC perp's own prints, resolved as a size-weighted VWAP. Chosen 2026-08-30 after a live measurement run, so the payout is the book a maker hedges on. |
| Strike rule | Whole-dollar threshold derived at mint | The market's published threshold is fixed; settlement compares against it at full precision. |
| Decision bands | none (0 / 0) | Always resolves on price; equality pays No, per the contract text. Void only on stream outage. Platform-wide, ladders included. |
| Window / step / min samples | 90s / 5s / 12 of 18 | Short on purpose: the market asks about an instant. Measured live, 18/18 buckets fill. |
| Retries before void | 3 | Densify in place; the window never slides. A gap the window overlaps can never heal, so it spends its retries and resolves to 0.5. |
| Concurrency | budget 1 / horizon 1 | One market at a time; the replacement mints in the settling tick (1s of empty book). Changed from budget 2 on 2026-08-30 — that ran two overlapping hourlies for the last ten minutes of every hour, which split the book on one asset. 24 deploys/day. |
| Fees | scale 1 (14/8 bps at tier 0) | Doubles the trader's own spot rate. Lowered from the chain ceiling of 10 on 2026-08-30, before the first mainnet mint: on a book held to expiry the taker side lands on effectively every position, and scale 10 would have been **77 bps** against an at-the-money hourly — most of the edge a maker quotes for. |