取引所間のファンディングレート裁定取引:レート差から利益を得る方法

暗号通貨取引所間でファンディングレート裁定取引がどのように機能するか、Binance、Bybit、OKX、dYdXでレートが異なる理由、そしてこれらの差異から利益を引き出すためのモニタリングと実行システムの構築方法。

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%程度だ。しかし、ボラティリティが高まる時期には乖離が拡大する:

市場フェーズBinanceBybitOKXdYdXスプレッド
穏やか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%になる。ポジションサイズが100Kの場合、1日あたり100Kの場合、1日あたり75、月間約$2,250となる — 方向性リスクなしで。

基本的な裁定取引のメカニズム

取引所間ファンディングレート裁定取引:2つの取引所での反対ポジション

アイデアはシンプルだ:2つの取引所で反対のポジションを開くことで、一方でファンディングを受け取り、もう一方でより少なく支払う。

例

Binance:ファンディングレート = +0.01%(ロングがショートに支払う) Bybit:ファンディングレート = +0.04%(ロングがショートに支払う)

アクション:

  1. Bybitでショートを開く — 8時間ごとに0.04%を受け取る
  2. Binanceでロングを開く — 8時間ごとに0.01%を支払う
  3. ポジションはミラーリング — 価格リスクはニュートラル
  4. 純利益: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.
    """
    # Short receives rate_short, long pays rate_long
    spread = rate_short_exchange - rate_long_exchange
    daily_pnl = spread * payments_per_day * position_size
    return daily_pnl * days

# Example: short on Bybit (0.04%), long on Binance (0.01%)
pnl = funding_arbitrage_pnl(0.0004, 0.0001, 100_000, days=30)
# = (0.0004 - 0.0001) * 3 * 100_000 * 30 = $2,700

リスクと落とし穴

取引所間裁定取引のリスク:清算、価格乖離、手数料侵食

この戦略は「無料のお金」のように見える。しかしそうではない。いくつかの深刻なリスクがある。

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):4×0.02%=0.08%4 \times 0.02\% = 0.08\%
  • 悲観的シナリオ(すべてTaker):4×0.05%=0.20%4 \times 0.05\% = 0.20\%

手数料の損益分岐点に達するには、十分な期間ポジションを保持する必要がある:

損益分岐時間=合計手数料スプレッド×1日あたりの支払い回数\text{損益分岐時間} = \frac{\text{合計手数料}}{\text{スプレッド} \times \text{1日あたりの支払い回数}}

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')

# With maker fees: 0.08% / (0.03% * 3) = 0.89 days
# With taker fees: 0.20% / (0.03% * 3) = 2.22 days

4. 証拠金要件

両方の取引所のポジションには担保が必要だ。$100Kのポジションで各取引所5倍レバレッジの場合:

  • Binance:$20K の担保
  • Bybit:$20K の担保
  • 合計ロック:100Kのポジションに対して∗∗100Kのポジションに対して **40K**

資本収益率: ROC=$2700$40000×100%=6.75% /月\text{ROC} = \frac{\$2700}{\$40000} \times 100\% = 6.75\% \text{ /月}

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.
        """
        # Collect funding rates in parallel
        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]

        # Group by symbol
        by_symbol: dict[str, list[FundingSnapshot]] = {}
        for s in snapshots:
            by_symbol.setdefault(s.symbol, []).append(s)

        # Find spreads
        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.
    """
    # Get current prices
    long_ticker = await long_exchange.fetch_ticker(symbol)
    short_ticker = await short_exchange.fetch_ticker(symbol)

    # Check the spread between exchanges
    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"
        )

    # Open simultaneously
    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

ポジション管理

オープン後は、継続的なモニタリングが必要だ:

  1. ファンディングレートスプレッド。 スプレッドが閾値以下に縮小したら — クローズ。
  2. 証拠金残高。 一方の取引所の証拠金が安全レベルを下回ったら — リバランスまたはクローズ。
  3. 価格乖離。 一方の未実現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:
        # Check the current spread
        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']
        )

        # Check margin balance
        long_balance = await long_exchange.fetch_balance()
        short_balance = await short_exchange.fetch_balance()

        # Check unrealized P&L
        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

        # Closing conditions
        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.
    """
    # Entry/exit costs
    total_fees = (spot_fee + perp_fee) * 2  # opening + closing

    # Daily income from funding (at 3 payments)
    daily_income = funding_rate * 3

    # Breakeven
    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,
    }

# Example: funding rate 0.03%
result = spot_perp_carry(0.0003)
# daily: 0.09%, monthly: 2.7%, annualized: 32.9%, breakeven: 3.3 days

マルチ取引所裁定取引

5つ以上の取引所を同時にモニタリングすると、より有利な機会を見つけることができる。アルゴリズム:

  1. すべての取引所からファンディングレートを収集する
  2. 最大スプレッドのペアを見つける
  3. 両方の取引所の流動性とオーダーブックの深さを確認する
  4. スプレッド > 閾値であれば — ポジションを開く
  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:]:
            # Long on the exchange with the lower rate, short on the one with the higher rate
            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%月間PnLROC
$10K$25K0.03%~$675~6.75%
$50K$125K0.03%~$3,375~6.75%
$200K$500K0.03%~$13,500~6.75%

ROCはスケールに依存しない(十分な流動性がある場合)。しかし、$10Kの資本での絶対的な利益は、インフラコストと時間を正当化しない可能性がある。

結論

ファンディングレート裁定取引は、構造的でデルタニュートラルな戦略である。価格予測は不要だが、以下が必要だ:

  1. インフラ — 複数の取引所にわたるレートのリアルタイムモニタリング
  2. 実行速度 — 異なる取引所でのポジションの同時オープン
  3. リスク管理 — 証拠金、価格乖離、スプレッド変動の管理
  4. 資本 — 利益はポジションサイズに比例する

ファンディングレートのスプレッドは一定ではない。ボラティリティの高い期間に拡大し、穏やかな期間に縮小する。課題は、乖離が存在する間に自動的にそれを見つけて活用することだ。

ファンディングレートがレバレッジ戦略にどのように影響するかについては、記事ファンディングレートがレバレッジを殺す:PnL×50xが虚構である理由を参照。


参考リンク

  1. Binance — Funding Rate History
  2. Binance — Introduction to Funding Rates
  3. Bybit — Understanding Funding Rates
  4. dYdX — Perpetual Funding Rate Mechanism
  5. 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.}
}