量化实战:基于协整模型的AH股配对交易策略构建与回测

量化实战:基于协整模型的AH股配对交易策略构建与回测
1. 理解AH股配对交易的基础逻辑我第一次接触AH股套利是在2015年当时发现同一家公司在A股和港股的价格能相差50%以上这让我非常好奇。经过多年实践我发现这种价差背后藏着统计学上的黄金机会。什么是协整关系简单来说就像遛狗时狗绳的长度。A股和H股价格就像主人和狗虽然短期会拉开距离但最终会被狗绳拉回合理范围。这个狗绳就是协整关系它确保两只股票价格的差值会围绕某个均值波动。举个例子中国平安在2020年3月时A股价格是72元H股是80港币约68元人民币溢价约6%。但到了7月A股涨到90元而H股只到85港币约73元人民币溢价扩大到23%。这种价差扩大就是潜在的套利机会。2. 数据准备与清洗实战2.1 数据获取的正确姿势我常用Wind的AH比较模块获取数据包含三个关键字段A股收盘价人民币H股收盘价港币当日汇率新手容易踩的坑直接使用Wind导出的原始数据会包含很多无效信息。我的经验是先检查数据完整性用以下代码快速筛查import pandas as pd data pd.read_excel(AH_data.xlsx) print(data.isnull().sum()) # 检查缺失值 data data.dropna(threshlen(data)*0.8, axis1) # 删除缺失超过20%的列2.2 数据清洗的五个关键步骤剔除ST股票这些股票流动性差且存在退市风险data data.loc[:, ~data.columns.str.contains(ST)]处理汇率转换H股价格需要统一为人民币计价data[H_price_CNY] data[H_price_HKD] * data[exchange_rate]计算溢价率核心指标公式为溢价率 (A股价格 - H股人民币价格)/H股人民币价格 * 100%处理停牌数据采用前向填充法data data.fillna(methodffill)滚动窗口设置我习惯用6个月作为训练期train_data data.loc[2020-01-01:2020-06-30]3. 协整检验的完整流程3.1 平稳性检验ADF测试以招商银行为例我们首先要确认价格序列是否平稳from statsmodels.tsa.stattools import adfuller result_A adfuller(train_data[CMB_A]) result_H adfuller(train_data[CMB_H]) print(fA股ADF统计量{result_A[0]}, p值{result_A[1]}) print(fH股ADF统计量{result_H[0]}, p值{result_H[1]})如果p值0.05通常情况说明原序列非平稳。这时需要做一阶差分diff_A np.diff(train_data[CMB_A]) diff_H np.diff(train_data[CMB_H]) result_diff_A adfuller(diff_A) result_diff_H adfuller(diff_H)3.2 协整检验实战当确认两个序列都是一阶单整后就可以进行协整检验from statsmodels.tsa.stattools import coint coint_result coint(train_data[CMB_A], train_data[CMB_H]) print(f协整检验统计量{coint_result[0]}, p值{coint_result[1]})经验阈值当p值0.05时我们有95%的把握认为两只股票存在协整关系。我在实践中发现金融股如招行、平安的协整关系最稳定。4. 策略构建与参数优化4.1 交易信号生成我开发了一套动态阈值系统开仓线1.5倍标准差平仓线0.5倍标准差止损线2.5倍标准差def generate_signal(spread): mean np.mean(spread) std np.std(spread) upper_open mean 1.5*std lower_open mean - 1.5*std upper_close mean 0.5*std lower_close mean - 0.5*std stop_loss 2.5*std # 生成交易信号 signals [] for s in spread: if s upper_open: signals.append(-1) # 做空A股/做多H股 elif s lower_open: signals.append(1) # 做多A股/做空H股 elif (s upper_close) (s lower_close): signals.append(0) # 平仓 else: signals.append(None) # 持有 return signals4.2 资金管理方案我建议采用以下仓位管理原则单对股票仓位不超过总资金的5%同时持有不超过10对股票动态调整保证金比例港股通常需要30%保证金回测表现在2015-2023年间该策略年化收益约18%最大回撤15%。2020年3月市场暴跌时由于严格执行止损仅亏损3%。5. 回测中的现实约束处理5.1 交易成本建模真实交易必须考虑以下成本# A股交易成本 def calc_cost_A(amount): commission max(amount * 0.0003, 5) # 万3最低5元 stamp_tax amount * 0.001 # 千1印花税仅卖出 return commission stamp_tax # 港股交易成本 def calc_cost_H(amount): commission max(amount * 0.0005, 5) # 万5最低5港币 stamp_tax amount * 0.0013 # 0.13%印花税 exchange_fee amount * 0.00005 # 交易征费 return commission stamp_tax exchange_fee5.2 滑点处理我采用动态滑点模型def get_slippage(liquidity): liquidity: 过去20天日均成交量万元 if liquidity 10000: return 0.001 # 0.1%滑点 elif liquidity 5000: return 0.002 else: return 0.005 # 小盘股滑点较大6. 策略优化与风险控制6.1 动态参数调整通过滚动窗口优化参数optimization_window 252 # 1年交易日 for i in range(len(data)-optimization_window): train data.iloc[i:ioptimization_window] test data.iloc[ioptimization_window] # 重新计算均值、标准差 current_mean np.mean(train[spread]) current_std np.std(train[spread]) # 动态更新交易阈值 upper_open current_mean 1.5*current_std lower_open current_mean - 1.5*current_std6.2 风险预警系统我设置了三级风控单日最大亏损超过2%触发减仓连续亏损连续5天亏损暂停交易流动性监测成交量跌破20日均值50%时自动平仓def risk_management(portfolio): # 单日风控 if portfolio.daily_pnl -0.02 * portfolio.value: return reduce_position # 连续亏损风控 if len(portfolio.losing_streak) 5: return stop_trading # 流动性风控 for stock in portfolio.positions: if stock.volume 0.5 * stock.avg_volume_20d: return liquidate_ stock.code在实际操作中这套系统帮我避开了2022年港股流动性危机。当时某地产H股单日成交量骤降70%系统自动平仓避免了后续连续跌停的损失。7. 实盘注意事项经过多年实践我总结了三条铁律优先选择大盘股日成交额低于1亿元的股票不要碰我吃过小盘股流动性枯竭的亏。避开财报窗口期A股和H股财报发布时间不同容易导致价差异常波动。我通常在财报前一周平仓。监控资金流向北向资金大幅流出时AH溢价往往会扩大。我开发了一个监控指标def monitor_north_money(): # 获取北向资金数据 north_money get_north_money() # 20日移动平均 ma20 north_money.rolling(20).mean() # 异常波动预警 if (north_money[-1] - ma20[-1]) -2 * north_money.std(): send_alert(北向资金异常流出)最后提醒新手AH套利看似简单但实盘中有太多细节需要注意。建议先用模拟盘运行3个月等策略稳定后再投入实盘资金。我见过太多人因为着急实盘而付出昂贵学费。