◈   ⌘ api · Intermediate

Bybit Funding Rate History Endpoint: A Trader's Guide

Learn to use Bybit's funding rate history API endpoint to retrieve perpetual contract data, parse responses with Python, and build smarter trading strategies.

Uncle Solieditor · voc · 18.05.2026 ·views 1
◈   Contents
  1. → What Funding Rates Actually Tell You About the Market
  2. → The Bybit V5 Funding Rate History Endpoint Explained
  3. → Fetching Funding History with Python
  4. → Parsing and Analyzing Funding Data with Pandas
  5. → Adding Authentication for Private Account Endpoints
  6. → Practical Ways Traders Use Funding Rate History
  7. → Frequently Asked Questions

Funding rates are the heartbeat of perpetual futures markets. Every 8 hours on Bybit — and at comparable intervals on Binance and OKX — long traders pay short traders (or vice versa), creating a timestamped record of market bias. The Bybit funding rate history endpoint gives you programmatic access to that entire record: who was paying, how much, and when. Whether you are backtesting a cash-and-carry strategy, building a sentiment indicator, or hunting for crowded-position reversals, this data is one of the most underused edges available to systematic traders.

What Funding Rates Actually Tell You About the Market

Perpetual futures contracts replicate the economics of a leveraged spot position without an expiry date. To keep the contract price from drifting too far from spot, exchanges use a funding mechanism: when the perpetual trades above the spot index, longs pay shorts. When it trades below, shorts pay longs. The size of each payment is the funding rate — a small percentage of the notional position, settled periodically.

Bybit calculates the rate from two components: a fixed interest rate (usually 0.01% per day) and a premium index that reflects the gap between the perpetual mid-price and the spot index. Most USDT-margined pairs settle every 8 hours at 00:00, 08:00, and 16:00 UTC, though some high-activity tokens settle every 4 or even 1 hour. OKX and Binance use similar mechanics — compare funding histories across exchanges and you will often find the same sentiment extremes playing out with slightly different timing.

The history matters because trends in funding are more meaningful than any single data point. When BTCUSDT funding on Bybit sustained rates above 0.05% per 8-hour period — equivalent to roughly 55% annualized — for several consecutive days, those periods reliably preceded sharp long liquidation cascades. Platforms like VoiceOfChain aggregate and surface these signals in real time, but pulling the raw data yourself lets you define custom thresholds and backtest exactly where the edge is.

The Bybit V5 Funding Rate History Endpoint Explained

Bybit's V5 API is the current standard — the older V3 and V2 endpoints are deprecated. The funding rate history endpoint is completely public, meaning no API key is required to access it. Authentication only becomes necessary if you want account-level data like your own personal funding settlement history.

The base endpoint is: GET https://api.bybit.com/v5/market/funding/history

Funding Rate History Endpoint Parameters
ParameterRequiredTypeDescription
categoryYesstringAlways 'linear' for USDT perpetuals
symbolYesstringe.g. 'BTCUSDT', 'ETHUSDT', 'SOLUSDT'
startTimeNointegerStart of range, Unix milliseconds
endTimeNointegerEnd of range, Unix milliseconds
limitNointegerRecords per page, 1–200 (default 200)

Results come back newest-first. Each record contains three fields: symbol, fundingRate (a decimal string — '0.0001' means 0.01%), and fundingRateTimestamp (Unix milliseconds). When you need more than 200 records, paginate using the nextPageCursor value from the response result object.

A fundingRate of 0.0001 means positions pay 0.01% every 8 hours. At 3 settlements per day, that annualizes to roughly 10.95%. During bull market extremes this can spike above 0.1% per period — over 100% annualized. Those spikes are where the interesting signals live.

Fetching Funding History with Python

The simplest starting point is a single request for the most recent records. The requests library handles everything cleanly — pass category and symbol, check the retCode in the response body, and return the list.

import requests

BASE_URL = 'https://api.bybit.com'

def get_funding_history(symbol, limit=200):
    endpoint = '/v5/market/funding/history'
    params = {
        'category': 'linear',
        'symbol': symbol,
        'limit': limit
    }
    response = requests.get(BASE_URL + endpoint, params=params, timeout=10)
    response.raise_for_status()
    data = response.json()
    if data['retCode'] != 0:
        raise ValueError('API error: ' + data['retMsg'])
    return data['result']['list']

# Fetch last 200 funding events for BTCUSDT
records = get_funding_history('BTCUSDT')
print('Fetched', len(records), 'records')
for r in records[:3]:
    print(r['fundingRateTimestamp'], r['fundingRate'])

To cover longer time windows — say, 90 days of historical data — you need to paginate. Bybit returns a nextPageCursor token in the response; pass it on the next request to continue retrieving records without overlap or gaps.

import requests
import time

BASE_URL = 'https://api.bybit.com'

def get_full_funding_history(symbol, start_ms, end_ms):
    endpoint = '/v5/market/funding/history'
    all_records = []
    cursor = None

    while True:
        params = {
            'category': 'linear',
            'symbol': symbol,
            'startTime': start_ms,
            'endTime': end_ms,
            'limit': 200,
        }
        if cursor:
            params['cursor'] = cursor

        resp = requests.get(BASE_URL + endpoint, params=params, timeout=10)
        resp.raise_for_status()
        body = resp.json()

        if body['retCode'] != 0:
            raise ValueError('API error: ' + body['retMsg'])

        result = body['result']
        batch = result.get('list', [])
        all_records.extend(batch)

        cursor = result.get('nextPageCursor', '')
        if not cursor or not batch:
            break

        time.sleep(0.05)  # stay within rate limits

    return all_records

# Fetch 90 days of BTCUSDT funding history
now_ms = int(time.time() * 1000)
start_ms = now_ms - (90 * 24 * 60 * 60 * 1000)
records = get_full_funding_history('BTCUSDT', start_ms, now_ms)
print('Total records retrieved:', len(records))

Parsing and Analyzing Funding Data with Pandas

Raw API records arrive as strings — fundingRate comes back as '0.0001', not a float. Converting to a proper DataFrame unlocks rolling averages, percentile analysis, and clean export to CSV or a time-series database.

import pandas as pd

def build_funding_df(records):
    df = pd.DataFrame(records)
    df['fundingRate'] = pd.to_numeric(df['fundingRate'])
    df['timestamp'] = pd.to_datetime(
        pd.to_numeric(df['fundingRateTimestamp']), unit='ms', utc=True
    )
    df = df.sort_values('timestamp').reset_index(drop=True)

    # Annualized rate: 3 settlements per day x 365 days
    df['annual_pct'] = df['fundingRate'] * 3 * 365 * 100

    # 7-day rolling mean (21 periods at 8-hour settlement intervals)
    df['rolling_7d'] = df['fundingRate'].rolling(21, min_periods=1).mean()

    # Flag extreme funding: >0.05% per period is roughly 55% annualized
    df['is_extreme'] = df['fundingRate'].abs() > 0.0005

    return df

df = build_funding_df(records)
print(df[['timestamp', 'fundingRate', 'annual_pct', 'is_extreme']].tail(10))

print('Summary stats:')
print('  Mean rate :', round(df['fundingRate'].mean(), 6))
print('  Max rate  :', round(df['fundingRate'].max(), 6))
print('  Min rate  :', round(df['fundingRate'].min(), 6))
print('  Extreme periods:', df['is_extreme'].sum())

# Export for further analysis or database ingestion
df.to_csv('btcusdt_funding_history.csv', index=False)

Adding Authentication for Private Account Endpoints

The market funding history endpoint is public, but if you want to retrieve your own funding settlements — what Bybit actually charged or credited your account at each interval — you need a signed request. Bybit V5 uses HMAC-SHA256 with a specific payload construction. Generate API keys in the Bybit dashboard under Account → API Management, and restrict them to read-only scope for safety.

import hashlib
import hmac
import os
import time
import requests

API_KEY = os.environ.get('BYBIT_API_KEY', '')
API_SECRET = os.environ.get('BYBIT_API_SECRET', '')
BASE_URL = 'https://api.bybit.com'

def signed_get(endpoint, params):
    timestamp = str(int(time.time() * 1000))
    recv_window = '5000'

    # Build deterministic query string for signature
    query = '&'.join(k + '=' + str(v) for k, v in sorted(params.items()))
    sign_payload = timestamp + API_KEY + recv_window + query

    signature = hmac.new(
        API_SECRET.encode('utf-8'),
        sign_payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    headers = {
        'X-BAPI-API-KEY': API_KEY,
        'X-BAPI-TIMESTAMP': timestamp,
        'X-BAPI-SIGN': signature,
        'X-BAPI-RECV-WINDOW': recv_window,
    }

    resp = requests.get(
        BASE_URL + endpoint, params=params, headers=headers, timeout=10
    )
    resp.raise_for_status()
    data = resp.json()
    if data['retCode'] != 0:
        raise ValueError('Signed API error: ' + data['retMsg'])
    return data

# Retrieve personal funding settlement history
result = signed_get('/v5/account/transaction-log', {
    'accountType': 'UNIFIED',
    'type': 'SETTLEMENT',
    'limit': 50
})
for entry in result['result']['list']:
    print(entry['symbol'], entry['funding'], entry['transactionTime'])
Never hardcode API credentials in source files. Load them from environment variables or a secrets manager. For read-only data access, create a key with no withdrawal or trading permissions — it reduces blast radius if the key is ever leaked.

Practical Ways Traders Use Funding Rate History

Raw funding data only becomes useful when you attach a specific thesis to it. These are the most common applications among systematic traders who work with this data set regularly.

The most durable applications combine funding history with complementary data — open interest, liquidation heatmaps, or spot-to-perp basis. VoiceOfChain does exactly this, pulling funding metrics alongside order flow data to generate composite signals that funding rate analysis alone cannot produce. Pull the raw endpoint yourself and you have full control over the signal construction and threshold calibration.

Frequently Asked Questions

Does querying the Bybit funding rate history endpoint require an API key?
No. The /v5/market/funding/history endpoint is fully public — you can call it without any credentials. Authentication is only required for private endpoints that return account-specific data, such as your personal funding settlement history via /v5/account/transaction-log.
How far back does Bybit's funding rate history actually go?
For major pairs like BTCUSDT and ETHUSDT, Bybit retains data going back several years. For newer or lower-volume assets, history extends only to the launch date of the perpetual contract. Paginate to the end of the response and check the earliest timestamp to determine the actual available range for any given symbol.
What is the rate limit for the funding history endpoint?
Bybit's V5 public market data endpoints generally allow up to 120 requests per minute without authentication. A 50ms sleep between paginated calls is conservative but keeps you well clear of throttling. If you hit a rate limit, Bybit returns retCode 10006 — add exponential backoff to your error handling.
How do I compare Bybit funding rates with Binance or OKX?
Each exchange has its own endpoint: Binance uses GET /fapi/v1/fundingRate, OKX uses GET /api/v5/public/funding-rate-history. All three return symbol, fundingRate, and timestamp in similar formats. Build a unified DataFrame with an exchange column, normalize timestamps to UTC, and align to the nearest common settlement interval for a clean comparison.
What does a negative funding rate on Bybit mean for traders?
A negative funding rate means the perpetual is trading below the spot index — short traders are paying longs. This typically signals bearish positioning or forced short crowding. Sustained negative funding often appears during extended downtrends and can be an early indicator that selling pressure is becoming exhausted.
Can I retrieve funding rate history for inverse (coin-margined) contracts on Bybit?
Yes. Change the category parameter from 'linear' to 'inverse' and use the coin-margined symbol format, such as 'BTCUSD' instead of 'BTCUSDT'. Inverse contracts are settled in the base cryptocurrency and often exhibit different funding dynamics than their linear counterparts during sharp price moves.

The Bybit funding rate history endpoint is a clean, well-documented API that unlocks a surprisingly deep layer of market intelligence. Start with a basic fetch, add pagination for extended time windows, and run the data through Pandas to calibrate your own signal thresholds. The edge comes from what you build on top — whether that is a cash-and-carry arb engine, a regime filter layered over your existing strategy, or a real-time alert dashboard. Tools like VoiceOfChain handle the aggregation layer; pull the raw data yourself and you retain full control over the analysis.

◈   more on this topic
◉ basics Mastering the ccxt library documentation for crypto traders ⌂ exchanges Mastering the Binance CCXT Library for Crypto Traders ⌬ bots Best Crypto Trading Bots 2025: Profitable AI-Powered Strategies