Funding Rate Specification

Funding Rate Specification

Overview

Kyan implements a continuous funding mechanism so perpetual contract prices converge to their underlying index prices. The premium is sampled every minute and funding is settled at every UTC hour boundary.

Funding Rate Calculation

Premium Index

Each sample measures the difference between the perpetual and index price:

Premium (p) = (Perpetual Price - Index Price) / Index Price
  • Perpetual Price: orderbook midpoint (with fallbacks — see below)
  • Index Price: spot price from the index feed

Funding Pipeline

The premium is averaged over the hour, then transformed into the per-hour funding rate through four steps:

1. Average   p_avg = seconds-weighted running average of p over the current hour
2. Compress  r = p_avg / PREMIUM_COMPRESSION_RATIO
3. Dampen    |r| <= DAMPENER_THRESHOLD  -> r = 0          (dead zone)
             r  >  DAMPENER_THRESHOLD  -> r = r - DAMPENER_THRESHOLD
             r  < -DAMPENER_THRESHOLD  -> r = r + DAMPENER_THRESHOLD
4. Cap       r = clamp(r, -MAX_FUNDING_RATE, +MAX_FUNDING_RATE)
5. Normalize rate_hourly = r / FUNDING_PERIOD_HOURS

Default configuration:

ParameterEnv varDefaultMeaning
Compression ratioPREMIUM_COMPRESSION_RATIO1 (≥1)Divides the premium; 1 = no compression
Dampener thresholdDAMPENER_THRESHOLD0.0005 (0.05%)Dead zone; premiums inside it produce zero funding
Max funding rateMAX_FUNDING_RATE0.005 (0.5%)Cap applied before normalization
Funding periodFUNDING_PERIOD_HOURS8Normalization divisor
Sampling intervalFUNDING_INTERVAL1 (minute)Premium sampling cadence

Because the cap is applied before dividing by the funding period, the effective per-hour cap is ±0.0625% (0.5% ÷ 8). The stored rate is the per-hour rate; the annualized rate is rate_hourly × 8760.

Price Discovery and Fallback Logic

Perpetual Price

The perpetual price is derived from the live orderbook, falling back to the index price whenever the book is unusable. All prices must be positive, finite numbers.

Primary: Orderbook Midpoint

  • Best bid and best ask are read from the perp orderbook.
  • Spread guard: if (ask - bid) / index > MAX_SPREAD_PERCENTAGE (default 0.01, 1%), fall back to the index price.
  • Otherwise perp price = (bid + ask) / 2.

Single-Sided Book

  • Bid only: use the bid if it is above the index price, otherwise use the index price.
  • Ask only: use the ask if it is below the index price, otherwise use the index price.

No Valid Orders

  • Fall back to the index price (logged at warn level).

Index Price

  • Sourced from the index price feed, keyed per base asset.
  • Must be a positive, finite number; an invalid index price is a hard error for that sample.

Settlement Mechanism

Funding Windows

  • Settlement cadence: every UTC hour boundary (00:00, 01:00, …, 23:00).
  • Rate: the hour's seconds-weighted average premium run through the funding pipeline above.

Payment Calculation

At each hour boundary every open perpetual position is settled:

Funding Payment = Position Size × rate_hourly

The payment adjusts the margin account's accrued_funding. The final rate for the hour is also stored as the "previous" rate, and the "current" accumulator resets to 0 for the next hour.

Settlement Triggers

  1. Scheduled: detected automatically when the current hour exceeds the last processed hour during minute processing.
  2. Manual: POST /settle_funding_interval with an explicit settlement payload.

Payment Direction

  • Positive funding rate (perpetual > index): long positions pay short positions.
  • Negative funding rate (perpetual < index): short positions pay long positions.

Mechanically, the payment is size × rate and is decremented from the payer's accrued_funding; the sign of size (long positive, short negative) and of rate together produce the correct direction.

Reliability & Edge Cases

  • Idempotent minute processing: each minute is processed at most once (dedupe guard); failed runs clear the guard so retries are not blocked.
  • Initialization: on first run (or reset) the current and previous funding rates are set to 0 and the last-processed hour is set to the current hour boundary (timestamp - timestamp % 3600).
  • Stale-data reset: if the last processed hour is more than 2 hours (7200s) old, funding state is reinitialized to 0.
  • Stored-rate guard: a stored hourly rate that is non-finite or has magnitude > 100% is rejected as invalid.
  • Graceful degradation: any orderbook problem (wide spread, single side, missing/invalid orders) falls back to the index price; only an invalid index price is fatal for the sample.

API Integration

These endpoints are internal and triggered by Cloud Scheduler / operators (not part of the public trading API):

EndpointBodySuccessPurpose
POST /compute_minutely_fundingempty202Sample the premium for all instruments; run hour-boundary settlement when the hour rolls over
POST /settle_funding_intervalsettlement request (instrument, final_rate, timestamp, previous_hour, type)200Force settlement for one instrument
GET /v1/funding/health200/503Health probe
GET /v1/funding/metrics200Prometheus metrics
GET /v1/funding/dashboard200Service dashboard summary

Supported Instruments

Configurable via INSTRUMENTS; defaults:

  • BTC_USDC-PERPETUAL
  • ETH_USDC-PERPETUAL

Data Storage

  • Redis: current and previous funding rates plus processing state (last processed hour, dedupe guard), keyed per base asset.
  • PostgreSQL: perpetual positions and each margin account's accrued_funding.
  • BigQuery: historical funding-rate samples and account-ledger settlement events.