取引所間のファンディングレート裁定取引:レート差から利益を得る方法
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)は1時間ごとに支払い、追加の機会を生み出す。
典型的な乖離

穏やかな市場では、主要取引所のファンディングレートは近い値になり、差は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%のスプレッドは、1日あたり0.075%になる。ポジションサイズが75、月間約$2,250となる — 方向性リスクなしで。
基本的な裁定取引のメカニズム

アイデアはシンプルだ:2つの取引所で反対のポジションを開くことで、一方でファンディングを受け取り、もう一方でより少なく支払う。
例
Binance:ファンディングレート = +0.01%(ロングがショートに支払う) Bybit:ファンディングレート = +0.04%(ロングがショートに支払う)
アクション:
- Bybitでショートを開く — 8時間ごとに0.04%を受け取る
- Binanceでロングを開く — 8時間ごとに0.01%を支払う
- ポジションはミラーリング — 価格リスクはニュートラル
- 純利益:0.04% - 0.01% = 8時間あたり0.03%
1日あたり(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%のスプレッドでポジションを開いた。1時間後にスプレッドが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. 取引手数料
2つの取引所でポジションを開閉するということは、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)
上級バリエーション
現物-パーペチュアル裁定取引
2つの取引所の先物の代わりに、1つの取引所で現物+先物を使うことができる:
- 現物を買う(ファンディングなし)
- 無期限先物をショートする(レートがプラスの時にファンディングを受け取る)
利点:すべて1つの取引所で完結し、証拠金管理がシンプル。欠点:プラスのファンディング(ロングがショートに支払う)の場合のみ機能し、強気相場では約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/ja/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
クオンツ・リサーチ&戦略