简介:《量化CTA策略:理念、框架与实战》是一份面向量化投资研究者、CTA策略学习者与资产配置从业者的专题PDF,系统梳理管理期货策略的理念、研究框架与实战要点,适合用于策略入门、投研参考和组合配置思路整理。包内仅含1个PDF文件,压缩包约1.58MB,篇幅完整、结构清晰,便于集中阅读与检索。目前已有781人学习下载。内容从CTA策略概况与收益来源切入,讨论其与量化指增及中性策略的低相关性、不同CTA子策略之间的低同质性,并展开趋势跟踪、统计套利、高频交易等类型;同时比较主观CTA与量化CTA在信息优势、数据解构和仓位管理上的差异,说明按交易频率划分的超高频、日内、中高频、低频特征。文中还强调研究体系与风控体系是策略难点,分析趋势戛然而止、波动掩盖趋势等适应环境问题,并提示模型失效风险。
1. 量化CTA的低相关性不是巧合:一个容量最小的策略,为什么成了配置里的必选项
国内期货市场容量小、参与者以专业机构为主、定价有效性高,做量化CTA策略的难度并不低,产品规模也远不及指数增强和市场中性。但恰恰是这个坐冷板凳的品类,几乎是所有多策略组合里绕不开的一环。原因不在收益率,而在于它和其他策略之间那条几乎拉不起来的低相关性:把CTA加进组合,净值曲线会明显变顺,回撤被削平。这种低相关性并不是统计上的偶然,它由交易标的、策略类型和收益来源三件事共同决定。搞懂这三个层面是怎么咬合的,比记住一堆净值指标更有用。
2. 趋势跟踪的收益引擎:为什么三成胜率的策略能活下来
2.1 右偏分布:趋势策略交易的对象是波动率,并非方向预测
很多人第一次看趋势跟踪策略的成交记录会皱眉:胜率只有三成出头,大部分交易小亏离场,看起来像在无效交易。但把逐笔盈亏画成直方图就会发现,分布是明显右偏的——亏损端被截断在很小的区间,盈利端拖着一条长尾。少数几笔大盈利覆盖掉全部小亏还有富余,这就是低胜率、高盈亏比的来源。
这个特征决定了趋势跟踪真正的收益引擎:它更像一个长期做多波动率的模型,靠价格在时间序列上的自相关性获利,并非去预测明天涨还是跌。对长期上行的资产来说,趋势策略往往跑不赢标的自身收益,但它能大幅提高收益回撤比、减少整体收益波动,同时资金使用效率更高。容量上,它只受标的容量和流动性的约束,不像高频那样被交易系统卡死。行为金融学给出的解释是:价格对信息的反应存在系统性迟滞,这种迟滞不会因为套利资金变多而立刻消失,这是趋势策略能长期存活的底层依据。
2.2 趋势的三段生命周期:反应不足、正反馈、回归基本面
把趋势拆开看,它并不是一条平滑的斜线,而是由三类不同的市场行为接力完成的。理解这三段,才能理解趋势策略为什么在有些行情里反复被打脸,在另一些行情里却能吃满。
| 阶段 | 主导机制 | 价格表现 | 对策略的含义 |
|---|---|---|---|
| 形成 | 锚定效应、处置效应、机械再平衡、交易摩擦 | 反应不足,趋势缓慢启动 | 信号反复,容易连续小亏 |
| 延续与过度反应 | 羊群效应、确认偏差、资金流正反馈 | 趋势加速,波动放大 | 持仓集中,盈亏比拉开 |
| 终结 | 基本面回归 | 反转或长期震荡 | 回撤集中出现,长尾在这里被削掉一截 |
形成阶段的核心是“反应不足”。投资者习惯把注意力放在最近的历史价格上,新信息来了也不愿意立刻调整观点;浮盈拿不住、浮亏不肯止损的处置效应,进一步拖慢了价格上涨和下跌的速度。还有一些非盈利性的机械操作,比如大型组合定期再平衡、机构在外汇和利率上的对冲盘,也会人为减缓趋势。交易摩擦越大,价格发现越慢,趋势的起点就越钝。
延续阶段靠的是正反馈。羊群效应让投资者主动向群体观点靠拢,确认偏差让人在趋势中不断自我暗示,表现好的基金拿到资金流入、表现差的被迫缩规模,这套资金流机制会把趋势进一步推过头。过度反应就是这么来的。
终结阶段没有太多花哨的机制,就是价格重新向基本面靠拢。趋势策略的右偏分布,本质上是在前两段里用小仓位试错、在后半段里用浮盈加仓换来的。很多人把趋势策略的回撤当成策略失效,其实右偏策略的常态就是“长时间小亏 + 短时间大赚”,用月度胜率去评价它,方向从一开始就错了。
2.3 用一段模拟看清分布:胜率、盈亏比、偏度要一起看
光看统计口径容易抽象,直接跑一段带趋势和噪声的价格序列,把双均线策略的逐笔交易统计出来,很多争论就清楚了。
import numpy as np def simulate_trend(prices, fast, slow): """双均线趋势策略:快线上穿慢线开多,下穿平仓。 prices: 价格序列(一维数组) fast/slow: 快慢均线窗口,决定交易频率 返回:逐笔交易的简单收益率数组 """ fast_ma = np.convolve(prices, np.ones(fast) / fast, mode="valid") slow_ma = np.convolve(prices, np.ones(slow) / slow, mode="valid") # 两条均线经过 valid 卷积后起点不同,取公共尾部对齐 n = min(len(fast_ma), len(slow_ma)) fast_ma, slow_ma = fast_ma[-n:], slow_ma[-n:] pos, entry, trades = 0, 0.0, [] for i in range(1, n): signal = 1 if fast_ma[i] > slow_ma[i] else 0 if signal == 1 and pos == 0: # 空仓转持多,记录开仓价 pos, entry = 1, prices[i] elif signal == 0 and pos == 1: # 持多转空仓,结算一笔交易 trades.append(prices[i] / entry - 1) pos = 0 return np.array(trades) # 构造一段带漂移和噪声的价格:漂移制造趋势,噪声制造假信号 rng = np.random.default_rng(7) rets = rng.normal(0.0004, 0.012, 3000) prices = 100 * np.exp(np.cumsum(rets)) trades = simulate_trend(prices, 10, 60) win_rate = (trades > 0).mean() # 胜率 payoff = trades[trades > 0].mean() / abs(trades[trades < 0].mean()) # 盈亏比 skew = ((trades - trades.mean()) ** 3).mean() / trades.std() ** 3 # 偏度 print(f"胜率={win_rate:.2%} 盈亏比={payoff:.2f} 偏度={skew:.2f}")这段代码里几个参数是有讲究的。mode="valid"避免卷积在边界做零填充,否则开头几根均线是假的;信号只用均线计算,不含任何未来数据;逐笔收益用简单收益率而不是对数收益,是为了后面算盈亏比时分子分母口径一致。fast=10, slow=60只是一组示例参数,把它改成 19/58,胜率和盈亏比会明显变化——这恰恰是规则模型的软肋:策略表现高度依赖参数选择,样本内调出来的漂亮数字,样本外经常原形毕露。
跑出来的典型结果是胜率三成多、盈亏比两倍以上、偏度为正。三个数字要连起来读:胜率低说明大部分时间在试错,盈亏比高说明试对一次能吃很久,偏度为正说明极端盈利的贡献远大于极端亏损。只盯胜率,就会得出“这个策略不行”的错误结论。
3. 时序模型的两条分岔路:规则模型欠拟合,预测模型过拟合
3.1 规则模型的先天约束:有限规则导致欠拟合,参数控制导致过拟合
规则模型是趋势跟踪的起点,双均线、通道突破、布林带都属于这一类。它们的优点是构建简单、技术门槛低、可解释性强,缺点也同样明确。
第一,规则模型只能判断标的变化的方向,不能给出变化幅度。这意味着仓位管理必须额外叠加一层模型,或者干脆靠人工控制。而仓位管理恰恰是CTA策略表现的重要变量,把这一块留给直觉,等于把一半的收益引擎交出去了。
第二,规则由人定义,人的认知边界就是规则的边界。规则数量有限,从整体策略角度看必然欠拟合,覆盖不了市场的全部状态;而单条规则的表现又高度依赖参数,从单体策略角度看又容易过拟合。这是一对很难调和的矛盾:想靠加规则提高覆盖率,规则之间的冲突和冗余会迅速膨胀;想靠调参数提高单策略表现,样本外衰减几乎不可避免。布林带策略用标准差倍数控制通道宽度、用均线周期控制中枢,两个参数一改,交易频率和盈亏结构全变,这就是参数敏感性的直观体现。
3.2 预测模型的流程:数据清洗、特征工程、拟合工程三段式
预测模型和规则模型最大的区别在于输出:前者不仅给出方向,还给出预期的变化幅度。这个“幅度”很关键,它让仓位可以直接由信号强度决定,不需要再外挂一层仓位模型。
整体生成流程和股票量化策略的处理方式有相似之处,大致分三段:数据清洗、特征工程、拟合工程。差别在三个地方——目标函数的设置、特征生成的偏好、拟合目标的选择。股票策略的标签通常是截面超额收益,CTA预测模型的标签是时序上的未来收益,而且必须做波动率归一化,否则不同品种、不同波动环境下的样本没法放在一起训练。特征上,CTA可用的原始维度比股票少得多,价格、成交量、持仓量、期限结构基本就是全部,特征构造的限制更紧。
有些产品在对外描述里会提到端到端方案,也就是把特征工程和拟合工程合并进一个神经网络里一起解决。这种做法省掉了人工特征设计,但对样本量和正则化的要求更高,在小样本场景下翻车的概率也更大。下图这类对比在业内很常见:预测模型发出的信号换手明显更高,既能捕捉大时间尺度上的价格波动,也能在震荡行情里靠小时间尺度的波动赚一点,而规则模型在震荡市里基本只能干等。
3.3 样本稀缺:CTA预测模型比股票模型更容易翻车
这是时序预测模型最容易被低估的难点。股票策略可选标的几千个,截面上一拉就是海量样本;CTA的品种数量少一个量级,时序上又只有一条价格序列,样本量天然稀缺。更麻烦的是标签构造方式会进一步放大这个问题。
# 时序预测的标签构造:未来H期收益,按波动率归一化 H = 20 # 预测周期,决定标签的“视野” vol_window = 60 # 波动率归一化窗口,让不同品种的标签可比 fwd_ret = close.shift(-H) / close - 1 # 未来H期收益 vol = close.pct_change().rolling(vol_window).std() * np.sqrt(H) label = fwd_ret / vol # 归一化后的回归目标 # 相邻样本共享 H-1 期的未来信息,名义样本量与有效样本量差距巨大 # 有效独立样本量 ≈ 名义样本量 / H,H=20 时缩水到二十分之一这段标签构造里有三个细节值得说清楚。shift(-H)是整段代码里唯一使用未来信息的地方,必须严格隔离在标签构造阶段,任何特征侧的前视都会让回测结果失真。除以波动率是为了让标签可比:同样 5% 的涨幅,在低波动品种上是强信号,在高波动品种上可能只是噪声。最容易被忽略的是重叠窗口——用滑动窗口每隔一天取一个样本,相邻样本的未来收益有 19 天是重叠的,名义上有几千个样本,有效独立样本可能只有几百个。在这种样本密度下训练复杂模型,过拟合几乎是必然的,这也解释了为什么CTA预测模型的门槛比股票模型更高。
反过来说,如果真能把时序预测模型做扎实,它是有机会包容截面模型和统计套利的——因为截面因子本质上也是时序信号的横截面组合,一个足够强的时序预测器可以把这些信息统一进同一个框架。这也是不少团队把预测模型当成终极目标的原因,只是这条路上的样本关、过拟合关,比想象中难过得多。
4. 截面与套利:同一条库存逻辑,两种完全相反的收益分布
4.1 截面因子:仓单、动量、期限结构背后是同一件事
横截面多因子模型的做法和股票多因子很像:用动量、偏度、期现结构等因子把一个标的池排序,得到相对强弱关系,然后双向开仓、做成市值中性。但搬过来之后会发现几个结构性差异。商品可选标的少,横截面的统计显著性天然存疑;所谓中性只做到了市值中性,没有股票那套风格和行业中性化的风控体系;品种之间的相关性在极端行情下会急剧上升,分散化效果打折,尾部风险甚至可能比单边暴露的策略更大。
不过相比时序策略那种偏艺术的发挥,截面模型至少有一套相对统一的研究范式。常见的因子大类里,仓单、动量、期限结构三条线其实指向同一个经济含义——库存。
仓单是交易所指定交割仓库签发的实物提货凭证。仓单大量生成,说明期货价格高于现货、空头交割意愿强,当前库存充足;仓单大量注销,说明现货紧张、多头占优。把升贴水大小排序,做空仓单增加的品种、做多仓单减少的品种,检验的就是库存紧张程度能不能转化为 alpha。
截面动量的逻辑是强者恒强:买入前期收益率高的品种、卖出前期收益率低的品种,赌品种间的相对强弱能延续。期限结构看的是近远月升贴水:远期高于近期是正向结构,对应库存充足;近期高于远期是反向结构,对应库存紧张。三条线的假设完全一致——库存紧的品种更容易继续涨,库存松的品种更容易继续跌。
# 截面动量因子:按过去N日收益率排序,多空各取两端 N = 20 ret = close.pct_change(N) rank = ret.rank(axis=1, pct=True) # 注意是横截面排序,不是时序排序 long_set = rank >= 0.8 # 前20%做多 short_set = rank <= 0.2 # 后20%做空 # 等权多空,权重和为0,天然市值中性 weights = long_set.astype(float) / long_set.sum(axis=1).values[:, None] \ - short_set.astype(float) / short_set.sum(axis=1).values[:, None] pnl = (weights.shift(1) * close.pct_change()).sum(axis=1) # 信号次日生效这里rank(axis=1)是横截面排序,如果误写成时序排序,整个因子含义就变了;weights.shift(1)保证 T 日收盘出信号、T+1 日才建仓,避免未来函数;等权多空让组合的市值暴露为零,但没有处理品种相关性和库存周期,这就是前面说的风控缺口。参数 N 决定动量周期,分位数决定多空宽度,两者都会显著影响换手和尾部风险。
4.2 统计套利:高胜率是表象,左偏尾部才是本质
统计套利的做法是同时交易两个或多个相关品种、双向开仓,赚价差回归的钱。按价差来源分,有期现、跨期、跨品种、跨市场几类。期现套利需要产业知识和现货信息,通常不在纯量化框架内;跨市场套利对时间效率要求极高,需要同时盯多个市场的交易数据;跨期和跨品种套利则演化出两种相对成熟的量化做法。
第一种是把调整过的价差曲线当成一个新标的,直接套用趋势跟踪或预测模型出信号。这种做法灵活,价差序列的构造方式可以按品种特性调整,但策略难度也更高,因为价差本身是加工出来的,加工方式一变,信号就全变。第二种是横截面多因子,把价差的各种统计特征做成因子,在多个价差组合之间排序配置。
统计套利的收益分布和趋势跟踪正好相反:胜率高、盈亏比低,分布左偏。大部分时候价差在历史区间内来回摆动,策略稳定赚小钱;一旦价差突破历史区间、收敛预期被打破,亏损会集中兑现,尾部风险比趋势策略更重。这也是为什么统计套利策略在评价时不能只看胜率和夏普,必须单独看价差突破历史极值时的最坏情况。趋势策略怕震荡,套利策略怕单边,两者的风险来源是对称的,放在同一个组合里才能互相抵消。
还有一类高频交易,做法素来不对外公开,能确定的是它对交易系统要求高、容量有限。如果按海外那种定义,赚的是买卖价差的钱,低延时约束下模型不可能太复杂,比的其实是工程能力和软硬件结合;如果泛指日内的 T+0 策略,研究方法和统计套利同源,只是换了时间尺度和目标函数。费率结构和保证金要求一变,这类策略的可行性会直接改写,这是它和低频策略最大的不同。
5. 量化CTA落地避坑:五个从净值曲线里看不出来的坑
5.1 数据与因子层面的三个坑
坑一:非交易因素让趋势戛然而止,模型还在按历史分布加仓。现象是某类期货品种在外部冲击下连续触及停板、流动性骤降,纯量化趋势模型仍在按历史统计继续加仓,净值单周大幅回撤。原因是归纳型模型只认价格和成交数据,这类冲击在历史样本里找不到对应分布;风控如果只看波动率,停板期间波动率反而是失真的。解决思路是在风控层加一道流动性闸门:成交量或持仓量骤降、连续同向停板时强制降杠杆,仓位上限和品种流动性挂钩,而不是和信号强度挂钩。
坑二:规则模型参数在样本内调得很漂亮,样本外直接失效。现象是双均线周期从 20/60 微调到 19/58,回测夏普从 1.2 跳到 1.6,实盘三个月掉回 0.6。原因是有限规则本身欠拟合,参数微调又引入过拟合,两头受挤压。解决思路是参数稳健性检验用滚动窗口做,看参数邻域的整体表现而不是单点最优;同时把仓位管理从规则里剥离出来单独建模,不要让一组参数同时承担方向和仓位的职责。
坑三:把股票多因子的风控假设直接搬到商品截面。现象是截面多空组合看起来是市值中性,遇到单边行情尾部回撤比单边策略还大。原因是商品可选标的少,横截面显著性弱;只做了市值中性,没有风格和行业中性那套风控;极端行情下品种间相关性急剧上升,分散化失效。解决思路是给组合加品种相关性和库存周期约束,极端行情主动降敞口;更重要的是把截面策略和时序策略做成组合,而不是单独押注截面。
5.2 组合与执行层面的两个坑
坑四:用胜率评价趋势策略,回撤一来就砍仓。现象是趋势策略胜率只有三成多,连续几个月小亏之后被要求降仓,刚降完仓就错过一波大趋势。原因是右偏分布决定了大部分交易小亏、少数交易贡献主要收益,用胜率和月度收益去评价会系统性误判。解决思路是评价指标换成收益回撤比、盈亏比和收益分布偏度,评价周期拉长到至少覆盖一轮完整的趋势周期,并且提前把回撤容忍度写进策略约束里,而不是等回撤发生了再临时决策。
坑五:忽视手续费、保证金和容量的变化。现象是回测里年化两位数的中高频策略,费率结构调整后收益直接腰斩。原因是中高频策略的 alpha 厚度本来就薄,对交易成本和保证金占用极其敏感;容量测算用的是历史流动性,没有考虑策略自身对市场的冲击。解决思路是回测里手续费和滑点按保守值打,不要用理想成交价;做容量压力测试,假设成交量下降三成策略还能不能活;把资金容量和品种流动性绑定,规模上去之后主动降频。
这五个坑有个共同点:它们都不会出现在净值曲线的表面,只会在特定市场状态下集中爆发。研究体系决定策略能不能赚钱,风控体系决定策略能不能活下来,后者的优先级其实更高。
6. 怎么判断一套CTA框架是不是真的能活:从收益归因到风控边界
CTA 策略最难讲清楚的一个概念是 alpha。指增策略的 alpha 可以定义为战胜基准的超额部分,口径清晰;CTA 的敞口在时序上并不稳定,杠杆倍数也未必可知,alpha 和 beta 的边界是模糊的。比较合理的拆法是把它分成两块:一块是预测收益,来自模型对方向的判断,性质接近指增的 alpha;另一块是趋势期间通过仓位管理获得的收益,性质更接近 beta,但如果管理人有能力在趋势确认后放大敞口,这部分也可以算作 alpha。这个拆分直接决定了一件事——评价一个 CTA 管理人,不能只看净值,要看净值的收益结构是怎么来的。
落到验证方法上,我会按下面几个维度去拆:
| 评价维度 | 具体看什么 | 为什么重要 |
|---|---|---|
| 净值结构 | 把曲线拆成趋势段和震荡段分别统计 | 混合统计会掩盖策略在不同市场状态下的真实表现 |
| 策略覆盖 | 时序、截面、套利是否都有成熟储备 | 单一策略类型的生命周期短,全覆盖才能平滑净值 |
| 因子储备 | 因子数量、分类逻辑、失效判定机制 | 因子会衰减,没有淘汰机制等于没有研究体系 |
| 风控边界 | 仓位上限是否与流动性挂钩、极端行情预案 | 决定极端行情下的生存能力,比收益率更关键 |
| 收益分布 | 偏度、盈亏比、最大回撤的持续时间 | 右偏和左偏策略不能用同一套指标评价 |
还有一个容易被忽略的维度是策略类型之间的低同质性。CTA 各策略类型之间的相关性低,这是由品种挑选和策略类型差异双重决定的,也是多策略组合能成立的基础。但低同质性也说明这个领域还没有形成统一的研究范式,策略表现里掺着管理人自身的经验、敞口偏好、杠杆控制和品种分配比例。对投资者来说,这意味着可以通过配置多个 CTA 管理人来平滑收益、分散风险,而不用太担心同质化带来的下行相关;对做策略的人来说,这意味着还有空间,但也意味着没有现成的标准答案可以抄。
最后说一个我自己的教训。早些年我看 CTA 产品,习惯先把年化、夏普、最大回撤拉一张表横向比,结果有两次被同一个问题绊倒:净值看起来差不多的两个产品,一个是靠少数几笔大趋势撑起来的右偏结构,另一个是靠高频次小盈利堆出来的左偏结构,放在同一个市场环境里,一个会横盘半年,一个会突然来一次深回撤。从那以后我每次看 CTA 框架,都强制先把净值按趋势段和震荡段拆开、把逐笔盈亏的分布画出来,再看因子储备和风控边界,顺序不能反。希望帮到你。
本文还有配套的精品资源,点击获取