gs-quant 实战:3 行核心代码跑通商品期货跨期价差回归套利回测
【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant
2024 年 3 月,某商品近月合约被现货抢购推高,对远月的溢价从 1% 拉到 5% 后迅速回落。价差回归策略赚的就是这段弹回的钱。这篇用 gs-quant 做一个商品期货套利的均值回归量化回测:价差信号、触发器、回测引擎,核心只有三行。
概念拆解:价差为什么倾向于回中
跨期价差可以想象成一根橡皮筋。近月和远月合约底层是同一件商品,季节性供需、交割成本变化会把两根价格"拉开",但只要两边基本面没有永久分叉,价差迟早缩回去。水位回中也是同一个道理:偏离足够远的时候进场,赌的是回归而不是方向。
策略逻辑不依赖代码就能说清楚,信号到动作的映射如下:
z 分数:价差偏离滚动均值多少个标准差。超过 ±2 就视为"橡皮筋拉过头"。
拿到近远月合约数据:安装、认证、拉价格三步走
Step 1:安装
一条命令装好依赖:
pip install gs-quant --upgradeStep 2:认证
gs-quant 的数据和计算都走远程 API,需要先初始化一个会话(凭据在 Marquee 开发者平台申请):
from gs_quant.session import GsSession # 替换为你自己的凭据 GsSession.use(client_id='your_client_id', client_secret='your_client_secret', scopes=('run_analytics',))Step 3:构造合约对象并拉历史价格
用FutureContract声明近月、远月两个合约,再从DAILY_BASIS数据集取日线收盘:
from gs_quant.markets.securities import FutureContract from gs_quant.data import Dataset # 合约 ID 以证券主数据实际为准,这里以黄金近月/远月为例 near_leg = FutureContract('GD-12-25', 'COMMODITIES', '黄金近月') far_leg = FutureContract('GD-06-26', 'COMMODITIES', '黄金远月') ds = Dataset('DAILY_BASIS') start, end = '2024-01-01', '2024-12-31' near_px = ds.get_data(start, end, assetId=(near_leg,))['close'] far_px = ds.get_data(start, end, assetId=(far_leg,))['close']合约对象的字段定义见 gs_quant/markets/securities.py。
构造价差 Z 分数信号,一条命令跑通回测
价差序列与 Z 分数
先算价差比率,再用 60 日滚动均值和标准差归一化。窗口长度决定"均值"代表什么:60 约等于一个季度,太长会迟钝,太短会把正常波动也当异常:
from gs_quant.timeseries.statistics import mean, std spread = near_px / far_px - 1 w = 60 z = (spread - mean(spread, w)) / std(spread, w) # Z 分数序列mean、std的实现见 gs_quant/timeseries/econometrics.py 所在的统计模块。
触发器:把规则交给内置的均值回归组件
gs-quant 自带MeanReversionTrigger:把价差序列喂给它,它按 z 的正负自动决定方向——z 高于阈值进空价差,低于阈值进多价差,价差回到均值时自动平仓。这就是那"三行核心"中的关键一行:
from gs_quant.backtests.triggers import MeanReversionTrigger, MeanReversionTriggerRequirements from gs_quant.backtests.data_sources import GenericDataSource from gs_quant.backtests.actions import AddTradeAction, ExitAllPositionsAction src = GenericDataSource(spread) trigger = MeanReversionTrigger( # 核心 1 MeanReversionTriggerRequirements(src, 2.0, 60, 60), # z 阈值 2,均值/标准差窗口 60 [AddTradeAction([near_leg, far_leg], name='gold_spread'), ExitAllPositionsAction()] )阈值2.0是进场的"橡皮筋拉伸上限";2.0偏保守、信号少而稳,1.5更激进、容易被震荡打脸。触发与动作定义见 gs_quant/backtests/triggers.py 和 gs_quant/backtests/actions.py。
回测:把策略丢给引擎按日推进
Strategy= 初始组合 + 触发器;初始组合传None表示空仓起步:
import datetime as dt from gs_quant.backtests.strategy import Strategy from gs_quant.backtests.generic_engine import GenericEngine strategy = Strategy(None, trigger) backtest = GenericEngine().run_backtest( # 核心 2 strategy, start=dt.date(2024, 1, 1), end=dt.date(2024, 12, 31), frequency='1d', show_progress=True ) summary = backtest.result_summary # 核心 3: dict[str, DataFrame]GenericEngine走 gs-quant 的风险 API 做逐日计算,是覆盖面最广的引擎,见 gs_quant/backtests/generic_engine.py。
读懂回测结果:年化、夏普、最大回撤该看什么
result_summary是按列名组织的 DataFrame 集合,累计现金列可以近似当组合净值。把三个最关键的指标一次打出来:
from gs_quant.timeseries.econometrics import sharpe_ratio, max_drawdown cash = summary['Cumulative Cash'] ret = cash.pct_change() print(f"年化 {ret.mean()*252:.1%} 夏普 {sharpe_ratio(ret).iloc[-1]:.2f} " f"最大回撤 {max_drawdown(cash).iloc[-1]:.1%}")📊 单看数字没意义,给个对照系:
| 指标 | 怎么读 | 参考阈值(单品种套利) |
|---|---|---|
| 年化收益 | 价差策略靠回归吃饭,别拿趋势策略的标准要求它 | 10%~25% 属合理区间 |
| 夏普比率 | 每单位波动能换多少收益,比绝对收益更可信 | 1.0 及格,2.0 优秀 |
| 最大回撤 | 最难受的那段跌了多少 | 控制在 10% 以内 |
如果夏普不低但回撤大,多半是阈值太紧、进场太频繁;反过来收益回撤都不动,说明 2σ 对这个品种太保守。
净值曲线一行代码就能画出来:
cash.plot(legend=False, title='价差回归策略净值曲线')避坑与调优:让均值回归 量化策略 更接近实盘
⚠️ 教学示例跑通不等于能上实盘,四个最常见的坑:
| 坑 | 处理办法 |
|---|---|
| 手续费和滑点吃掉价差收益 | 在AddTradeAction里传transaction_cost(如ConstantTransactionModel),进出场可分别设置;价差策略对成本极度敏感 |
| 固定 2σ 不适应波动率变化 | 用滚动波动率校准z_score_bound,或用timeseries.technicals里的指数波动率做动态边界 |
| 单品种黑天鹅(逼仓、政策) | 多品种各挂一套触发器并行回测,在组合层面看总风险而不是单策略收益 |
| 近月临近交割,价差序列跳变 | 回测中处理换月:在 roll 日重置价差基准,或改用连续拼接头寸 |
另外把窗口长度 30/60/120 各跑一遍做敏感性分析:参数在合理范围内结论稳定,策略才值得继续打磨;换个窗口就变号,说明赚的是噪音。
策略价值与边界
三行核心代码背后,gs-quant 把数据、信号、触发器、引擎拆成了可替换的组件:改阈值、换窗口、加新品种都是改参数而不是重写代码,这是均值回归这类策略快速迭代的正确姿势。
风险提示:本文策略仅作教学示例,不构成投资建议,实盘需自行承担风险。商品期货还有流动性、保证金和交割制度等现实约束,回测结果不代表未来表现。
想继续深入,建议看仓库内这两处:
- 回测入门教程:gs_quant/documentation/04_backtesting/tutorials/
- 文档总览:docs/index.rst
【免费下载链接】gs-quantPython toolkit for quantitative finance项目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考