MarketMaker.cc Team
量化研究与策略
MarketMaker.cc Team
量化研究与策略
ETHUSDT 的资金费率在 Binance 上为 0.01%,在 Bybit 上为 0.035%。同一枚代币,同一时刻,但费率相差 3.5 倍。有人多付,有人少付。而有人从这个差异中获利。
资金费率套利是加密货币中为数不多的不依赖于市场方向的策略之一。你不预测价格。你从平台之间费率的结构性差异中提取利润。
资金费率是将永续合约价格锚定于现货价格的机制。每个交易所根据自己的数据独立计算:

在平静的市场中,主要交易所的资金费率接近——差异为 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%(多头向空头支付)
操作:
每天(3 次支付):0.09%。每月:约 2.7%。没有方向性风险。
def funding_arbitrage_pnl(
rate_short_exchange: float, # 做空交易所的费率
rate_long_exchange: float, # 做多交易所的费率
position_size: float, # 仓位大小(美元)
payments_per_day: int = 3,
days: int = 30,
) -> float:
"""
一段时间内资金费率套利的 PnL。
正资金费率时:空头收取,多头支付。
负资金费率时:空头支付,多头收取。
"""
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)
这个策略看起来像"免费的钱"。实际并非如此。存在几个严重的风险。
不同交易所的仓位价格不同。Binance 和 Bybit 之间的价差通常为 0.01-0.05%,但在高波动时刻可能达到 0.5-1%。如果你不同时开仓,价格差异可能超过资金费率利润。
**解决方案:**通过 API 同时开仓,延迟最小化。理想情况下——在两个交易所附近部署共址服务器。
你在价差 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% 开仓 + 平仓
) -> bool:
"""
如果价差低于阈值或当前价差不足以覆盖交易成本,
则平仓。
"""
return current_spread < min_spread or current_spread < trading_costs
在两个交易所开仓和平仓意味着 4 个订单。在 maker 费率 0.02% 和 taker 费率 0.05% 下:
为了使手续费回本,需要持仓足够长的时间:
def breakeven_days(
total_commissions_pct: float, # 总手续费百分比
spread: float, # 资金费率价差
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')
两个交易所的仓位都需要抵押品。在每个交易所 5 倍杠杆和 $100K 仓位下:
资本回报率:
在 10 倍杠杆下,抵押品降至 $20K,ROC 上升至 13.5%。但价格差异导致的清算风险也会增加。
如果资产价格剧烈波动,其中一个仓位产生未实现亏损。在亏损仓位所在的交易所需要维持保证金。如果保证金不足——清算。而另一个交易所的利润无济于事——它在不同的账户中。
解决方案:
套利的第一步是数据收集。你需要实时跟踪所有感兴趣交易所的资金费率。
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:
"""
监控多个交易所的资金费率。
"""
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):
"""从交易所获取当前资金费率。"""
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]:
"""
扫描所有交易所,寻找套利机会。
"""
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] # 在这里做多(支付更少)
highest = rates[-1] # 在这里做空(收取更多)
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, # 年化百分比
})
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,
):
"""
在两个交易所同时开设多头和空头。
"""
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
开仓后需要持续监控:
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,
):
"""
监控已开设的套利仓位。
"""
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, # 当前资金费率
spot_fee: float = 0.001, # 现货手续费(0.1%)
perp_fee: float = 0.0005, # 期货手续费(0.05%)
leverage: int = 1,
) -> dict:
"""
计算现货-永续 carry trade 的收益率。
"""
total_fees = (spot_fee + perp_fee) * 2 # 开仓 + 平仓
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:
"""
找到资金费率价差最大的交易所配对。
Returns: (long_exchange, short_exchange, spread) 或 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, # 每 8 小时 0.01%(标准)
clamp_range: float = 0.0005, # ±0.05%
) -> float:
"""
基于当前溢价指数预测下一个资金费率。
Binance 公式: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 资金的绝对利润可能无法证明基础设施成本和时间投入的合理性。
资金费率套利是一种结构性的、Delta 中性的策略。它不需要预测价格,但需要:
资金费率价差不是恒定的。它们在波动期扩大,在平静期缩小。任务是自动发现并利用差异,趁它们还存在的时候。
关于资金费率如何影响杠杆策略的更多内容——请参阅文章资金费率扼杀你的杠杆:为什么 PnL×50x 是虚构的。
@article{soloviov2026fundingarbitrage, author = {Soloviov, Eugen}, title = {Funding Rate Arbitrage Across Exchanges: How to Profit from Rate Differences}, year = {2026}, url = {https://marketmaker.cc/ru/blog/post/funding-rate-arbitrage-cross-exchange}, description = {加密交易所之间的资金费率套利如何运作,为什么 Binance、Bybit、OKX 和 dYdX 上的费率不同,以及如何构建监控和执行系统。} }