Skip to content

Trading

Funding Rates, Basis, and Perp Mechanics: What Every Trading Infra Engineer Needs to Know

How perpetual futures actually work under the hood - funding calculations, mark price, basis trading, and the infrastructure implications for any system that holds positions overnight.

11 min
#perpetual-futures #funding-rates #binance #basis-trading #crypto-derivatives #market-structure

I trade Binance BTCUSDT perps every day. Not academically - with real infrastructure that tracks positions, manages funding accrual, and makes execution decisions based on where basis is trading. Before I built ZeroCopy’s trading infrastructure, I learned the hard way that most resources on perpetual futures explain the mechanism but skip the engineering consequences. This post is the one I wish I had before I wrote my first position management system.

What a Perpetual Future Actually Is

A perpetual future (perp) is a derivative contract that tracks the price of an underlying asset but never expires. You can hold a BTCUSDT perpetual position indefinitely - there’s no settlement date, no rolling from front month to back month, no delivery. This makes perps dramatically simpler operationally than dated futures.

The mechanism that keeps the perp price tethered to spot is the funding rate. Every 8 hours on Binance, a cash payment transfers between longs and shorts based on how far the perp price has deviated from the underlying spot price. If longs have been paying, it means the perp was trading above spot (bullish market sentiment causing upward price pressure on perps). If shorts have been paying, the perp was below spot.

This is the core insight: funding is a correction mechanism, not a fee. It’s the market’s way of repeatedly reconciling the derivative back to the underlying.

The Funding Rate Formula

Binance calculates funding every 8 hours using this formula:

Funding Rate = max(-0.05%, min(0.05%, Interest Rate + Premium))

Where:

  • Interest Rate is a fixed 0.01% per 8-hour period (approximately 0.03% daily, set by Binance)
  • Premium = (Perp Mid Price - Mark Price) / Mark Price × (8 / Funding Interval Hours)
  • The cap of ±0.05% per period prevents extreme funding events from immediately liquidating carry traders

In practice, the interest rate component is nearly negligible - it’s the premium that drives meaningful funding rates. When BTC perps are trading 0.1% above the index during a bull run, funding will be close to the cap at 0.05%. When sentiment flips and spot rips while perp lags, funding goes negative.

The actual payment at each 8-hour settlement:

Funding Payment = Position Size (in base currency) × Funding Rate

For a 10 BTC long position at 0.05% funding rate:

Payment = 10 BTC × 0.05% = 0.005 BTC ≈ $400 at $80,000/BTC

That’s 400every8hours,or400 every 8 hours, or 1,200/day, that you’re paying just to hold the position. At scale, this is not noise - it’s a material cost center.

Mark Price vs Last Price vs Index Price

This is where most infrastructure engineers get confused, and the confusion is dangerous because using the wrong price for risk calculations can mean your system thinks it’s safe when it’s about to get liquidated.

Index Price: A weighted average of BTC/USDT spot prices across major spot exchanges (Coinbase, Binance spot, Kraken, Bitfinex, Huobi, etc.). Binance weights these by volume and applies outlier rejection to prevent any single exchange from manipulating the index. The index price is the “true” reference price.

Mark Price: This is what Binance actually uses for unrealized PnL calculation and liquidation decisions. It’s derived from the index price with a short-term smoothing mechanism:

Mark Price = Index Price × (1 + 8h EMA of basis)

where basis = (Perp Last Price - Index Price) / Index Price.

The mark price smooths out short-term manipulations of the perp price. If someone dumps the perp to trigger liquidations, the mark price won’t immediately follow - it’s anchored to the index with a smoothed adjustment.

Last Price: The most recent trade price on the perp market. This is what you see on the chart. It’s used for your entry/exit fills but NOT for unrealized PnL or liquidation threshold calculations.

The engineering implication: your risk system must subscribe to the mark price stream, not the last price stream. If you calculate your unrealized PnL and distance-to-liquidation using last price, you’re calculating against a number that Binance ignores. During thin markets or volatile moves, mark price and last price can diverge by 0.1–0.5%, which materially changes your margin calculations.

On Binance, mark price is available on the WebSocket stream:

wss://fstream.binance.com/ws/btcusdt@markPrice

It updates every second. Subscribe to this stream, not the trade stream, for your position risk calculations.

Why Funding Matters for Infrastructure

If your strategy holds positions through funding windows, funding is a direct cash flow in your PnL model. This is not a fee that disappears into the exchange - it’s a payment to or from counterparties based on market positioning.

The infrastructure requirements:

  1. Track when the next funding settlement is. Binance settles at 00:00, 08:00, and 16:00 UTC. Your position management system needs to know exactly how many hours until the next settlement and accumulate accrued funding in your unrealized PnL calculation.

  2. Fetch the predicted funding rate. Binance publishes a predicted funding rate that updates every minute in the 8-hour window leading up to settlement:

    GET /fapi/v1/premiumIndex?symbol=BTCUSDT

    The lastFundingRate field shows the most recently settled rate; nextFundingTime tells you the timestamp.

  3. Apply funding to your PnL model in real-time. Most naive implementations track fill prices and unrealized PnL from mark price but forget to subtract/add the accrued funding. This produces incorrect PnL numbers that cause incorrect risk decisions.

  4. Handle funding settlement events. When funding settles, your account balance changes. You should be reconciling your internal balance model against the exchange balance after each settlement.

Here’s a Python class that tracks funding accrual for a position:

import time
from dataclasses import dataclass, field
from typing import Optional

BINANCE_SETTLEMENT_HOURS = [0, 8, 16]  # UTC hours

@dataclass
class FundingTracker:
    symbol: str
    position_size: float  # in base currency (BTC for BTCUSDT)
    current_funding_rate: float = 0.0
    next_funding_time_ms: int = 0
    accrued_funding_usd: float = 0.0
    settled_funding_usd: float = 0.0
    last_settlement_time_ms: int = 0

    def update_funding_rate(self, funding_rate: float, next_funding_time_ms: int, mark_price: float):
        """Called when we receive a funding rate update from Binance."""
        self.current_funding_rate = funding_rate
        self.next_funding_time_ms = next_funding_time_ms
        self._recompute_accrued(mark_price)

    def _recompute_accrued(self, mark_price: float):
        """
        Compute the funding payment that would be made if settlement happened right now.
        This is the fraction of the full funding rate proportional to time elapsed
        in the current 8-hour window.
        """
        now_ms = int(time.time() * 1000)
        window_duration_ms = 8 * 60 * 60 * 1000  # 8 hours in ms
        elapsed_ms = window_duration_ms - (self.next_funding_time_ms - now_ms)
        fraction_elapsed = max(0.0, min(1.0, elapsed_ms / window_duration_ms))

        # Funding payment = position × rate × mark_price (converted to USD)
        # Positive = we pay (if long and rate is positive)
        # Negative = we receive (if long and rate is negative)
        full_payment = self.position_size * self.current_funding_rate * mark_price
        self.accrued_funding_usd = full_payment * fraction_elapsed

    def on_settlement(self, actual_payment_usd: float):
        """
        Called when Binance settles funding. The actual_payment_usd comes from
        the account balance change event on the user data stream.
        """
        self.settled_funding_usd += actual_payment_usd
        self.accrued_funding_usd = 0.0
        self.last_settlement_time_ms = int(time.time() * 1000)

    def total_funding_cost_usd(self) -> float:
        """Total realized + unrealized funding cost for this position."""
        return self.settled_funding_usd + self.accrued_funding_usd

    def expected_next_payment_usd(self, mark_price: float) -> float:
        """What we'll pay/receive at the next settlement."""
        return self.position_size * self.current_funding_rate * mark_price


def calculate_funding_payment(
    position_size_btc: float,
    funding_rate: float,
    mark_price: float
) -> float:
    """
    Calculate the funding payment for a single settlement.

    Args:
        position_size_btc: Positive = long, negative = short
        funding_rate: The settled funding rate (e.g., 0.0005 = 0.05%)
        mark_price: BTC mark price at settlement time

    Returns:
        USD amount: positive = you pay, negative = you receive
    """
    return position_size_btc * funding_rate * mark_price


# Example:
# Long 5 BTC at funding rate of 0.025% (moderate bull market)
# Mark price: $82,000
payment = calculate_funding_payment(5.0, 0.00025, 82000)
print(f"Funding payment: ${payment:.2f}")  # $102.50 per 8-hour period
print(f"Daily cost: ${payment * 3:.2f}")   # $307.50/day

The Carry Trade: When Funding Is Predictably Positive

When crypto markets are in sustained uptrends, funding rates are consistently positive - longs pay shorts. This creates the classic cash-and-carry trade:

  1. Buy spot BTC (or USDT-denominated spot on Binance)
  2. Short an equivalent amount of BTCUSDT perps
  3. Delta-neutral: the position has zero directional exposure
  4. Collect the funding rate paid by longs

When funding is running at 0.05% per 8-hour period (the Binance cap during peak bull markets), this generates:

Daily yield = 0.05% × 3 = 0.15%
Annualized = (1.0015)^365 - 1 ≈ 70% APR

This is real yield - not DeFi yield farming with protocol inflation. You’re being paid by leveraged longs to provide short-side liquidity. The risk: if the market reverses and funding goes negative (shorts start paying longs), your carry position starts costing rather than earning. You must be prepared to exit or accept that you’re now short-funding.

The infrastructure for this trade:

  • Track funding rate history to model when carry becomes attractive (typically annualized > 20% on sustained basis)
  • Monitor delta continuously - if spot and perp prices diverge even briefly, your hedge ratio drifts
  • Manage spot position on one system (exchange API or on-chain) and perp position on another - these must be linked in your position aggregation layer

Basis Trading: The Perp-Spot Premium as Signal

Basis = Perp Price - Spot Price (or as a percentage: (Perp - Spot) / Spot)

In normal markets, basis should be slightly positive and stable - the small interest rate component means perps trade at a tiny premium to spot. When basis becomes significantly positive (>0.2%), it signals that leveraged longs are paying up aggressively. When basis goes negative, spot demand is outpacing perp demand - potentially indicating institutional spot accumulation.

Basis as a market structure signal:

  • Basis expanding positively: Retail leverage building; often precedes price exhaustion
  • Basis compressing toward zero: Carry traders entering, hedging interest increasing
  • Basis negative: Spot buyers dominating; historically a healthier market structure

For your infrastructure, computing real-time basis requires:

  1. A reliable spot mid price (Binance BTCUSDT spot best bid/ask mid)
  2. The perp mark price (not last price - use mark for consistency)
  3. A rolling 1-hour, 4-hour, 24-hour basis history for trend context
def compute_basis(
    perp_mark_price: float,
    spot_mid_price: float
) -> dict:
    """Compute basis in both absolute and percentage terms."""
    absolute_basis = perp_mark_price - spot_mid_price
    percentage_basis = (perp_mark_price - spot_mid_price) / spot_mid_price * 100

    return {
        "absolute_usd": absolute_basis,
        "percentage": percentage_basis,
        "annualized_funding_equiv": percentage_basis * 3 * 365  # rough annualization
    }

How This Breaks in Production

Mistake 1: Not tracking funding in your PnL model. I’ve seen engineers build position management systems that accurately track fills and mark-to-market PnL but don’t subtract accrued funding. If you’re running a long-biased strategy in a bull market, your actual PnL can be 10-15% worse than your fill-based calculation because of accumulated funding costs. You’ll hit risk limits based on stale PnL numbers.

Mistake 2: Subscribing to last price for risk calculations. During the 2021 May crash, mark price and last price on BTCUSDT perps diverged by over 1%. Positions that appeared to have 2% margin cushion based on last price were being liquidated because mark price - what actually matters - had already blown through the maintenance margin threshold.

Mistake 3: Ignoring funding direction for position sizing. If funding is running at 0.05% per 8 hours (0.15%/day), a position held for a week costs 1.05% in funding alone. At 10x leverage, that’s 10.5% of your margin consumed by carry costs before your directional bet has even played out. Your position sizing model must include expected funding cost as a holding cost parameter.

Mistake 4: Not hedging during funding windows. In the 30 minutes before a funding settlement, leveraged traders sometimes try to push the price in the direction that makes the opposing side’s funding cost worse. This causes predictable (if not tradeable) price pressure near settlement times. If your strategy is unaware of funding timing, you may be taking fills at bad prices during this window.

Mistake 5: Treating predicted funding as settled funding. The predicted funding rate updates every minute and can change significantly. I’ve seen predicted funding at 0.03% flip to 0.005% in the last hour before settlement as arbitrageurs entered to compress the premium. Your model should use predicted funding for planning but only mark realized funding as cash in your PnL.

The perpetual futures mechanism is elegant in design and merciless in practice. Before you build any system that holds perp positions through funding windows, make sure your infrastructure correctly tracks mark price, accrues funding in your PnL model, and knows exactly when the next settlement is. Everything else depends on getting those fundamentals right.

Continue Reading

Enjoyed this?

Get one deep infrastructure insight per week.

Free forever. Unsubscribe anytime.

You're in. Check your inbox.