Skip to content

Funding Service

The Funding Service is a Go microservice that computes funding rates for perpetual contracts, calculates per-user funding payments, and coordinates settlement through the Wallet Service.

  • Funding Rate Computation: Calculate funding rates using Time-Weighted Average Price (TWAP) of the mark-index premium.
  • Payment Calculation: Compute per-user funding payments based on open positions.
  • Settlement Orchestration: Coordinate funding payment settlement through the Wallet Service.
  • Rate Broadcasting: Publish funding rate updates for downstream services and WebSocket clients.
  • History Maintenance: Persist all funding rate snapshots and payment records for audit.
  • Retry Management: Handle failed payments with automatic retry and dead-letter processing.
graph TB MDS[Market Data Service] -->|md.mark.v1, md.index.v1| Kafka[Kafka] MetaSvc[Metadata Service] -->|config.funding.updated.v1| Kafka Kafka --> Funding[Funding Service] Funding -->|gRPC ApplyFunding| Wallet[Wallet Service] Funding -->|gRPC GetAllPositions| Position[Position Service] Funding -->|Events| Kafka2[Kafka] Funding -->|Stores| PG[(PostgreSQL)] Kafka2 --> MDS2[Market Data Service] Kafka2 --> PosSvc[Position Service]
FieldTypeDescription
idUUID (PK)Snapshot ID
symbolVARCHAR(32)Perpetual symbol
funding_rateNUMERIC(18,10)Computed funding rate (e.g., 0.0001 = 0.01%)
mark_priceNUMERIC(24,12)Mark price at computation time
index_priceNUMERIC(24,12)Index price at computation time
premiumNUMERIC(24,12)Mark - Index
premium_rate_twapNUMERIC(18,10)TWAP of premium rate over interval
interest_rateNUMERIC(18,10)Fixed interest rate component
interval_hoursINTFunding interval (typically 8)
computed_atTIMESTAMPTZComputation timestamp
settlement_atTIMESTAMPTZWhen this rate will be settled
FieldTypeDescription
idUUID (PK)Payment ID
user_idUUIDAccount owner
symbolVARCHAR(32)Perpetual symbol
funding_cycle_idUUID (FK)References funding_rate_snapshots
position_sizeNUMERIC(24,12)User’s position at time of funding
position_sideENUM(long, short)Position direction
funding_rateNUMERIC(18,10)Applied funding rate
mark_priceNUMERIC(24,12)Mark price used
payment_amountNUMERIC(20,4)Payment amount (positive = received, negative = paid)
currencyVARCHAR(10)Payment currency
statusENUM(calculated, settling, settled, failed, retrying)Payment status
settled_atTIMESTAMPTZWhen payment was settled
retry_countINTNumber of settlement retries
error_messageTEXTLast error message (if failed)
created_atTIMESTAMPTZCalculation time
MethodEndpointDescription
POST/v1/funding/computeTrigger funding rate computation (admin/cron)
POST/v1/funding/settleTrigger funding settlement (admin/cron)
GET/v1/funding/rates?symbol={symbol}Get historical funding rates
GET/v1/funding/payments?user_id={id}Get user’s funding payment history
GET/v1/funding/current?symbol={symbol}Get current funding rate info
RPCDescriptionCalled By
GetCurrentRate(symbol)Get latest funding rateMarket Data Service
GetPaymentHistory(user_id, symbol)Get user’s funding paymentsPosition Service
TopicDescription
md.mark.v1Mark price updates (for TWAP computation)
md.index.v1Index price updates (for premium computation)
config.funding.updated.v1Funding configuration changes
TopicDescription
funding.rate.broadcast.v1New funding rate computed
funding.payment.created.v1Payment calculated for a user
funding.payment.settled.v1Payment successfully settled via Wallet
funding.payment.failed.v1Payment settlement failed
premium_rate = (mark_price - index_price) / index_price
interest_rate = 0.01% (configurable per symbol)
funding_rate = clamp(premium_rate_twap + interest_rate, -0.75%, +0.75%)
  • Premium rate sampled at regular intervals (e.g., every minute)
  • TWAP computed over the funding interval (e.g., 8 hours)
  • premium_rate_twap = sum(premium_rate_samples) / count(samples)
  • Maximum positive rate: +0.75% per interval
  • Maximum negative rate: -0.75% per interval
  • Prevents extreme funding rates during volatile periods
  • Default: 8 hours (3 settlements per day)
  • Configurable per symbol via Metadata Service
  • Settlement times: 00
    UTC, 08
    UTC, 16
    UTC
  1. Collect mark and index prices for the symbol over the interval
  2. Compute premium rate samples
  3. Calculate TWAP of premium rates
  4. Add interest rate component
  5. Clamp to allowed range
  6. Persist to funding_rate_snapshots
  7. Publish funding.rate.broadcast.v1
  1. At settlement time (e.g., 08
    UTC):
  2. Load the computed funding rate for the cycle
  3. Query Position Service for all open positions in the symbol
  4. For each position:
    payment = position_size * mark_price * funding_rate
    • Long positions with positive rate: Pay funding (negative payment)
    • Short positions with positive rate: Receive funding (positive payment)
    • Long positions with negative rate: Receive funding (positive payment)
    • Short positions with negative rate: Pay funding (negative payment)
  5. Create funding_payments rows (status = calculated)
  6. For each payment: call WalletService.ApplyFunding(user_id, amount, currency, funding_cycle_id)
  7. On success: update status to settled, emit funding.payment.settled.v1
  8. On failure: update status to failed, queue for retry
  • Polls for failed or retrying payments
  • Retries with exponential backoff (1s, 2s, 4s, 8s, 16s, 32s)
  • Max retry attempts: 10
  • After max retries: move to dead letter, alert ops
  • Idempotent: same funding_cycle_id + user_id won’t double-settle
PositionFunding RateActionPayment
LongPositive (+)Longs pay shortsNegative (pays)
ShortPositive (+)Shorts receivePositive (receives)
LongNegative (-)Longs receivePositive (receives)
ShortNegative (-)Shorts pay longsNegative (pays)

Net Zero: Total payments from longs exactly equals total payments to shorts (funding is a transfer, not a fee).

  • funding_rate_computed_total{symbol} — Rates computed
  • funding_payment_total{symbol,status} — Payments by status
  • funding_payment_amount_total{symbol,direction} — Total payment volume
  • funding_settlement_latency_ms{symbol} — Settlement processing time
  • funding_retry_total{symbol} — Payment retries
  • funding_rate_value{symbol} — Current funding rate gauge

Spans: funding.compute_rate, funding.calculate_payments, funding.settle_payment, funding.retry_payment

Structured JSON via zap: symbol, funding_rate, user_id, position_size, payment_amount, trace_id.

MetricTarget
Rate computation latency< 5 seconds
Settlement latency (all payments)< 30 seconds
Payment accuracy100% (net-zero verified)
Settlement success rate>= 99.9% (with retries)
Rate freshness for WebSocket< 2 seconds
VariableDescriptionDefault
POSTGRES_URLPostgreSQL connection stringRequired
KAFKA_BROKERSKafka broker addressesRequired
WALLET_SERVICE_GRPC_URLWallet Service gRPC endpointRequired
POSITION_SERVICE_GRPC_URLPosition Service gRPC endpointRequired
FUNDING_INTERVAL_HOURSHours between settlements8
MAX_FUNDING_RATEMaximum funding rate cap0.0075
MIN_FUNDING_RATEMinimum funding rate floor-0.0075
RETRY_MAX_ATTEMPTSMax payment retry attempts10
  • Language: Go 1.21+
  • Database: PostgreSQL with SQLC code generation
  • Migrations: Atlas
  • Kafka: confluent-kafka-go with Avro
  • gRPC: google.golang.org/grpc
  • Metrics: Prometheus client_golang
  • Logging: zap structured logging