
欢迎加入专注于财经数据与量化投研的【数据科学实战】知识星球!在这里,您将获取持续更新的《财经数据宝典》和《量化投研宝典》,这两部宝典相辅相成,为您在量化投研道路上提供明确指引。 我们提供了精选的国内外量化投研的 250+ 篇高质量文章,并每日更新最新研究成果,涵盖策略开发、因子分析、风险管理等核心领域。 无论您是量化投资新手还是经验丰富的研究者,星球社区都能帮您少走弯路,事半功倍,共同探索数据驱动的投资世界!
在现代金融市场中,传统的主观交易正逐渐被算法交易所增强甚至取代。量化交易系统通过数学模型识别市场中稍纵即逝的低效机会,以超越人类能力的速度和规模处理海量数据。本文将深入讲解两种经典的量化策略:均值回归(配对交易)和纯套利(跨交易所套利),并通过 Python 代码带你一步步实现从数据获取、统计检验到信号生成的完整流程。
均值回归策略的核心假设是:两只历史上高度相关的股票,当价格关系出现异常偏离时,未来会回归到正常水平。就像一根被拉伸的橡皮筋,拉得越远,反弹的力量越大。
交易方式:
首先,我们需要获取多只股票的历史价格数据:
import pandas as pd
import yfinance as yf
from datetime import datetime
defget_historical_data(tickers):
"""获取多只股票的调整后收盘价"""
data = pd.DataFrame()
names = list()
for i in tickers:
# 下载指定时间范围的股票数据
downloaded = yf.download(i, start=datetime(2020, 10, 27), end=datetime(2021, 10, 27))
# 提取调整后收盘价(考虑了分红和拆股)
data = pd.concat([data, downloaded['Adj Close']], axis=1)
names.append(i)
data.columns = names
return data
# 定义股票列表
ticks = ["DPZ", "AAPL", "GOOG", "AMD", "GME", "SPY", "NFLX", "BA", "WMT", "BRK-B", "MSFT", "NKE"]
d = get_historical_data(ticks)
print(d.shape) # 查看数据维度
d.tail() # 查看最新数据
为什么使用调整后收盘价? 因为它已经考虑了公司的分红派息和股票拆分等行为,能够真实反映投资者的实际收益情况,避免在计算价差时产生虚假的跳跃。
接下来,计算股票之间的相关性矩阵,并用热力图可视化:
import seaborn as sn
from matplotlib.pyplot import figure
# 计算相关性矩阵
corr_matrix = d.corr()
# 绘制热力图
figure(figsize=(8, 6), dpi=200)
sn.heatmap(corr_matrix, annot=True)
相关性矩阵帮助我们快速筛选出历史上走势相近的股票对。一般而言,相关系数大于 0.8 的配对值得进一步研究。但需要注意:高相关性只是必要条件,不是充分条件。
找到高相关性的股票对后,需要进行协整检验来验证它们的价差是否具有均值回归特性:
import statsmodels.tsa.stattools as ts
from statsmodels.tsa.stattools import adfuller
# 选取伯克希尔和微软作为候选配对
BRK_B = d['BRK-B']
MSFT = d['MSFT']
# 进行协整检验(Engle-Granger 两步法)
result = ts.coint(BRK_B, MSFT)
p_val = result[1]
print(f'协整检验 P 值:{p_val}')
print('当 P 值 < 0.05 时,说明两个序列存在协整关系')
# 对价差进行 ADF 平稳性检验
spread = BRK_B - MSFT
spread_adf = adfuller(spread)
print(f'价差的 ADF 检验 P 值:{spread_adf[1]}')
协整的含义: 虽然两只股票的价格各自都是非平稳的(会随机游走),但它们的某种线性组合(价差)却是平稳的,会围绕均值波动。这正是均值回归策略的理论基础。
当价差被证明是平稳的,我们可以用 Z 分数来衡量当前偏离程度:
import matplotlib.pyplot as plt
# 计算价格比率
ratio = BRK_B / MSFT
# 计算滚动均值和标准差
ratios_mavg5 = ratio.rolling(window=5).mean() # 5 日均线
ratios_mavg20 = ratio.rolling(window=20).mean() # 20 日均线
std_20 = ratio.rolling(window=20).std() # 20 日滚动标准差
# 计算 Z 分数
zscore_20_5 = (ratios_mavg5 - ratios_mavg20) / std_20
# 绘制 Z 分数及交易阈值
figure(figsize=(8, 6), dpi=200)
zscore_20_5.plot()
plt.axhline(0, color='black') # 均值线
plt.axhline(1, color='red', linestyle='--') # 上阈值
plt.axhline(-1, color='green', linestyle='--') # 下阈值
plt.legend(['Z 分数', '均值', '+1', '-1'])
plt.title('BRK-B / MSFT 比率的 Z 分数')
plt.show()
交易规则:
figure(figsize=(8, 6), dpi=200)
ratio.plot()
# 创建买入信号(Z 分数 <= -1)
buy = ratio.copy()
buy[zscore_20_5 > -1] = 0
# 创建卖出信号(Z 分数 >= 1)
sell = ratio.copy()
sell[zscore_20_5 < 1] = 0
# 绘制信号点
buy.plot(color='g', linestyle='None', marker='^')
sell.plot(color='r', linestyle='None', marker='v')
plt.legend(['比率', '买入信号', '卖出信号'])
plt.title('BRK-B 与 MSFT 的交易信号')
plt.show()
纯套利是指在不同交易所之间,利用同一资产的价格差异进行无风险获利。操作逻辑很简单:在价格低的交易所买入,同时在价格高的交易所卖出。
import pandas as pd
import numpy as np
# 从 Excel 读取两个交易所的 BTC 价格数据
gemini = pd.read_excel('BTCPrices.xlsx', sheet_name='Gemini')
reuters = pd.read_excel('BTCPrices.xlsx', sheet_name='Reuters')
# 设置时间索引
gemini = gemini.set_index("Date (EST)")
reuters = reuters.set_index("Time")
# 提取开盘价
gem_BTC = gemini['Open']
reu_BTC = reuters['Open']
from matplotlib.pyplot import figure
# 绘制两个交易所的价格对比
figure(figsize=(8, 4), dpi=200)
plt.plot(gem_BTC, label="Gemini BTC")
plt.plot(reu_BTC, label="Reuters BTC")
plt.title('BTC 开盘价对比')
plt.legend()
# 绘制价差的绝对值
figure(figsize=(8, 4), dpi=400)
plt.plot(abs(gem_BTC - reu_BTC), label="价差 |Gemini - Reuters|")
plt.title('两交易所价差')
plt.legend()
真正的套利必须扣除交易费用后仍有利润:
# 构建综合分析表
# 假设平均交易费率为 0.2%(买卖各 0.1%)
comb_df = pd.concat([
gem_BTC,
reu_BTC,
abs(gem_BTC - reu_BTC), # 绝对价差
0.002 * (gem_BTC + reu_BTC) # 总交易成本
], axis=1)
comb_df.columns = ["Gemini_Open", "Reuters_Open", "Absolute_Difference", "Total_Tax"]
# 生成交易方向信号
# 0 表示在 Gemini 卖出、在 Reuters 买入
v = pd.DataFrame(np.where(comb_df["Gemini_Open"] > comb_df["Reuters_Open"], 0, 1))
v.index = comb_df.index
v.columns = ["Direction"]
comb_df = pd.concat([comb_df, v], axis=1)
# 生成执行信号:只有当价差大于交易成本时才执行
# 0 表示执行,1 表示不执行
order = pd.DataFrame(np.where(comb_df["Absolute_Difference"] > comb_df["Total_Tax"], 0, 1))
order.index = comb_df.index
order.columns = ["Execute"]
comb_df = pd.concat([comb_df, order], axis=1)
# 查看执行信号分布
print(np.unique(comb_df["Execute"], return_counts=True))
# 筛选出所有可执行的套利机会
orders_fulfilled = comb_df.loc[comb_df["Execute"] == 0]
# 计算总利润(价差减去交易成本)
total_profits = sum(orders_fulfilled["Absolute_Difference"] - orders_fulfilled["Total_Tax"])
print(f'扣除费用后的总利润:${total_profits:.2f}')
本文详细介绍了两种经典的量化交易策略。均值回归策略通过统计检验识别具有协整关系的股票对,利用价差的均值回归特性进行交易。跨交易所套利则通过监控同一资产在不同市场的价格差异,在扣除交易成本后捕捉无风险利润。
无论采用哪种策略,成功的关键在于:严谨的统计检验、完善的成本模型、以及稳健的风险管理。希望本文能为你的量化交易之路提供有价值的参考。
核心权益如下:
星球已有丰富内容积累,包括量化投研论文、财经高频数据、 PyBroker 视频教程、定期直播、数据分享和答疑解难。适合对量化投研和财经数据分析有兴趣的学习者及从业者。欢迎加入我们!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用
9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解
好书推荐