거래소 간 펀딩비 차익거래: 금리 차이에서 수익을 얻는 방법
Binance의 ETHUSDT 펀딩비는 0.01%, Bybit에서는 0.035%이다. 같은 코인, 같은 시점이지만 금리는 3.5배나 다르다. 누군가는 더 많이 지불하고, 누군가는 덜 지불한다. 그리고 누군가는 이 차이에서 수익을 낸다.
펀딩비 차익거래는 암호화폐에서 시장 방향에 의존하지 않는 몇 안 되는 전략 중 하나이다. 가격을 예측하지 않는다. 거래소 간 금리의 구조적 차이에서 수익을 추출한다.
왜 거래소마다 펀딩비가 다른가
펀딩비는 무기한 선물 계약의 가격을 현물 가격에 고정시키는 메커니즘이다. 각 거래소는 자체 데이터를 기반으로 독립적으로 계산한다:
- 트레이더 구성. Binance는 롱 포지션을 선호하는 개인 투자자가 지배적이다. Bybit과 OKX에는 더 많은 전문 참가자가 있다. 롱/숏 밸런스가 다르면 펀딩비도 달라진다.
- 계산 공식. 각 거래소는 자체 공식을 사용한다. Binance는 프리미엄 인덱스와 금리를 고려한다. Bybit과 OKX도 마찬가지이지만 가중치와 평균화 기간이 다르다.
- 유동성. 유동성이 낮은 거래소에서는 프리미엄(선물과 현물의 차이)이 더 변동성이 크며, 펀딩비의 변동폭도 커진다.
- 지급 빈도. 대부분의 거래소는 8시간마다(00:00, 08:00, 16:00 UTC) 펀딩비를 지급한다. 그러나 일부(Bybit의 특정 페어, dYdX)는 매시간 지급하여 추가적인 기회를 만든다.
전형적인 차이

안정적인 시장에서 주요 거래소의 펀딩비는 비슷하며, 차이는 0.001-0.005%이다. 그러나 변동성이 높아지는 시기에는 차이가 커진다:
| 시장 단계 | Binance | Bybit | OKX | dYdX | 스프레드 |
|---|---|---|---|---|---|
| 안정적 | 0.01% | 0.012% | 0.009% | 0.01% | ~0.003% |
| 상승 추세 | 0.03% | 0.05% | 0.025% | 0.04% | ~0.025% |
| 극단적 상승 | 0.1% | 0.2% | 0.08% | 0.15% | ~0.12% |
| 하락 추세 | -0.02% | -0.01% | -0.025% | -0.015% | ~0.015% |
8시간당 0.025%의 스프레드는 하루 0.075%이다. 포지션 규모가 75 또는 월 약 $2,250이다 — 방향성 리스크 없이.
기본적인 차익거래 메커니즘

아이디어는 간단하다: 두 거래소에서 반대 포지션을 열어 한쪽에서 펀딩비를 받고 다른 쪽에서 더 적게 지불하는 것이다.
예시
Binance: 펀딩비 = +0.01% (롱이 숏에게 지불) Bybit: 펀딩비 = +0.04% (롱이 숏에게 지불)
행동:
- Bybit에서 숏 진입 — 8시간마다 0.04% 수령
- Binance에서 롱 진입 — 8시간마다 0.01% 지불
- 포지션은 미러링 — 가격 리스크 중립
- 순이익: 0.04% - 0.01% = 8시간당 0.03%
하루(3회 지급): 0.09%. 월간: 약 2.7%. 방향성 리스크 없음.
def funding_arbitrage_pnl(
rate_short_exchange: float, # rate on the exchange where we short
rate_long_exchange: float, # rate on the exchange where we long
position_size: float, # position size in USD
payments_per_day: int = 3,
days: int = 30,
) -> float:
"""
PnL from funding rate arbitrage over a period.
With positive funding: short receives, long pays.
With negative funding: short pays, long receives.
"""
spread = rate_short_exchange - rate_long_exchange
daily_pnl = spread * payments_per_day * position_size
return daily_pnl * days
pnl = funding_arbitrage_pnl(0.0004, 0.0001, 100_000, days=30)
리스크와 함정

이 전략은 "공짜 돈"처럼 보인다. 하지만 그렇지 않다. 몇 가지 심각한 리스크가 있다.
1. 거래소 간 가격 차이
서로 다른 거래소의 포지션은 동일한 가격이 아니다. Binance와 Bybit 간의 스프레드는 보통 0.01-0.05%이지만, 높은 변동성의 순간에는 0.5-1%에 도달할 수 있다. 포지션을 동시에 열지 않으면, 차이가 펀딩 수익을 초과할 수 있다.
해결책: 최소 지연시간으로 API를 통한 동시 진입. 이상적으로는 — 양쪽 거래소 근처에 코로케이션된 서버.
2. 펀딩비 변동
0.03%의 스프레드로 포지션을 열었다. 한 시간 후 스프레드가 0.005%로 축소되거나 역전된다. 이제 양쪽 거래소에서 지불하게 된다.
해결책: 실시간 스프레드 모니터링과 스프레드가 임계값 아래로 떨어지면 자동 청산.
def should_close(
current_spread: float,
entry_spread: float,
min_spread: float = 0.0001, # 0.01%
trading_costs: float = 0.0005, # 0.05% for opening + closing
) -> bool:
"""
Close the position if the spread has fallen below the threshold
or if the current spread does not cover trading costs.
"""
return current_spread < min_spread or current_spread < trading_costs
3. 거래 수수료
두 거래소에서 포지션을 열고 닫는 것은 4개의 주문을 의미한다. Maker 수수료 0.02%, Taker 수수료 0.05%일 때:
- 낙관적 시나리오 (전부 Maker):
- 비관적 시나리오 (전부 Taker):
수수료의 손익분기점에 도달하려면 충분한 기간 동안 포지션을 유지해야 한다:
def breakeven_days(
total_commissions_pct: float, # total commissions in %
spread: float, # funding rate spread
payments_per_day: int = 3,
) -> float:
daily_income = spread * payments_per_day
return total_commissions_pct / daily_income if daily_income > 0 else float('inf')
4. 증거금 요건
양쪽 거래소의 포지션에는 담보가 필요하다. $100K 포지션에 각 거래소 5배 레버리지의 경우:
- Binance: $20K 담보
- Bybit: $20K 담보
- 총 잠김: 40K**
자본 수익률:
10배 레버리지에서는 담보가 $20K로 줄어들고 ROC는 13.5%로 상승한다. 그러나 가격 차이로 인한 청산 리스크도 증가한다.
5. 청산 리스크
자산 가격이 급격히 움직이면, 한쪽 포지션에 미실현 손실이 발생한다. 손실이 발생한 포지션이 있는 거래소에서는 증거금을 유지해야 한다. 증거금이 부족하면 — 청산. 한편, 다른 거래소의 이익은 도움이 되지 않는다 — 다른 계정에 있기 때문이다.
해결책:
- 증거금 여유분 확보 (최소 최저치의 2배)
- 증거금 수준 알림 설정
- 자동 리밸런싱: 불균형 발생 시 — 거래소 간 자금 이동
펀딩비 모니터링 시스템
차익거래의 첫 번째 단계는 데이터 수집이다. 관심 있는 모든 거래소의 펀딩비를 실시간으로 추적해야 한다.
import asyncio
import ccxt.pro as ccxt
from dataclasses import dataclass
from datetime import datetime
@dataclass
class FundingSnapshot:
exchange: str
symbol: str
rate: float
next_funding_time: datetime
timestamp: datetime
class FundingMonitor:
"""
Monitor funding rates across multiple exchanges.
"""
def __init__(self, symbols: list[str], exchanges: list[str]):
self.symbols = symbols
self.exchanges = {
name: getattr(ccxt, name)() for name in exchanges
}
self.latest: dict[str, dict[str, FundingSnapshot]] = {}
async def fetch_funding(self, exchange_name: str, exchange, symbol: str):
"""Fetch current funding rate from an exchange."""
try:
funding = await exchange.fetch_funding_rate(symbol)
return FundingSnapshot(
exchange=exchange_name,
symbol=symbol,
rate=funding['fundingRate'],
next_funding_time=datetime.fromtimestamp(
funding['fundingTimestamp'] / 1000
),
timestamp=datetime.utcnow(),
)
except Exception as e:
print(f"Error fetching {exchange_name} {symbol}: {e}")
return None
async def scan(self) -> list[dict]:
"""
Scan all exchanges and find arbitrage opportunities.
"""
tasks = []
for ex_name, ex in self.exchanges.items():
for symbol in self.symbols:
tasks.append(self.fetch_funding(ex_name, ex, symbol))
snapshots = await asyncio.gather(*tasks)
snapshots = [s for s in snapshots if s is not None]
by_symbol: dict[str, list[FundingSnapshot]] = {}
for s in snapshots:
by_symbol.setdefault(s.symbol, []).append(s)
opportunities = []
for symbol, rates in by_symbol.items():
rates.sort(key=lambda x: x.rate)
lowest = rates[0] # long here (pay less)
highest = rates[-1] # short here (receive more)
spread = highest.rate - lowest.rate
opportunities.append({
'symbol': symbol,
'long_exchange': lowest.exchange,
'long_rate': lowest.rate,
'short_exchange': highest.exchange,
'short_rate': highest.rate,
'spread': spread,
'annualized': spread * 3 * 365 * 100, # in % annualized
})
return sorted(opportunities, key=lambda x: -x['spread'])
샘플 출력
Symbol | Long @ | Rate | Short @ | Rate | Spread | APR
-----------+-------------+---------+-------------+---------+---------+--------
ETHUSDT | Binance | 0.010% | Bybit | 0.040% | 0.030% | 32.9%
BTCUSDT | OKX | 0.008% | Binance | 0.020% | 0.012% | 13.1%
SOLUSDT | Binance | 0.015% | dYdX | 0.055% | 0.040% | 43.8%
ARBUSDT | Bybit | 0.005% | OKX | 0.030% | 0.025% | 27.4%
실행: 동시 포지션 진입

롱과 숏을 가능한 한 동시에 여는 것이 극히 중요하며, 방향성 리스크 노출을 피해야 한다.
import asyncio
async def execute_arbitrage(
long_exchange,
short_exchange,
symbol: str,
size: float,
max_slippage_pct: float = 0.05,
):
"""
Simultaneously open a long and short on two exchanges.
"""
long_ticker = await long_exchange.fetch_ticker(symbol)
short_ticker = await short_exchange.fetch_ticker(symbol)
price_spread = abs(
long_ticker['ask'] - short_ticker['bid']
) / long_ticker['ask'] * 100
if price_spread > max_slippage_pct:
raise ValueError(
f"Price spread {price_spread:.3f}% exceeds max slippage"
)
long_order, short_order = await asyncio.gather(
long_exchange.create_market_buy_order(symbol, size),
short_exchange.create_market_sell_order(symbol, size),
)
return long_order, short_order
포지션 관리
진입 후에는 지속적인 모니터링이 필요하다:
- 펀딩비 스프레드. 스프레드가 임계값 이하로 축소되면 — 청산.
- 증거금 잔액. 한쪽 거래소의 증거금이 안전 수준 아래로 떨어지면 — 리밸런스 또는 청산.
- 가격 차이. 한쪽의 미실현 P&L이 한도를 초과하면 — 청산.
async def monitor_and_manage(
long_exchange,
short_exchange,
symbol: str,
size: float,
min_spread: float = 0.0001,
max_unrealized_loss_pct: float = 2.0,
check_interval: int = 60,
):
"""
Monitor an open arbitrage position.
"""
while True:
long_funding = await long_exchange.fetch_funding_rate(symbol)
short_funding = await short_exchange.fetch_funding_rate(symbol)
current_spread = (
short_funding['fundingRate'] - long_funding['fundingRate']
)
long_balance = await long_exchange.fetch_balance()
short_balance = await short_exchange.fetch_balance()
long_positions = await long_exchange.fetch_positions([symbol])
short_positions = await short_exchange.fetch_positions([symbol])
long_upnl = long_positions[0]['unrealizedPnl'] if long_positions else 0
short_upnl = short_positions[0]['unrealizedPnl'] if short_positions else 0
total_upnl_pct = (long_upnl + short_upnl) / size * 100
if current_spread < min_spread:
print(f"Spread collapsed: {current_spread:.4%}")
await close_both(long_exchange, short_exchange, symbol, size)
break
if abs(total_upnl_pct) > max_unrealized_loss_pct:
print(f"Unrealized loss exceeded: {total_upnl_pct:.2f}%")
await close_both(long_exchange, short_exchange, symbol, size)
break
await asyncio.sleep(check_interval)
고급 변형
현물-무기한 차익거래
두 거래소의 선물 대신, 하나의 거래소에서 현물 + 선물을 사용할 수 있다:
- 현물 매수 (펀딩 없음)
- 무기한 선물 숏 (금리가 양수일 때 펀딩 수령)
장점: 모든 것이 하나의 거래소에서 이루어져 증거금 관리가 간단하다. 단점: 양의 펀딩(롱이 숏에게 지불)인 경우에만 작동하며, 강세장에서 약 70%의 시간 동안 관찰된다.
def spot_perp_carry(
funding_rate: float, # current funding rate
spot_fee: float = 0.001, # spot commission (0.1%)
perp_fee: float = 0.0005, # futures commission (0.05%)
leverage: int = 1,
) -> dict:
"""
Calculate the yield of a spot-perp carry trade.
"""
total_fees = (spot_fee + perp_fee) * 2 # opening + closing
daily_income = funding_rate * 3
breakeven_days = total_fees / daily_income if daily_income > 0 else float('inf')
return {
'daily_income_pct': daily_income * 100,
'monthly_income_pct': daily_income * 30 * 100,
'annualized_pct': daily_income * 365 * 100,
'total_fees_pct': total_fees * 100,
'breakeven_days': breakeven_days,
}
result = spot_perp_carry(0.0003)
다중 거래소 차익거래
5개 이상의 거래소를 동시에 모니터링하면 더 유리한 기회를 찾을 수 있다. 알고리즘:
- 모든 거래소에서 펀딩비 수집
- 최대 스프레드를 가진 페어 찾기
- 양쪽 거래소의 유동성과 오더북 깊이 확인
- 스프레드 > 임계값이면 — 포지션 진입
- 지속적으로 재스캔: 최적의 페어가 변경되면 — 로테이션
def find_best_pair(
rates: dict[str, float], # {"binance": 0.01, "bybit": 0.04, "okx": 0.02}
min_spread: float = 0.0002,
) -> tuple[str, str, float] | None:
"""
Find the exchange pair with the maximum funding rate spread.
Returns: (long_exchange, short_exchange, spread) or None.
"""
exchanges = list(rates.keys())
best = None
for i, ex_long in enumerate(exchanges):
for ex_short in exchanges[i+1:]:
if rates[ex_long] < rates[ex_short]:
spread = rates[ex_short] - rates[ex_long]
long_ex, short_ex = ex_long, ex_short
else:
spread = rates[ex_long] - rates[ex_short]
long_ex, short_ex = ex_short, ex_long
if spread >= min_spread:
if best is None or spread > best[2]:
best = (long_ex, short_ex, spread)
return best
펀딩비 예측
펀딩비는 프리미엄 인덱스(선물 가격과 현물 가격의 차이)를 포함하는 공식으로 계산된다. 프리미엄은 펀딩보다 더 자주 업데이트된다(매분 vs 8시간마다). 이는 지급 몇 분 또는 몇 시간 전에 다음 펀딩비를 예측할 수 있다는 것을 의미한다.
def predict_next_funding(
premium_index: float,
interest_rate: float = 0.0001, # 0.01% per 8h (standard)
clamp_range: float = 0.0005, # ±0.05%
) -> float:
"""
Predict the next funding rate based on the current premium index.
Binance formula: FR = clamp(Premium - Interest, -0.05%, 0.05%) + Interest
"""
diff = premium_index - interest_rate
clamped = max(-clamp_range, min(clamp_range, diff))
return clamped + interest_rate
예측된 펀딩비를 알면, 스프레드가 다른 차익거래자들의 주의를 끌기 전에 포지션을 열 수 있다.
인프라 요건
본격적인 펀딩비 차익거래에는 인프라가 필요하다:
| 구성 요소 | 최소 | 최적 |
|---|---|---|
| 서버 | 클라우드 VPS | 거래소 근처 코로케이션 |
| 지연시간 | < 500ms | < 50ms |
| API 키 | 2개 거래소 | 5개 이상 거래소 |
| 거래소당 자본 | 각 $10K | 각 $50K 이상 |
| 모니터링 | 로그 + 알림 | 대시보드 + 자동 리밸런싱 |
| 데이터 | REST API 폴링 | WebSocket 스트리밍 |
다양한 규모에서의 경제성
| 자본 | 포지션 (5배) | 스프레드 0.03% | 월간 PnL | ROC |
|---|---|---|---|---|
| $10K | $25K | 0.03% | ~$675 | ~6.75% |
| $50K | $125K | 0.03% | ~$3,375 | ~6.75% |
| $200K | $500K | 0.03% | ~$13,500 | ~6.75% |
ROC는 규모에 의존하지 않는다(충분한 유동성이 있는 경우). 그러나 $10K 자본에서의 절대 수익은 인프라 비용과 시간을 정당화하지 못할 수 있다.
결론
펀딩비 차익거래는 구조적이고 델타 중립적인 전략이다. 가격 예측이 필요하지 않지만, 다음이 필요하다:
- 인프라 — 여러 거래소에 걸친 금리의 실시간 모니터링
- 실행 속도 — 서로 다른 거래소에서의 동시 포지션 진입
- 리스크 관리 — 증거금, 가격 차이, 스프레드 변동 관리
- 자본 — 수익은 포지션 규모에 비례
펀딩비 스프레드는 일정하지 않다. 변동성이 높은 시기에 확대되고 안정적인 시기에 축소된다. 과제는 차이가 존재하는 동안 자동으로 이를 찾아 활용하는 것이다.
펀딩비가 레버리지 전략에 미치는 영향에 대해서는 기사 펀딩비가 레버리지를 죽인다: PnL×50x가 허구인 이유를 참조하라.
유용한 링크
- Binance — Funding Rate History
- Binance — Introduction to Funding Rates
- Bybit — Understanding Funding Rates
- dYdX — Perpetual Funding Rate Mechanism
- Coinglass — Funding Rate Monitor
Citation
@article{soloviov2026fundingarbitrage,
author = {Soloviov, Eugen},
title = {Funding Rate Arbitrage Across Exchanges: How to Profit from Rate Differences},
year = {2026},
url = {https://marketmaker.cc/ko/blog/post/funding-rate-arbitrage-cross-exchange},
description = {How funding rate arbitrage works across crypto exchanges, why rates differ on Binance, Bybit, OKX and dYdX, and how to build a monitoring and execution system.}
}
MarketMaker.cc Team
퀀트 리서치 및 전략