Formulas & Calculations
Funding History Search uses a set of formulas to normalize rates, calculate APR, and compute PnL. This page describes the math behind the interface.
Rate Normalization
Exchanges publish funding rates at different intervals:
- 8 hours — most centralized exchanges (Binance, OKX, Bybit, etc.)
- 1 hour — Drift (decentralized exchange)
To compare rates on a common basis, all values are normalized to hourly BPS (basis points per hour):
hourlyBps = rate / intervalHoursExample:
- Binance: rate = 0.03% per 8h → hourlyBps = 0.03 / 8 = 0.00375
- Drift: rate = 0.005% per 1h → hourlyBps = 0.005 / 1 = 0.005
APR (Annual Percentage Rate)
APR is derived from the hourly rate:
APR = hourlyBps × 87.6Where the constant 87.6 comes from:
hourly_rate / 10000 × 24 × 365 × 100 = hourlyBps × 87.6Example:
- hourlyBps = 0.00375 → APR = 0.00375 × 87.6 = 0.3285%
BPS (Basis Points)
1 BPS = 0.01%. A rate of 0.03% equals 3 BPS. Basis points are used as the internal unit for precise calculations before converting to percentage for display.
Spread
The spread is the difference between the maximum and minimum funding rates across the selected exchanges:
spread = max_rate − min_rateThe spread represents the potential profit from an arbitrage position (long on the exchange with the minimum rate + short on the exchange with the maximum rate).
Example:
- Binance funding: +0.43% → best short exchange
- Hyperliquid funding: −0.02% → best long exchange
- Spread = 0.43 − (−0.02) = 0.45%
Stability
Stability measures how volatile the funding rate is over the analysis period:
stability = max(stdDev(longExchangeRates), stdDev(shortExchangeRates))Where stdDev is the standard deviation of APR values across the time series. Lower stability means calmer, more predictable funding rates.
Smart Score
Smart Score is a Sharpe-like composite metric:
smartScore = spread / stabilityIt evaluates how suitable a ticker is for funding arbitrage by balancing:
- Spread magnitude — higher is better (more profit potential)
- Stability — lower is better (more predictable rates)
Tickers with a high Smart Score have strong spreads and low volatility — the ideal combination for long-term arbitrage positions.
PnL Calculation
Portfolio position PnL is computed using Riemann sum integration over historical rates:
Step-by-Step
Fetch data: Get the historical funding rate series for both the long and short exchange from the entry date to now.
For each data point in the series:
hourlyBps = point.y / intervalHours durationHours = (nextPointTime − currentPointTime) / 3,600,000 ms weightedBps += hourlyBps × durationHoursConvert to percentage:
totalFundingPercent = totalWeightedBps / 100Calculate PnL:
rawPnL = investment × (shortFundingPercent − longFundingPercent) / 100 netPnL = rawPnL − openingCost
Variables
| Variable | Description |
|---|---|
investment | Position size in USD (per leg) |
shortFundingPercent | Accumulated funding percentage on the short exchange |
longFundingPercent | Accumulated funding percentage on the long exchange |
openingCost | Costs incurred when opening (fees + slippage on both exchanges) |
Why Integration Instead of an Average?
Funding rates change every 1 to 8 hours. Simply multiplying the average rate by time produces an inaccurate result. Integrating over each individual interval accounts for the actual rate dynamics and yields a precise PnL figure that matches what you would actually earn on the exchanges.
Price Fetching
Token prices used in the portfolio are fetched using a multi-source strategy:
- Exchange APIs (tried in parallel): Binance, Bybit, OKX, Gate.io, Bitget, KuCoin, Hyperliquid
- If multiple exchanges respond: average the prices
- If all exchange APIs fail: CoinGecko fallback (search → price lookup)
- Prices are cached in localStorage (
portfolio_prices) to avoid redundant requests