Settlement & Expiry
This page covers options on the main Hypercall Exchange. They are European-style and cash-settled in USDC. At expiry, positions are settled automatically against the underlying's settlement price, and the settlement value is credited to or debited from your account.
Expiry Time
| Underlyings | Expiry time |
|---|---|
| BTC, ETH | 08:00 UTC |
| Equities and indexes (SPCX, SP500, BOT, MU, NVDA, META, MSFT, AAPL, SNDK, BABA) | 20:00 UTC |
20:00 UTC is 4:00 PM New York time while US daylight saving time is in effect. The expiry is fixed in UTC, so it does not move with daylight saving.
At expiry:
- New orders are rejected
- Open orders are cancelled
- Positions enter the settlement process
The engine checks for expired instruments every minute.
Instrument Lifecycle
Instruments progress through three states:
| State | Description | Trading |
|---|---|---|
| Active | Normal trading | Enabled |
| Expired Pending Price | Awaiting the settlement price | Disabled |
| Settled | Settlement complete, positions closed | N/A |
State Transitions
- Active to Expired Pending Price: contract expiry time reached
- Expired Pending Price to Settled: settlement price available and all positions settled
Once an instrument enters Expired Pending Price, all open orders are cancelled and new orders are rejected with "Instrument has expired".
Settlement Price
The settlement price is a robust 30-minute average of the Hyperliquid oracle price for the underlying, taken over the 30 minutes that end at expiry.
| Parameter | Value |
|---|---|
| Price source | Hyperliquid oracle price (oraclePx) for the underlying's perp. BTC and ETH use the main Hyperliquid perps; equities and indexes use the xyz HIP-3 perps, for example xyz:NVDA. |
| Window | 30 minutes, ending at the expiry time |
| Sampling | Every distinct oracle update inside the window, by its Hyperliquid timestamp |
| Minimum samples | 500 |
| Averaging | Trimmed median of means |
How the average is computed
- Collect. Hypercall records each new oracle price observed between expiry minus 30 minutes and expiry. Repeated reads of the same update count once, and nothing published after expiry is used.
- Trim. Sort the samples by price and drop the top 5% and bottom 5%.
- Bucket. Split the remaining prices into roughly √n groups and average each group.
- Take the median of those group averages. That is the settlement price.
Trimming and the median of means make the price hard to move with a few outlying prints near expiry, while still tracking the whole window.
If there are not enough samples
A window with fewer than 500 samples is never used. If Hypercall's own record is short (for example, after a restart inside the window), it rebuilds the window from an archived history of the same Hyperliquid oracle price and applies the same 500-sample minimum and the same averaging. If neither source has enough samples, the instrument stays in Expired Pending Price and settlement waits. Hypercall does not settle on a partial window or a fallback price.
This is separate from how positions are marked during an oracle outage. Margin checks and liquidation keep valuing positions at the last recorded spot price, and risk-increasing orders are rejected once that price is more than 30 seconds old. See Failure Modes. The last recorded price is never used as a settlement price.
Settlement Value Calculation
Settlement is the intrinsic value of the option at the settlement price:
Call Options:
Put Options:
Where:
- = Settlement price
- = Strike price
- = Position size (signed: positive for long, negative for short)
Out-of-the-money options settle at zero and are removed. Option premium is paid in cash when you trade, so settlement moves only the intrinsic value. This applies to both standard and portfolio margin accounts.
Examples
Long Call (ITM):
- Position: Long 2 BTC-100000-C
- Settlement price: $105,000
- Intrinsic: max(0, 105000 - 100000) = $5,000
- Settlement value: 10,000** (credited)
Short Call (ITM):
- Position: Short 2 BTC-100000-C
- Settlement price: $105,000
- Settlement value: 10,000** (debited)
Long Put (OTM):
- Position: Long 1 BTC-100000-P
- Settlement price: $105,000
- Intrinsic: max(0, 100000 - 105000) = $0
- Settlement value: $0 (expires worthless)
Settlement Process
When settlement occurs:
- Price fetched: the finalized 30-minute settlement price
- Value computed: intrinsic value calculated for each position
- Cash moved: all options on one underlying with the same expiry settle as one batch, netted per account
- Position removed: the position is closed and removed from the portfolio
- Event emitted: a
PositionExpiredmessage is sent on theportfolioWebSocket channel
Settlement is processed with idempotency guarantees. Replays or restarts cannot cause double-settlement.
Who pays, by margin mode
- Standard margin: an account that owes settlement pays it in full from its Hypercall cash.
- Portfolio margin: an account that owes settlement pays from its Hypercall cash first, then from a loan from the PM lending pool. Anything the pool cannot fund becomes a pending obligation, due within the cure period. See PM Financing.
If a portfolio margin payer in the batch could not pay in full, the accounts owed money in that batch share the cash that was collected pro rata, and the rest is recorded as a pending claim that is paid, with interest, as the payer repays. The instrument settles either way; it never halts on an unpaid obligation.
WebSocket Events
PositionExpired
Sent on the portfolio channel when a position is settled:
{
"type": "PositionExpired",
"wallet_address": "0x...",
"symbol": "BTC-20250131-100000-C",
"position_size": "2",
"settlement_price": "5000",
"settlement_value": "10000",
"settlement_entry_price": "3200",
"cost_basis": "6400",
"net_pnl": "3600",
"timestamp": 1738310400000
}
| Field | Description |
|---|---|
position_size | Signed position size (positive = long, negative = short) |
settlement_price | Intrinsic value per contract |
settlement_value | Total cash settlement amount |
settlement_entry_price | Your per-contract entry price |
cost_basis | Position cost basis at settlement |
net_pnl | Settlement PnL net of cost basis, excluding fees |
Market expired
Sent on the market_updates channel when an instrument expires:
{
"type": "MarketUpdate",
"action": "Expired",
"symbol": "BTC-20250131-100000-C",
"strike": "100000",
"is_call": true,
"underlying": "BTC",
"expiry": 1738310400,
"timestamp": 1738310400000
}
API Endpoints
List Instruments by Status
GET /instruments?currency=BTC&status=EXPIRED_PENDING_PRICE
status defaults to ACTIVE. Pass EXPIRED_PENDING_PRICE, SETTLED, a comma-separated list, or all.
Get Settlement Payouts
GET /settlement-payouts?wallet=0x...
Returns settlement records for your account. Optional symbol, ledger_applied, limit (default 50, maximum 100) and offset.
Response:
{
"success": true,
"data": [
{
"id": 1,
"wallet": "0x...",
"symbol": "BTC-20250131-100000-C",
"expiry_ts": 1738310400,
"position_size": "2",
"settlement_price": "5000",
"settlement_value": "10000",
"settlement_entry_price": "3200",
"cost_basis": "6400",
"net_pnl": "3600",
"ledger_applied": true,
"is_seen": false,
"created_at": 1738310460000
}
],
"pagination": { "limit": 50, "offset": 0, "count": 1 },
"error": null
}
Failure Handling
Settlement Price Not Available
If the settlement price cannot be finalized at expiry:
- The instrument remains in
Expired Pending Price - Trading is already blocked
- The engine retries on every expiry check, once a minute
- Cash moves only after a settlement price that meets the 500-sample rule exists
System Restart
Settlement state is durable. If the system restarts:
- Expired instruments are picked up on startup
- Settlement continues automatically
- Idempotency guarantees prevent double-settlement
Parameters
| Parameter | Value | Description |
|---|---|---|
| Expiry check interval | 60 seconds | How often the engine checks for expiries and retries pending settlements |
| Settlement window | 30 minutes | Ends at the expiry time |
| Minimum samples | 500 | Fewer and the window is not used |
| Trim | 5% each tail | Removed before averaging |
Best Practices
- Monitor expiries: track expiry dates for your positions via the portfolio endpoint
- Plan ahead: close positions before expiry if you want to avoid settlement
- Watch the last 30 minutes: the settlement price is set by the oracle over that window, not by the price at the expiry instant
- Subscribe to WebSocket: receive real-time
PositionExpiredevents for immediate notification - Maintain margin buffer: keep enough cash or margin for potential ITM short settlements
See also:
- Liquidation: What happens if margin is insufficient
- Portfolio Margin: How positions affect margin
- PM Financing: How portfolio margin accounts pay settlement
- Standard Margin: Per-position margin calculation