通过配对交易中的均值回归进行统计套利:用数学战胜市场(基础篇)
📘

通过配对交易中的均值回归进行统计套利:用数学战胜市场(基础篇)

第 1/2 篇

「用配对价差抓均值回归的统计套利思路」

统计套利不赌单边方向,而是找两只高度相关、价差长期围绕均值波动的品种,等价差偏离到统计边界时反向建仓,赌它回归。外汇与贵金属市场波动剧烈、杠杆风险高,这种策略只是把「方向判断」换成「相对价差偏离」,并不能消除爆仓可能。 实操上先在 MT5 里挑 EURUSD 与 GBPUSD 这类同属欧系、小时图相关系数常年在 0.85 以上的货币对。算出两者价差序列的滚动均值与标准差,当价差突破 ±2σ 时视为小概率偏离,倾向开「多弱空强」的组合单。 下面这段 MQL5 片段演示了如何用 iMA 取两条均线的差值来近似价差中枢,读者可直接粘进指标文件改周期验证。

MQL5 / C++
class="type">class="kw">double spread = iMA("EURUSD",PERIOD_H1,class="num">1,class="num">0,MODE_SMA,PRICE_CLOSE,class="num">0)
           - iMA("GBPUSD",PERIOD_H1,class="num">1,class="num">0,MODE_SMA,PRICE_CLOSE,class="num">0);
class="type">class="kw">double mean = iMAOnArray(spread_array,class="num">0,class="num">20,class="num">0,MODE_SMA,class="num">0);
class="type">class="kw">double sigma = MathStdDev(spread_array,class="num">0,class="num">20);

散户也能碰的统计套利起点

牛顿晚年因炒股几乎赔光退休储蓄,留下那句关于「算不出人类疯狂」的感叹,说明市场不是纯物理系统。去年5月10日吉姆·西蒙斯离世,这位微分几何与密码学背景的数学家,用文艺复兴科技把「市场可被数学战胜」变成了现实。 大奖章基金1988—2018年年均回报约66%,三十年累计交易利润超1040亿美元,策略核心西蒙斯只肯说「投资组合层面的统计套利」加「一种机器学习」,细节至今是企业最高机密。 普通人没顶尖数学团队确实难复刻,但理解原理并从小处搭起轻量版统计套利完全可行。本文不碰人家的秘密配方,只分享通用驱动逻辑,让普通MT5用户用消费级笔记本就能验证。 接下来会先用最直接设置描述流程,再建最小投资组合、用智能交易系统自动化跑、记结果、想后续。目标就是给你一套低成本可改的分析方法,外汇与贵金属波动剧烈、杠杆高风险大,统计套利只降概率不消除风险,跑之前先开MT5自测。

◍ 把市场当谜题,而非可破解的密码

吉姆·西蒙斯在创立文艺复兴科技前做过密码破译,但用预测思维做交易屡败,后来转向一个底层假设:永远无法预测市场未来,只能把市场当谜题。这谜题没有图灵机那种可逆向工程的确定性算法——央行加息本应推升本币,但遥远国家突发政治冲突可能反向抵消,让加息失效甚至令货币走弱。 输入与输出之间夹着经济主体的非理性、政治不可预见性与混沌互动。长达一年的黄金牛市和下周的一个月暴跌之间,隔的就是人类行为;卡尼曼拿诺贝尔经济学奖正是因戳破理性人假设。即便如此,投行仍用金融模型、对冲基金仍用布莱克-斯科尔斯估期权,量化策略年耗数百万美元,原因是它有效。 西蒙斯给的答案是:交易成功不在于永远正确,而在于最大化收益、最小化损失。这条真理早于本间宗久的蜡烛图就已存在,本质就是风险管理。但任何策略只在一段未知时长内有效——可能盈利一天、一个月或一年,唯一保证是过去在那些品种、周期和参数下盈利;它下一分钟就失效或永远有效,我们都无法知道,因为市场无密码可破,只有持续变化。 市场唯一不变的就是变化本身。我们选参数值,不是适配某市场状态,而是适配特定变化。一张盈利单和平仓之间市场按预期变,亏损单则按未预期变,我们永远无法精确定位是哪个变化翻转了策略盈亏。老手花数月交易同资产,是为找模式、提升下次类似变化中做对的概率;交易日记就是记预期变化假设、事后复盘改假设用的。 现在海量数据加算力,能把找模式的学习年限压到几小时:自动采集、回测、执行,甚至训练机器学习挑品种和策略。但本系列面向普通散户,记住这两点被忽视的原则,后续才能看清统计套利到底是什么。

「从黄金交叉报价里筛出可套利对」

做统计套利组合,第一步不是拍脑袋选品种,而是先圈一个子集。MT5 终端里可选品种常过万,写稿时账户报出 10563 个,逐个算关系不现实。用 Python 接 MT5,先把名字带 XAU 的拉出来,实测有 6 个:XAUUSD、XAUEUR、XAUAUD、XAUG、XAUCHF、XAUGBP;其中 XAUG 是 ETF,先剔除,剩 5 个外汇黄金报价做候选。 取最近一年约 250 个 D1 收盘价,算它们与 XAUUSD 的皮尔逊系数:XAUEUR 0.969、XAUAUD 0.967、XAUGBP 0.905、XAUCHF 0.842。单看系数会误以为价差天然窄,但把 XAUEUR 按当日 EURUSD 折成美元再比,真实年平均差约 5.9 美元、标准差 6.2 美元——这才是能触发交易的异常空间。 别把价格相关性当圣经。皮尔逊系数统计上要求平稳序列,而价格是非平稳的,直接算容易出“伪相关”。货币对里长期不回归均值算例外,但商品、股票里很常见,所以做回归均值类策略,止损和入场时机是强制项,外汇贵金属本身杠杆高、风险大。 触发阈值怎么定?样本异常值少就用均值,有极端峰(比如大数据新闻)就用中位数抗干扰。这里选均值,价差扩超均值 50% 时动手:价高的那个算走强、价低的算走弱,同步空强多弱。下面这段是上面筛选与折算的代码骨架,可直接在 MT5+Python 环境跑。

MQL5 / C++
print("Total symbols =",mt5.symbols_total()) # display all symbols
Total symbols = class="num">10563
# get symbols containing XAU in their names
xau_symbols=mt5.symbols_get("*XAU*")
print(&class="macro">#x27;len(*XAU*): &class="macro">#x27;, len(xau_symbols))
for s in xau_symbols:
    print(s.name)
len(*XAU*):  class="num">6
XAUUSD
XAUEUR
XAUAUD
* XAUG
XAUCHF
XAUGBP
# get class="num">250 D1 bars from the current day
xauusd_rates = mt5.copy_rates_from_pos("XAUUSD", mt5.TIMEFRAME_D1, class="num">0, class="num">250)
xaueur_rates = mt5.copy_rates_from_pos("XAUEUR", mt5.TIMEFRAME_D1, class="num">0, class="num">250)
xauaud_rates = mt5.copy_rates_from_pos("XAUAUD", mt5.TIMEFRAME_D1, class="num">0, class="num">250)
xauchf_rates = mt5.copy_rates_from_pos("XAUCHF", mt5.TIMEFRAME_D1, class="num">0, class="num">250)
xaugbp_rates = mt5.copy_rates_from_pos("XAUGBP", mt5.TIMEFRAME_D1, class="num">0, class="num">250)
(...)
# calculate correlation coefficients
class="kw">import numpy as np
usd_eur_corr = np.corrcoef(xauusd_close[&class="macro">#x27;close&class="macro">#x27;], xaueur_close[&class="macro">#x27;close&class="macro">#x27;])
usd_aud_corr = np.corrcoef(xauusd_close[&class="macro">#x27;close&class="macro">#x27;], xauaud_close[&class="macro">#x27;close&class="macro">#x27;])
usd_chf_corr = np.corrcoef(xauusd_close[&class="macro">#x27;close&class="macro">#x27;], xauchf_close[&class="macro">#x27;close&class="macro">#x27;])
usd_gbp_corr = np.corrcoef(xauusd_close[&class="macro">#x27;close&class="macro">#x27;], xaugbp_close[&class="macro">#x27;close&class="macro">#x27;])
adjusted_for_dollars = pd.concat([xauusd_close, xaueur_close[&class="macro">#x27;close&class="macro">#x27;], eurusd_close[&class="macro">#x27;close&class="macro">#x27;]], join=&class="macro">#x27;inner&class="macro">#x27;, axis=class="num">1)
adjusted_for_dollars.columns = [&class="macro">#x27;time&class="macro">#x27;, &class="macro">#x27;xauusd&class="macro">#x27;, &class="macro">#x27;xaueur&class="macro">#x27;, &class="macro">#x27;eurusd&class="macro">#x27;]
adjusted_for_dollars[&class="macro">#x27;xaueur_dollars&class="macro">#x27;] = adjusted_for_dollars[&class="macro">#x27;xaueur&class="macro">#x27;] * adjusted_for_dollars[&class="macro">#x27;eurusd&class="macro">#x27;]
adjusted_for_dollars[&class="macro">#x27;diff&class="macro">#x27;] = abs(adjusted_for_dollars[&class="macro">#x27;xauusd&class="macro">#x27;] - adjusted_for_dollars[&class="macro">#x27;xaueur_dollars&class="macro">#x27;])

常见问题

建议准备可覆盖两笔反向头寸保证金且能扛20%价差的闲置资金,太小易被手续费和滑点吃掉利润。
先算历史价差协整性,挑p值小于0.05且半衰期小于20交易日的对,再用滚动窗口看价差是否稳定回中轨。
小布可自动计算交叉报价的协整与半衰期,并实时标注价差偏离带,打开对应品种页即可直接看。
降低单边敞口、把仓位切到更小周期网格,或暂停该对只留预警,别硬扛趋势行情。
可能宏观利差或供需结构变了,协整已破裂,应先重测协整再决定是否平仓退场。