◈   ⌘ api · Intermediate

Binance Funding Rate History API: Complete Guide

Learn how to access Binance historical funding rates via API with Python examples, endpoint details, and practical strategies for algorithmic traders.

Uncle Solieditor · voc · 19.05.2026 ·views 6
◈   Contents
  1. → What Funding Rates Actually Tell You
  2. → Binance API Funding Rate Endpoints
  3. → Setting Up the Binance API Client in Python
  4. → Paginating for Full Historical Data
  5. → Practical Analysis: Building a Funding Rate Signal
  6. → Rate Limits and Production Considerations
  7. → Frequently Asked Questions
  8. → Putting It All Together

Funding rates are one of the most underutilized signals in crypto trading. Every 8 hours on Binance, longs pay shorts (or vice versa), and that flow of money tells you exactly how crowded a trade is. If you can pull Binance historical funding rates via API and analyze them systematically, you gain an edge that most retail traders completely ignore.

This guide walks through everything you need: the actual endpoints, authentication, parsing responses, and building a simple backtesting-ready dataset from Binance funding rate history API data. Whether you're building a bot or just want to understand the market structure better, this is the foundation.

What Funding Rates Actually Tell You

Perpetual futures don't expire like quarterly contracts, so exchanges use a funding mechanism to keep the perpetual price anchored to the spot price. When funding is positive, longs pay shorts — meaning the market is net long and slightly overheated. When it's negative, shorts pay longs, signaling bearish overcrowding.

Binance settles funding every 8 hours: at 00:00, 08:00, and 16:00 UTC. The rate itself is calculated based on the interest rate component (fixed) plus the premium index (variable). On most days BTCUSDT funding sits between +0.01% and +0.03%. When it spikes above 0.1% or goes deeply negative, that's a signal worth paying attention to.

Funding rate alone isn't a trade signal — it's context. Combine it with open interest trends and price action. Platforms like VoiceOfChain aggregate funding rates alongside real-time order flow signals so you see the full picture without building everything from scratch.

Binance API Funding Rate Endpoints

Binance exposes funding rate data through the FAPI (Futures API) endpoints. There are two main ones you'll use: one for the current funding rate and one for historical records. The historical endpoint is what matters for backtesting and trend analysis.

Binance Funding Rate API Endpoints
EndpointDescriptionAuth Required
/fapi/v1/fundingRateHistorical funding rates (up to 1000 records)No
/fapi/v1/premiumIndexCurrent funding rate + mark priceNo
/fapi/v1/fundingInfoFunding settlement intervals per symbolNo
/fapi/v1/incomeYour actual funding payments received/paidYes (API key)

The historical endpoint returns up to 1000 records per request. Since Binance settles 3 times per day, 1000 records covers roughly 333 days for a single symbol. For longer histories or bulk data across many symbols, you'll need to paginate using the startTime and endTime parameters.

Setting Up the Binance API Client in Python

For public endpoints like funding rate history, you don't need API keys — just make a GET request. For pulling your own funding payments or placing trades based on the signal, you'll need a read-only API key from Binance. Here's the minimal setup:

import requests
import pandas as pd
from datetime import datetime, timezone

BASE_URL = "https://fapi.binance.com"

def get_funding_rate_history(
    symbol: str,
    start_time: int = None,
    end_time: int = None,
    limit: int = 1000
) -> pd.DataFrame:
    """
    Fetch historical funding rates from Binance API.
    No API key required for public data.
    
    Args:
        symbol: e.g. 'BTCUSDT', 'ETHUSDT'
        start_time: Unix timestamp in milliseconds
        end_time: Unix timestamp in milliseconds
        limit: Max records per request (max 1000)
    """
    endpoint = f"{BASE_URL}/fapi/v1/fundingRate"
    
    params = {
        "symbol": symbol,
        "limit": limit
    }
    
    if start_time:
        params["startTime"] = start_time
    if end_time:
        params["endTime"] = end_time
    
    try:
        response = requests.get(endpoint, params=params, timeout=10)
        response.raise_for_status()
        data = response.json()
    except requests.exceptions.Timeout:
        print(f"Request timed out for {symbol}")
        return pd.DataFrame()
    except requests.exceptions.HTTPError as e:
        print(f"HTTP error: {e} — Status: {response.status_code}")
        return pd.DataFrame()
    except ValueError:
        print("Failed to parse JSON response")
        return pd.DataFrame()
    
    if not data:
        return pd.DataFrame()
    
    df = pd.DataFrame(data)
    df["fundingTime"] = pd.to_datetime(df["fundingTime"], unit="ms", utc=True)
    df["fundingRate"] = df["fundingRate"].astype(float)
    df = df.set_index("fundingTime").sort_index()
    
    return df

# Example usage
df = get_funding_rate_history("BTCUSDT", limit=500)
print(df.tail(10))
print(f"\nCurrent funding rate: {df['fundingRate'].iloc[-1]:.4%}")
print(f"7-day average: {df['fundingRate'].tail(21).mean():.4%}")

Paginating for Full Historical Data

The 1000-record limit means you need pagination for multi-year datasets. The pattern is simple: fetch a batch, take the last timestamp, use it as the next startTime. Keep going until you get fewer records than the limit or hit your target end date.

import time

def get_full_funding_history(
    symbol: str,
    start_date: str,
    end_date: str = None
) -> pd.DataFrame:
    """
    Pull complete Binance historical funding rates for a symbol.
    Handles pagination automatically.
    
    Args:
        symbol: Trading pair e.g. 'ETHUSDT'
        start_date: ISO format string e.g. '2023-01-01'
        end_date: ISO format string, defaults to now
    """
    start_ts = int(
        datetime.fromisoformat(start_date)
        .replace(tzinfo=timezone.utc)
        .timestamp() * 1000
    )
    
    if end_date:
        end_ts = int(
            datetime.fromisoformat(end_date)
            .replace(tzinfo=timezone.utc)
            .timestamp() * 1000
        )
    else:
        end_ts = int(datetime.now(timezone.utc).timestamp() * 1000)
    
    all_records = []
    current_start = start_ts
    
    print(f"Fetching {symbol} funding history from {start_date}...")
    
    while current_start < end_ts:
        endpoint = f"{BASE_URL}/fapi/v1/fundingRate"
        params = {
            "symbol": symbol,
            "startTime": current_start,
            "endTime": end_ts,
            "limit": 1000
        }
        
        try:
            resp = requests.get(endpoint, params=params, timeout=15)
            resp.raise_for_status()
            batch = resp.json()
        except Exception as e:
            print(f"Error fetching batch: {e}")
            break
        
        if not batch:
            break
        
        all_records.extend(batch)
        
        # Move start to just after last record
        last_ts = batch[-1]["fundingTime"]
        current_start = last_ts + 1
        
        print(f"  Fetched {len(all_records)} records so far...")
        
        # Stop if we got a partial batch (end of data)
        if len(batch) < 1000:
            break
        
        # Respect rate limits — Binance allows 2400 requests/min on FAPI
        time.sleep(0.1)
    
    if not all_records:
        return pd.DataFrame()
    
    df = pd.DataFrame(all_records)
    df["fundingTime"] = pd.to_datetime(df["fundingTime"], unit="ms", utc=True)
    df["fundingRate"] = df["fundingRate"].astype(float)
    df = df.drop_duplicates(subset="fundingTime").set_index("fundingTime").sort_index()
    
    print(f"Done. {len(df)} total records fetched.")
    return df

# Pull 2 years of BTC funding data
btc_funding = get_full_funding_history("BTCUSDT", "2023-01-01", "2025-01-01")
print(btc_funding.describe())

For comparison, Bybit and OKX expose similar historical funding endpoints. Bybit uses /v5/market/funding/history and OKX uses /api/v5/public/funding-rate-history. If you're building a multi-exchange funding monitor, the data structures are slightly different but the concept is identical. Platforms like Bitget and Gate.io also publish full funding rate histories, useful for altcoin analysis where Binance might have less liquidity.

Practical Analysis: Building a Funding Rate Signal

Raw funding rate numbers are noise. What matters is the trend and the extremes. A 7-day rolling average smooths out settlement artifacts. A z-score tells you how extreme the current rate is relative to history. Here's a simple signal framework:

import numpy as np

def analyze_funding_signal(df: pd.DataFrame, lookback_days: int = 30) -> pd.DataFrame:
    """
    Build a funding rate signal from Binance historical funding rates API data.
    Uses rolling statistics to identify crowded market conditions.
    """
    result = df.copy()
    
    # Number of 8h periods in lookback
    periods = lookback_days * 3
    
    # Rolling statistics
    result["rolling_mean"] = result["fundingRate"].rolling(periods).mean()
    result["rolling_std"] = result["fundingRate"].rolling(periods).std()
    
    # Z-score: how extreme is today's rate vs recent history?
    result["z_score"] = (
        (result["fundingRate"] - result["rolling_mean"]) 
        / result["rolling_std"]
    )
    
    # Annualized funding cost (3 payments/day * 365 days)
    result["annualized_rate"] = result["fundingRate"] * 3 * 365
    
    # Signal classification
    conditions = [
        result["z_score"] > 2.0,    # Extremely bullish/overheated
        result["z_score"] > 1.0,    # Bullish lean
        result["z_score"] < -2.0,   # Extremely bearish/oversold
        result["z_score"] < -1.0,   # Bearish lean
    ]
    choices = ["extreme_long", "mild_long", "extreme_short", "mild_short"]
    result["signal"] = np.select(conditions, choices, default="neutral")
    
    return result

# Apply to BTC data
btc_analyzed = analyze_funding_signal(btc_funding, lookback_days=30)

# Show extreme events
extreme_events = btc_analyzed[btc_analyzed["signal"].isin(["extreme_long", "extreme_short"])]
print(f"Extreme funding events: {len(extreme_events)}")
print(extreme_events[["fundingRate", "z_score", "signal", "annualized_rate"]].tail(10))

# Summary stats
print("\nSignal distribution:")
print(btc_analyzed["signal"].value_counts(normalize=True).mul(100).round(1))
Annualized funding rates above 100% are a red flag for longs. At that level, you're paying over 100% per year just to hold the position — the asset needs to move significantly in your favor just to break even on funding costs alone.

VoiceOfChain monitors funding rates across perpetual markets in real time and surfaces these extreme conditions as actionable signals — so if you don't want to maintain your own pipeline, that's a ready-made alternative for spotting funding-driven setups.

Rate Limits and Production Considerations

Binance FAPI has generous rate limits for public endpoints — 2400 requests per minute with a weight system. The funding rate history endpoint costs 1 weight per request. In practice, if you're fetching data for 50 symbols at startup, you'll be fine with a 100ms sleep between calls.

For production systems, store the fetched data in a local SQLite or PostgreSQL database. Fetch only the delta (new records since your last fetch) rather than pulling full history every run. A simple table with columns (symbol, funding_time, funding_rate) with a composite primary key handles this cleanly.

Frequently Asked Questions

Do I need an API key to access Binance funding rate history?
No. The /fapi/v1/fundingRate endpoint is fully public — no API key or authentication required. You only need credentials if you want to see your own funding payment history via the /fapi/v1/income endpoint.
How far back does Binance historical funding rates API go?
Binance perpetual futures launched in late 2019, and the API returns data from inception for most major pairs. For BTCUSDT you can pull data back to September 2019. Altcoin pairs start from their individual listing dates.
What's the maximum number of records I can fetch per request?
The limit parameter maxes out at 1000 records per request. Since Binance settles funding 3 times per day, 1000 records covers about 333 days. Use startTime and endTime with pagination for longer histories.
How does Binance funding rate compare to Bybit or OKX?
All three use 8-hour settlement cycles with similar calculation methodologies. Bybit and OKX generally show very similar rates to Binance for major pairs since arbitrageurs keep them aligned. Divergences between exchanges can sometimes signal temporary dislocations worth trading.
Can I use funding rate history for backtesting a delta-neutral strategy?
Yes, and it's one of the best use cases for this data. A delta-neutral strategy goes long spot and short perpetual (or vice versa) to collect funding without directional exposure. Historical data lets you model expected returns, drawdown from rates swinging negative, and optimal entry/exit thresholds.
Why does the funding rate sometimes spike sharply and then revert quickly?
Sudden spikes usually happen during volatile price moves when the perpetual premium blows out briefly before arbitrageurs close the gap. They're often noise rather than signal. Look at multi-day sustained elevated rates rather than single-settlement spikes for meaningful crowding signals.

Putting It All Together

The Binance API funding rate data is genuinely one of the cleanest free datasets in crypto. It's timestamped, reliable, goes back years, and requires zero authentication to access. Most traders glance at the current rate and move on — building a systematic historical analysis gives you the context to know whether today's 0.05% is actually extreme or just normal.

The code in this guide is production-ready as a starting point. Add your symbol list, point it at a database, schedule it to run every 8 hours after settlement, and you have a funding rate data pipeline running in under an hour. From there, the signal logic is yours to build. Whether you're running a funding arbitrage strategy, using it as a sentiment filter for directional trades, or just want better market context — the Binance historical funding rates API gives you the raw material to do it properly.

◈   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