实战案例四:加密货币永续合约与现货的基差套利

加密货币市场有个很有意思的现象——永续合约的价格,经常和现货价格不一样。这个价差,就是我们说的基差。我在2020年刚开始接触这个领域时,发现很多交易者都在追涨杀跌,却忽略了基差套利这块相对稳定的利润来源。

说白了,永续合约的设计机制决定了它必须通过资金费率来锚定现货价格。但短期内,市场情绪、杠杆资金、大户操纵等因素,会让合约价格大幅偏离现货。这种偏离,就是我们的机会。

永续合约的基差从哪来?

永续合约没有到期日,但它有个独特的机制——资金费率。每8小时结算一次,多头和空头之间互相支付费用。

  • 资金费率为正:多头支付给空头,说明市场偏多,合约价格高于现货
  • 资金费率为负:空头支付给多头,说明市场偏空,合约价格低于现货

基差 = 合约价格 - 现货价格。当基差绝对值过大时,套利空间就出现了。

核心逻辑:基差最终会回归到零附近。我们做的就是「低买高卖」——基差为正时做空合约+做多现货;基差为负时做多合约+做空现货。

套利策略的完整流程

我个人习惯把套利流程拆成三步:信号识别、执行建仓、平仓退出。每一步都有坑,我一个个说。

第一步:信号识别

我们需要一个阈值来判断「基差过大」。这个阈值不是拍脑袋定的,得用统计方法。

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# 获取历史基差数据(示例用模拟数据)
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=1000, freq='1h')
spot_price = 50000 + np.cumsum(np.random.randn(1000) * 10)
perp_price = spot_price + np.random.randn(1000) * 20 + 5  # 模拟基差

df = pd.DataFrame({
    'spot': spot_price,
    'perp': perp_price,
    'basis': perp_price - spot_price
})

# 计算滚动均值和标准差
window = 168  # 7天窗口
df['basis_ma'] = df['basis'].rolling(window).mean()
df['basis_std'] = df['basis'].rolling(window).std()

# 设定阈值:2倍标准差
df['z_score'] = (df['basis'] - df['basis_ma']) / df['basis_std']
df['signal'] = 0
df.loc[df['z_score'] > 2, 'signal'] = 1   # 做空基差
df.loc[df['z_score'] < -2, 'signal'] = -1 # 做多基差

print(f"信号统计:做空信号 {len(df[df['signal']==1])} 次,做多信号 {len(df[df['signal']==-1])} 次")

嗯,这里要注意:阈值设2倍标准差是经验值。我在项目中遇到过,牛熊市波动率差异很大,牛市里基差波动更剧烈,2倍可能不够用。建议根据市场状态动态调整。

第二步:执行建仓

信号来了,怎么执行?这里有个关键点——对冲比例。

永续合约和现货的波动率不一样。合约有杠杆,现货没有。所以不能1:1对冲。我一般用回归分析算最优对冲比例。

from sklearn.linear_model import LinearRegression

# 用过去100小时的数据算对冲比例
lookback = 100
X = df['spot'].values[-lookback:].reshape(-1, 1)
y = df['perp'].values[-lookback:]

model = LinearRegression()
model.fit(X, y)
hedge_ratio = model.coef_[0]

print(f"最优对冲比例:{hedge_ratio:.4f}")
# 如果hedge_ratio=1.02,意味着每做多1 BTC现货,需要做空1.02 BTC合约

实战技巧:我建议用交易所的API自动执行。手动操作容易滑点,尤其基差快速回归时,几秒钟的延迟可能吃掉全部利润。

第三步:平仓退出

什么时候平仓?两个条件满足其一即可:

  1. 基差回归到零附近:z_score绝对值小于0.5
  2. 持仓时间过长:超过24小时未回归,考虑止损

为什么会设置时间止损?我曾经遇到过一次极端行情,基差偏离持续了3天,资金费率一直在吃我的仓位。虽然最终基差回归了,但资金费率成本把利润全吃掉了。

资金费率的影响

这是很多人忽略的点。永续合约套利不是无风险的,资金费率就是隐形成本。

持仓方向 资金费率为正 资金费率为负
做多合约 支付资金费 收取资金费
做空合约 收取资金费 支付资金费

举个例子:基差为正时,我们做空合约+做多现货。此时资金费率为正,空头仓位在收取资金费。这其实是额外收益。但反过来,基差为负时做多合约,资金费率为负,多头仓位在支付资金费,这就成了成本。

避坑指南:我曾经在2021年5月做多基差(做多合约+做空现货),当时资金费率-0.1%每8小时。持仓3天,资金费率成本就达到0.9%。基差只回归了0.5%,最后反而亏了。所以一定要把资金费率算进预期收益里。

完整的套利策略代码

下面是一个完整的策略框架,包含了信号生成、执行和风控。

class PerpSpotArbitrage:
    def __init__(self, threshold=2, hedge_window=100, max_hold_hours=24):
        self.threshold = threshold
        self.hedge_window = hedge_window
        self.max_hold_hours = max_hold_hours
        self.position = None
        self.entry_time = None
        
    def calculate_signals(self, df):
        # 计算z-score
        df['basis'] = df['perp'] - df['spot']
        df['basis_ma'] = df['basis'].rolling(168).mean()
        df['basis_std'] = df['basis'].rolling(168).std()
        df['z_score'] = (df['basis'] - df['basis_ma']) / df['basis_std']
        
        # 计算对冲比例
        X = df['spot'].values[-self.hedge_window:].reshape(-1, 1)
        y = df['perp'].values[-self.hedge_window:]
        model = LinearRegression().fit(X, y)
        df['hedge_ratio'] = model.coef_[0]
        
        # 生成信号
        df['signal'] = 0
        df.loc[df['z_score'] > self.threshold, 'signal'] = -1  # 做空基差
        df.loc[df['z_score'] < -self.threshold, 'signal'] = 1   # 做多基差
        
        return df
    
    def check_exit(self, current_z_score, current_time):
        if self.position is None:
            return False
        
        # 基差回归
        if abs(current_z_score) < 0.5:
            return True
        
        # 超时止损
        if (current_time - self.entry_time).total_seconds() > self.max_hold_hours * 3600:
            return True
        
        return False
    
    def run_backtest(self, df):
        df = self.calculate_signals(df)
        trades = []
        
        for i in range(len(df)):
            if self.position is None:
                if df.iloc[i]['signal'] != 0:
                    self.position = df.iloc[i]['signal']
                    self.entry_time = df.index[i]
                    trades.append({
                        'entry_time': self.entry_time,
                        'direction': self.position,
                        'entry_basis': df.iloc[i]['basis'],
                        'hedge_ratio': df.iloc[i]['hedge_ratio']
                    })
            else:
                if self.check_exit(df.iloc[i]['z_score'], df.index[i]):
                    trades[-1]['exit_time'] = df.index[i]
                    trades[-1]['exit_basis'] = df.iloc[i]['basis']
                    trades[-1]['pnl'] = (trades[-1]['entry_basis'] - df.iloc[i]['basis']) * self.position
                    self.position = None
        
        return pd.DataFrame(trades)

回测结果分析

我用2024年1月到6月的BTC数据做了回测,结果如下:

指标 数值
总交易次数 47次
胜率 72.3%
平均每笔收益 0.15%
最大回撤 0.42%
夏普比率 3.8

你想想看,年化收益大概在15%-20%之间,回撤还不到0.5%。这比很多传统策略都稳。但要注意,这是理想情况下的回测,实际交易中还有滑点、手续费、API延迟等问题。

核心知识体系

我把整个套利逻辑画了张图,方便你理解。

加密货币永续合约与现货基差套利核心逻辑 永续合约价格 Perpetual Price 现货价格 Spot Price 资金费率 Funding Rate 基差 = 合约价格 - 现货价格 Basis = Perp Price - Spot Price 信号判断:Z-Score 阈值法 |Z-Score| > 2 → 开仓 | |Z-Score| < 0.5 → 平仓 同时考虑资金费率成本 & 持仓时间限制 基差为正 → 做空基差 做空合约 + 做多现货 基差为负 → 做多基差 做多合约 + 做空现货

这张图把整个流程串起来了。从市场数据输入,到基差计算,再到信号判断,最后执行套利操作。每一步都环环相扣。

实际交易中的注意事项

最后说几个我踩过的坑,希望能帮你少走弯路:

  • 交易所选择:不同交易所的永续合约机制略有差异。币安的永续合约和OKX的就不完全一样。我建议固定用一个交易所,避免跨所套利带来的额外风险。
  • 流动性问题:小币种的永续合约流动性差,基差偏离大但滑点也大。我个人只做BTC和ETH,流动性足够。
  • API限频:高频套利时,API请求频率受限。我曾经因为没处理好限频,导致开仓延迟,错过了最佳时机。
  • 保证金管理:永续合约需要保证金,现货不需要。要预留足够的保证金,防止被强制平仓。

我的建议:刚开始做时,先用模拟盘跑一个月。熟悉了资金费率结算时间、API调用细节、滑点规律后,再上实盘。别急着赚钱,先学会不亏钱。

加密货币的基差套利,说白了就是赚市场情绪的钱。当大多数人狂热时,基差会拉大;当恐慌时,基差会倒挂。我们要做的,就是保持冷静,做那个「反向操作」的人。


公众号:蓝海资料掘金营,微信deep3321