Skip to main content

Settlement & Expiry

Options on Hypercall are European-style and cash-settled. At expiry, positions are automatically settled based on the underlying's reference price, with the settlement value credited or debited to your account.

Expiry Time

All options expire at 08:00 UTC on their expiry date.

At expiry:

  • New orders are rejected
  • Open orders are cancelled
  • Positions enter the settlement process

Instrument Lifecycle

Instruments progress through three states:

StateDescriptionTrading
ActiveNormal tradingEnabled
Expired Pending PriceAwaiting settlement price from oracleDisabled
SettledSettlement complete, positions closedN/A

State Transitions

  1. Active → Expired Pending Price: Expiry time reached (08:00 UTC)
  2. Expired Pending Price → 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 30-minute TWAP (Time-Weighted Average Price) of the Hyperliquid Oracle index price for the underlying asset.

ParameterValue
Price sourceHyperliquid Oracle (index price)
TWAP window30 minutes
Window end08:00 UTC (expiry time)

The oracle begins sampling 30 minutes before expiry and computes the TWAP at expiry time.

Settlement Value Calculation

Settlement is computed as the intrinsic value of the option at expiry:

Call Options:

Settlement Value=max(0,SK)×Q\text{Settlement Value} = \max(0, S - K) \times Q

Put Options:

Settlement Value=max(0,KS)×Q\text{Settlement Value} = \max(0, K - S) \times Q

Where:

  • SS = Settlement price (30-min TWAP)
  • KK = Strike price
  • QQ = Position size (signed: positive for long, negative for short)

Examples

Long Call (ITM):

  • Position: Long 2 BTC-100000-C
  • Settlement price: $105,000
  • Intrinsic: max(0, 105000 - 100000) = $5,000
  • Settlement value: 5,000×2=+5,000 × 2 = **+10,000** (credited)

Short Call (ITM):

  • Position: Short 2 BTC-100000-C
  • Settlement price: $105,000
  • Settlement value: 5,000×2=5,000 × -2 = **-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:

  1. Price fetched: Oracle returns the 30-minute TWAP
  2. Value computed: Intrinsic value calculated for each position
  3. Cash updated: Settlement value added to (long ITM) or subtracted from (short ITM) account balance
  4. Position removed: Position is closed and removed from portfolio
  5. Event emitted: PositionExpired message sent via WebSocket

Settlement is processed atomically per position with idempotency guarantees. Replays or restarts cannot cause double-settlement.

WebSocket Events

PositionExpired

Sent when a position is settled:

{
"type": "PositionExpired",
"wallet_address": "0x...",
"symbol": "BTC-20250131-100000-C",
"position_size": 2.0,
"settlement_price": 5000.0,
"settlement_value": 10000.0,
"timestamp": 1738310400000
}
FieldDescription
position_sizeSigned position size (positive = long, negative = short)
settlement_priceIntrinsic value per contract
settlement_valueTotal cash settlement amount

MarketExpired

Sent when an instrument transitions to Expired Pending Price:

{
"type": "MarketUpdate",
"symbol": "BTC-20250131-100000-C",
"status": "MARKET_EXPIRED",
"timestamp": 1738310400000
}

API Endpoints

Get Instrument Status

GET /instruments/{symbol}

Returns the instrument's current status (ACTIVE, EXPIRED_PENDING_PRICE, or SETTLED).

Get Settlement History

GET /settlement/history?wallet=0x...

Returns settlement records for your account.

Response:

{
"success": true,
"data": [
{
"symbol": "BTC-20250131-100000-C",
"position_size": 2.0,
"settlement_price": 5000.0,
"settlement_value": 10000.0,
"settled_at": 1738310400000
}
]
}

Failure Handling

Oracle Unavailable

If the oracle cannot provide a settlement price at expiry:

  • Instrument remains in Expired Pending Price state
  • System retries every 30 seconds
  • Alert triggered if pending longer than 10 minutes

Trading is blocked immediately at expiry regardless of oracle availability.

Stale Price

If the oracle returns a price older than 5 minutes:

  • Settlement is delayed
  • System waits for fresh price
  • Alert triggered

System Restart

Settlement state is persisted to the database. If the system restarts:

  • Expired instruments are identified from DB on startup
  • Settlement continues automatically
  • Idempotency guarantees prevent double-settlement

Parameters

ParameterValueDescription
Expiry check interval60 secondsHow often system checks for expiries
TWAP window30 minutesSettlement price averaging window
Settlement retry interval30 secondsRetry frequency when price unavailable
Max price staleness5 minutesMaximum acceptable price age
Pending alert threshold10 minutesAlert if settlement delayed

Best Practices

  1. Monitor expiries: Track expiry dates for your positions via the portfolio endpoint
  2. Plan ahead: Close positions before expiry if you want to avoid settlement
  3. Check settlement prices: Verify the oracle price matches your expectations
  4. Subscribe to WebSocket: Receive real-time PositionExpired events for immediate notification
  5. Maintain margin buffer: Ensure sufficient margin for potential ITM short settlements

On-Chain Settlement

For testnet, settlement prices are posted on-chain after computation:

  • SimpleOracle.setExpiryPrice(symbol, price) is called after TWAP finalized
  • Exchange contract can verify settlement prices on-chain
  • No live oracle feeds on-chain, only final settlement prices

See also: