1900年,巴黎。
一个俄国数学家坐在咖啡馆里,盯着一张纸发呆。纸上写满了公式,他在试图证明一件事------股票价格可以被预测。
这个人名叫巴舍利耶(Louis Bachelier),他的博士论文题目是《投机理论》。在这篇论文里,他第一次用数学模型描述了期权价格的波动规律。
有意思的是,他的导师------大数学家庞加莱------在评审意见里写了一句话:"巴舍利耶把概率论用在了金融上,这很有趣,但跟金融市场有什么关系呢?"
50年后,同样的数学模型被布莱克和斯科尔斯重新发现,变成了著名的"Black-Scholes期权定价公式"。两个人因此拿了诺贝尔奖。
而巴舍利耶呢?他的论文被遗忘了半个世纪。
为什么讲这个故事?因为巴舍利耶做的事情,本质上就是统计套利的雏形------用数学模型发现市场价格的"不合理",然后从中获利。
今天这篇,我们就来聊聊量化交易中最神秘、也最让人着迷的策略类型------统计套利 。

Why:为什么市场会存在"定价误差"?
一个反直觉的事实
如果市场是有效的------也就是说,所有信息都会立刻反映在价格里------那应该不存在任何"免费的午餐"。
但事实是:市场并不总是有效的。
你有没有见过这样的场景?
• 两只业务几乎一模一样的公司,一家市值100亿,另一家市值60亿。
• 同一家公司,在A股的价格比在H股贵了30%。
• 某只股票因为一个明显的假消息暴跌20%,三天后又涨回来了。
这些现象说明什么?说明价格在很多时候是"错"的 。
不是长期错,是短期错。错的时间可能是一天、一周、一个月。但最终,价格会回到它"应该在"的位置。
这个过程,就叫均值回归 。
均值回归:统计套利的底层逻辑
均值回归是什么意思?
简单说就是:偏离了平均值的东西,最终会回到平均值附近。
一根橡皮筋,你拉得越长,它弹回来的力量就越大。
股票价格也是一样。当价格偏离了它的"合理价值"太远,就会有一股力量把它拉回来。
这股力量是什么?是套利者。
当你发现一只股票被低估了,你买入。当别人也发现了,他们也买入。买入的人多了,价格就上去了,回到了合理水平。
统计套利的本质,就是系统地、大量地寻找这些"定价偏差",然后从中获利。
定价偏差从何而来?
你可能会问:市场里有那么多聪明人,为什么还会有定价偏差?
答案是:因为人不是机器。
具体来说,定价偏差主要来自三个方面:
1. 行为偏差
人是有情绪的。恐惧、贪婪、从众心理......这些情绪会导致价格过度反应或反应不足。
• 过度反应 :一个坏消息出来,大家恐慌性抛售,价格跌过头了。等情绪平复,价格涨回来。
• 反应不足 :一个好消息出来,大家不以为然,价格没怎么涨。等更多人意识到这是好消息,价格才慢慢涨上去。
2. 流动性差异
大机构要卖股票,不可能一天卖完,得卖好几天。这几天里,持续的卖压会把价格压低。等机构卖完了,价格又会回升。
同样,大基金建仓的时候,连续的买入会把价格推高。等建仓完成,价格可能已经偏离了合理水平。
3. 信息不对称
有些信息,有些人知道得早,有些人知道得晚。
先知道的人先交易,价格先动。后知道的人后交易,价格再动。这中间就存在一个时间差,可以被利用。
What:统计套利 vs 确定性套利
先搞清楚一个概念
说到"套利",很多人第一反应是"无风险赚钱"。
没错,确定性套利 (也叫无风险套利)确实是这样的。
举个例子:
同一家公司的股票,在A股卖100元,在H股卖70元(换算后)。你买入H股,同时卖空A股,等两边价格收敛,你就赚了30元的差价。无风险。
但这种机会,在成熟市场里几乎不存在了。因为一旦有价差,高频交易程序会在毫秒级别内把它抹平。
统计套利和确定性套利的区别在于:统计套利是有风险的。
为什么?因为你赌的是"价格会回归",但价格可能不回归 。
• 它可能继续偏离
• 它可能偏离的时间比你想象得长得多
• 甚至,你可能判断错了------价格根本没有偏离,是你算错了
所以,统计套利不是"无风险套利",而是"概率优势的套利 "。
你做的是大量的小赌注,每个赌注的胜率略高于50%。单次可能亏,但做了几百次、几千次之后,大数定律保证你总体是赚钱的。
统计套利的核心特征
|--------|-----------|-------------|
| 特征 | 确定性套利 | 统计套利 |
| 风险 | 理论上无风险 | 有风险 |
| 收益率 | 低(竞争激烈) | 中等(5-15%年化) |
| 交易频率 | 极高(毫秒级) | 中等(日/周级别) |
| 资金需求 | 极高(杠杆大) | 中等 |
| 持仓时间 | 极短 | 数天到数月 |
| 核心能力 | 速度和基础设施 | 模型和研究能力 |
| 竞争者 | 高频交易公司 | 量化对冲基金 |
统计套利的收益来源
既然有风险,那赚的是什么钱?
三种:
1. 信息优势的钱
你比别人更快、更准地理解了信息。
比如,两家公司宣布合并。普通人看到新闻,只知道"合并了"。但你的模型告诉你,按照历史数据,这类合并的标的中,收购方的股价平均会在两周内上涨5%。
你提前买入,等市场消化完信息,你赚了。
2. 行为偏差的钱
你利用了别人的非理性行为。
比如,某只股票因为一个明显的假消息暴跌。你的模型识别出这是假消息,价格已经跌到了不合理的水平。你买入,等价格回归,你赚了。
3. 流动性差异的钱
你提供了流动性,赚取流动性溢价。
比如,某只小盘股因为流动性差,买卖价差很大。你挂单买入,等了两天才成交。但你赚了这个价差。
How:统计套利的三大策略类型
类型一:配对交易(Pairs Trading)
最经典的统计套利策略。
核心思想:找两只价格走势高度相关的股票。当它们的价格差偏离历史均值时,做多被低估的那个,做空被高估的那个。等价差回归,平仓获利。
// python
import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import coint, adfuller
def find_cointegrated_pairs(prices_df, significance_level=0.05):
"""寻找协整配对"""
n = prices_df.shape1
p_values = \[\]
pairs = \[\]
symbols = prices_df.columns
for i in range(n):
for j in range(i+1, n):
stock1 = prices_df.iloc:, i
stock2 = prices_df.iloc:, j
协整检验
score, p_value, _ = coint(stock1, stock2)
if p_value < significance_level:
pairs.append((symbolsi, symbolsj, p_value))
print(f"协整配对: {symbolsi} & {symbolsj}, p值={p_value:.4f}")
return pairs
def pairs_trading_signal(stock1_prices, stock2_prices, window=60, threshold=2.0):
"""配对交易信号生成"""
计算价差(使用对数价格比)
spread = np.log(stock1_prices) - np.log(stock2_prices)
计算滚动Z-Score
spread_mean = spread.rolling(window=window).mean()
spread_std = spread.rolling(window=window).std()
z_score = (spread - spread_mean) / spread_std
生成信号
signals = pd.Series(index=spread.index, dtype=float)
Z-Score > threshold → 价差偏高 → 做空stock1,做多stock2
signalsz_score \> threshold = -1
Z-Score < -threshold → 价差偏低 → 做多stock1,做空stock2
signalsz_score \< -threshold = 1
Z-Score在-0.5, 0.5之间 → 平仓
signals(z_score \> -0.5) \& (z_score \< 0.5) = 0
return signals, z_score
配对交易的关键:协整关系
不是随便两只股票就能做配对。必须是"协整"的------也就是说,它们的价格差是平稳的,会均值回归。
怎么判断?用协整检验 (Engle-Granger检验或Johansen检验)。
如果p值小于0.05,说明两只股票确实存在长期均衡关系,价差会回归。
类型二:因子套利(Factor Arbitrage)
基于多因子模型的统计套利。
核心思想:股票的收益可以被分解为多个"因子"的贡献。当某只股票的实际收益与因子模型预测的收益出现偏差时,就存在套利机会。
举个例子:
Fama-French三因子模型认为,股票的收益由三个因子决定:
• 市场因子(Market):大盘涨它就涨
• 规模因子(SMB):小盘股比大盘股收益高
• 价值因子(HML):价值股比成长股收益高
如果一只股票的实际收益,显著低于模型根据这三个因子预测的收益,那它可能被低估了------买入。反之卖出。
// python
def factor_model_arbitrage(returns_df, factor_returns_df, window=252):
"""基于因子模型的套利信号"""
from sklearn.linear_model import LinearRegression
signals = {}
for stock in returns_df.columns:
stock_returns = returns_dfstock.rolling(window).apply(lambda x: x.values)
滚动回归
model = LinearRegression()
model.fit(factor_returns_df, stock_returns)
预测收益 vs 实际收益
predicted = model.predict(factor_returns_df)
residual = stock_returns - predicted
残差的Z-Score
residual_mean = np.mean(residual)
residual_std = np.std(residual)
residual_z = (residual-1 - residual_mean) / residual_std
if residual_z > 2.0:
signalsstock = 'UNDERPRICED' # 实际收益远低于预测,可能被低估
elif residual_z < -2.0:
signalsstock = 'OVERPRICED' # 实际收益远高于预测,可能被高估
return signals
因子套利的关键:因子选择
用什么因子?这直接决定了策略的成败。
常用的因子包括:
• 价值因子:PE、PB、EV/EBITDA
• 动量因子:过去3-12个月的收益率
• 质量因子:ROE、毛利率稳定性
• 波动率因子:历史波动率、beta
• 流动性因子:换手率、买卖价差
类型三:事件驱动套利(Event-Driven Arbitrage)
利用特定事件造成的价格偏离获利。
核心思想:某些事件(如并购、财报发布、指数调整)会导致价格短暂偏离合理水平。在这些事件发生前后进行交易,可以获利。
常见的事件驱动策略:
并购套利(Merger Arbitrage)
当A公司宣布收购B公司时,B公司的股价通常会涨,但不会涨到收购价。为什么?因为市场担心交易可能失败。
如果你判断交易会成功,就可以在宣布后买入B公司,赚取收购价与当前价之间的差价。
// python
def merger_arbitrage_spread(acquirer_price, target_price, offer_price,
offer_type='cash', probability_of_success=0.85):
"""计算并购套利价差"""
if offer_type == 'cash':
现金收购:简单价差
spread = (offer_price - target_price) / target_price
expected_return = spread * probability_of_success
risk_return = (1 - probability_of_success) * (-target_price) / target_price
else:
换股收购:需要考虑比率
spread = offer_price - target_price
expected_return = spread * probability_of_success
return {
'spread': f"{spread:.2%}",
'expected_return': f"{expected_return:.2%}",
'annualized_return': '取决于交易完成时间'
}
指数调整套利(Index Rebalancing)
当某个指数宣布要纳入或剔除某只股票时,跟踪该指数的基金必须被动买入或卖出。
被纳入的股票:预计有大量被动买入 → 价格可能上涨 → 提前买入
被剔除的股票:预计有大量被动卖出 → 价格可能下跌 → 提前做空
财报事件套利
财报发布前后,股价经常过度反应。
• 如果公司连续几个季度都beat预期,市场可能对新财报过度乐观 → 可以做空
• 如果公司连续miss预期,市场可能对新财报过度悲观 → 可以做多
统计套利实操:一个完整的配对交易案例
为了让你更直观地理解,我们来跑一个完整的配对交易案例。
// python
def full_pairs_trading_example(stock1_data, stock2_data,
initial_capital=1000000,
window=60,
entry_threshold=2.0,
exit_threshold=0.5):
"""完整的配对交易回测"""
1. 协整检验
score, p_value, crit_values = coint(stock1_data, stock2_data)
print(f"协整检验 p值: {p_value:.4f}")
if p_value > 0.05:
print("两只股票不存在协整关系,不适合配对交易")
return None
2. 计算价差和Z-Score
spread = np.log(stock1_data) - np.log(stock2_data)
spread_mean = spread.rolling(window).mean()
spread_std = spread.rolling(window).std()
z_score = (spread - spread_mean) / spread_std
3. 生成交易信号
position = 0 # 0=空仓, 1=多stock1空stock2, -1=空stock1多stock2
portfolio_value = initial_capital
trades = \[\]
for i in range(window, len(z_score)):
z = z_score.iloci
开仓
if position == 0:
if z > entry_threshold:
position = -1 # 价差偏高,空stock1多stock2
trades.append({'date': i, 'action': 'OPEN_SHORT_SPREAD', 'z': z})
elif z < -entry_threshold:
position = 1 # 价差偏低,多stock1空stock2
trades.append({'date': i, 'action': 'OPEN_LONG_SPREAD', 'z': z})
平仓
elif position == 1 and z > -exit_threshold:
position = 0
trades.append({'date': i, 'action': 'CLOSE_LONG_SPREAD', 'z': z})
elif position == -1 and z < exit_threshold:
position = 0
trades.append({'date': i, 'action': 'CLOSE_SHORT_SPREAD', 'z': z})
4. 计算收益
total_trades = len(t for t in trades if 'OPEN' in t\['action'])
print(f"总开仓次数: {total_trades}")
print(f"最终净值: {portfolio_value-1:.0f}")
return {
'cointegration_p_value': p_value,
'total_trades': total_trades,
'final_value': portfolio_value-1,
'total_return': (portfolio_value-1 / initial_capital - 1) * 100
}
配对交易的注意事项
-
协整关系不是永恒的 :两个公司的业务关系可能变化,协整关系可能消失。要定期重新检验。
-
不要在极端行情中使用 :黑天鹅事件可能导致价格永久性偏离,协整关系崩溃。
-
交易成本很重要 :配对交易需要同时买卖两只股票,交易成本是单边策略的两倍。间距设得太小,利润会被手续费吃掉。
-
资金管理 :每对配对分配的资金不要超过总资金的20%。同时运行多对配对来分散风险。
总结
今天是第100篇,聊了一个量化交易中非常核心的话题------统计套利。
回顾一下核心要点:
-
统计套利的本质 :市场存在短期定价偏差,偏差会均值回归。你赚的就是这个回归的钱。
-
定价偏差的来源 :行为偏差(人的非理性)、流动性差异(大资金的冲击)、信息不对称(知道得早晚不同)。
-
统计套利 ≠ 无风险套利 :它是有风险的。你赌的是概率优势,单次可能亏,但大量交易后总体盈利。
-
三大策略类型 :
◦ 配对交易 :找协整的股票对,价差偏离时做多低估的、做空高估的
◦ 因子套利 :基于多因子模型,交易实际收益与预测收益的偏差
◦ 事件驱动 :利用并购、指数调整、财报等事件造成的价格偏离
-
关键前提 :均值回归。如果价格不回归,策略就失效了。所以一定要用统计检验(协整检验等)来验证。
-
实操要点 :定期重新检验、控制单对资金比例、考虑交易成本、避免极端行情。
100篇了。从最初的量化入门,到今天的统计套利,我们一起走过了量化交易的很大一部分版图。
下一期,我们继续深入统计套利------从因子到信号的完整建模流程。