量化CTA策略收益拆解:相关性、趋势跟踪与统计套利实践
简介:这份PDF聚焦量化CTA策略(管理期货策略)的理念、框架与实战,适合量化研究员、私募FOF配置人员及具备一定期货基础的投资者系统梳理策略脉络。内容从CTA的策略概况与功能切入,辨析主观CTA与量化CTA在数据解构、逻辑演绎上的差异,并按趋势跟踪、统计套利、高频交易等类型展开,进而讨论时序模型、截面模型与预测模型的研究体系,以及风控体系对策略生存能力的影响,同时点明趋势戛然而止、波动掩盖趋势等不适应环境与模型失效风险。资源包仅含1个PDF文件,大小约1.58MB,便于通读与归档查阅。已有778人学习下载。读者可借此建立从策略分类、收益来源、低同质性配置价值,到实战落地与风险提示的完整认知框架。
1. 相关性才是主线:一个小众策略凭什么进资产配置的核心
量化CTA策略常被贴上“期货趋势跟踪”的标签,很多人第一次看它的净值曲线会觉得平平无奇:没有指数增强那种陡峭的超额斜率,也不像中性策略那样把波动压得很低。但就是这样一个管理规模远不及股票量化的品类,几乎出现在所有多策略组合的必配清单里。原因不在收益,而在相关性结构——期货市场容量小、参与者以专业机构为主、有效性偏高,导致这个赛道很难卷出同质化,而它的收益又天然与其他策略错位。搞懂这件事的关键,是先把“它的钱从哪来”和“它为什么跟别人不一样”拆开看,否则你只会记住一堆策略名词,却解释不了它为什么能平滑净值。
2. 收益来源拆解:CTA 的 alpha 和 beta 为什么没法照搬指增那套定义
2.1 敞口不稳定,归因就先崩了一半
股票量化里谈 alpha 和 beta,前提是有一把相对稳定的尺子。指数增强的 beta 来自对基准的暴露,alpha 是剥离各类风险敞口之后剩下的部分;后来各家逐步放开风格与行业敞口,alpha 又被宽泛地定义为“战胜基准的超额”。中性策略更简单,对冲掉市场 beta,剩下的就是 alpha。这套话语之所以能成立,是因为基准明确、敞口可测、杠杆倍数相对固定。
把这套尺子搬到 CTA 上,第一刀就卡住了:CTA 的敞口在时序上并不稳定。一个趋势跟踪策略今天可能满仓做多黑色系,明天因为信号反转变成净空,后天又空仓等待;杠杆倍数随波动率、保证金、信号强度动态调整,历史区间里没有一个恒定的“beta 敞口”可以扣。你没法像指增那样问一句“这只产品暴露了多少小市值因子”,因为期货端根本没有一个被广泛接受的风格因子体系去承接这个问题。
目前能做的还只是定性拆解:把收益分成若干来源,然后观察哪一部分在解释净值。这也解释了为什么 CTA 的业绩归因材料普遍比股票量化粗——不是管理人不想做细,而是可用的锚点太少。
2.2 一条被忽略的线:做多波动率是 beta,趋势里加仓才是 alpha
把 CTA 的收益来源摊开,大致是两条主脉。第一条是做多市场波动率,典型代表就是趋势跟踪:标的走出趋势,策略跟随进场,赚的是趋势延续那一段的价格位移。这条脉络的性质其实接近 beta——你付的成本是震荡期的连续止损,换来的收益是趋势期的连续盈利。第二条是通过预测获得收益,靠模型对方向的判断精度赚钱,这是标准的 alpha,取决于模型能力。
真正值得琢磨的是第三块:如果管理人能在趋势期间放大策略敞口,那么这部分收益同样可以算作 alpha。同样是趋势跟踪,A 产品在趋势确认后维持原始仓位,B 产品在趋势确认后按信号强度加仓、按波动率调整杠杆,两者的 beta 部分相同,但 B 多出来的一块收益来自仓位管理能力,而不是来自市场给的行情。
这个判断带来一个很实际的推论:CTA 的 alpha 比指增更“多样化”,来源更分散。指增的 alpha 高度依赖因子挖掘与交易执行,同质化风险集中在这一处;CTA 的 alpha 至少分成预测精度和仓位管理两块,后者的天花板取决于研究体系对风险预算的理解,而不是算力和数据量的军备竞赛。这也部分解释了为什么 CTA 机构之间的业绩相关性长期偏低。
2.3 低同质性有两层,别只看其中一层
CTA 的低相关性不是一句话,它分两层,而且两层的原因完全不同。
第一层是跨机构之间的低相关。观察一批 CTA 产品的净值,2021 年那种高相关性主要出现在长周期趋势策略里,这是策略特性决定的:长周期信号变化慢,大家都跟着同一批品种的同一段趋势走,净值自然同步。但整体上,CTA 产品的相关性显著低于同期的指增产品。原因有两个:其一,CTA 至今没有形成统一的研究范式,各家在品种分配比例、子策略权重、敞口与杠杆控制上带着大量差异化选择,甚至掺入主观操作;其二,CTA 规模远小于股票量化,还没到“规模倒逼降频、降频导致特色消失”的阶段。
第二层是策略类型之间的低相关。时序模型、截面模型、统计套利、高频交易,方法论差异极大:时序模型看的是单个品种时间序列上的自相关,截面模型看的是同一时点品种之间的相对强弱,统计套利看的是价差收敛。它们的收益分布在形态上就不一样——趋势跟踪右偏、低胜率高盈亏比;统计套利左偏、高胜率低盈亏比。把这几类拼在一起,组合的净值曲线才会真正被磨平。
对照一下指增市场发生过的事,会更清楚这条逻辑的分量。规模快速扩张阶段,策略同质化的问题被规模增量掩盖:各家调仓标的和频率趋同,抢筹让平均超额衰减,但影响的只是收益增幅而非方向,此时比拼的是信号生成速度和算法交易能力。等到外部冲击导致相关板块调整、超额不及预期、资金流出,同质持仓又被进一步拖累,非预期因素引发的减仓让交易型因子的预测结果紊乱,超额就更难修复。这是一个典型的正反馈反转过程。
CTA 目前还没走到这一步。跨机构低相关意味着可以用多个管理人的产品来平滑收益,而不用担心一损俱损;策略类型之间的低相关意味着子策略融合真的能降低组合波动,而不是名义上分散、实际共用同一个动量信号源。下面这段代码是我做同类产品横向对比时的常用做法,滚动窗口算相关性,看同质性有没有在某个时间段突然抬升:
import pandas as pd def rolling_corr_matrix(nav_df, window=60, min_periods=40): """ nav_df: 行=日期, 列=产品/策略净值(已对齐交易日) window: 滚动窗口长度(交易日),60 约等于一个季度 min_periods: 最少有效样本,避免新发产品前期全是 NaN """ ret = nav_df.pct_change().dropna(how="all") # 净值转日收益 # 逐对计算滚动相关系数,返回 {产品对: 相关系数序列} out = {} cols = ret.columns for i in range(len(cols)): for j in range(i + 1, len(cols)): pair = ret[cols[i]].corr(ret[cols[j]]) # 全样本相关做基准 roll = ret[cols[i]].rolling(window, min_periods=min_periods).corr(ret[cols[j]]) out[(cols[i], cols[j])] = {"full": pair, "rolling": roll} return out def corr_regime_shift(corr_dict, threshold=0.6): """筛出滚动相关性长期高于阈值的产品对,这类组合的'分散'是伪分散""" flagged = [] for pair, v in corr_dict.items(): r = v["rolling"].dropna() if len(r) == 0: continue ratio = (r > threshold).mean() # 高相关时间占比 if ratio > 0.5: flagged.append((pair, v["full"], round(ratio, 2))) return flagged第一段用日收益而非净值做相关,是因为净值序列带趋势,直接算相关会被共同的上行趋势抬高,掩盖真实的同步性;滚动窗口取 60 个交易日,是为了让“同质性突然抬升”这种事件能在曲线上看出来,而不是被全样本平均值吃掉。第二段的阈值 0.6 和占比 0.5 是经验值:滚动相关有超过一半时间高于 0.6,基本可以判定这两个产品共享了同一个信号来源,把它们放进组合只是把仓位加倍,不是在分散风险。参数可以按策略频率调整——中高频策略的窗口该缩短到 20 日左右,否则信号噪声会被平滑掉。
3. 时序趋势跟踪:一套靠行为偏差活了几十年的机制
3.1 趋势的四段生命周期,每一段都有具体的非理性来源
趋势跟踪最容易被误解成“追涨杀跌的技术活”,但它的生命力来自一个更硬的东西:价格对信息的反应不是瞬间完成的,中间存在系统性的延迟和过度。这条逻辑可以拆成四段。
趋势形成阶段,价格反应不足。锚定效应让投资者把注意力锁在最近的历史价格上,新信息到来时观点调整缓慢;处置效应让人过早卖出浮盈、死扛浮亏,上涨和下跌的过程都被拉长;还有一类非盈利操作在机械地减缓价格反应,比如大型机构在外汇和利率市场的对冲操作本身就是为了压波动,再比如按固定比例再平衡的组合会机械地在涨了之后卖、跌了之后买。市场摩擦——交易成本、流动性约束——进一步拖慢价格发现。
趋势延续阶段,正反馈接管。羊群效应让投资者改变自己的判断去跟群体保持一致,这会加强趋势;确认偏差和代表性偏差让持仓者在趋势中不断自我暗示,强化信念;资金流是最直接的加速器,表现好的产品获得申购,规模扩张后被迫继续沿着原有方向配置,形成自我强化的循环。这三条叠在一起,趋势就从“反应不足的修正”变成了“过度反应”。
趋势结束阶段,价格回归基本面。这一段没有可靠的先行信号,也是趋势跟踪策略回撤的主要来源。
这四段结构解释了一个常被忽略的事实:传统趋势跟踪本质上不是一个预测模型,而是一个长期做多波动率的模型。它不预测趋势什么时候来,只保证趋势来的时候自己在场、震荡的时候亏损可控。所以它的容量只受标的容量和流动性约束,跟模型复杂度关系不大;收益分布呈现右偏——胜率低、盈亏比高,靠少数几笔大盈利覆盖大量小亏损。这一点在做资金曲线预期时特别重要:拿月度胜率去考核一个趋势策略,等于用错误的尺子量东西。
3.2 规则模型的天花板:欠拟合和过拟合同时发生
规则型策略是最经典的一类:双均线、通道突破、布林带。构建简单、技术门槛低,参数就那几个,任何人都能复现。但它的局限不是“不够先进”,而是结构性的。
第一条局限:规则模型只判断方向,不给幅度。双均线金叉了,信号是“做多”,但做多少?这个问题规则本身回答不了,必须外挂一套仓位管理模型,或者干脆人工控制。这意味着规则模型的收益上限有一半不在模型手里。
第二条局限更微妙:规则由人定义,而人的认知是有限的,所以规则数量必然有限。这带来一对同时存在的毛病——从整体策略看,有限的规则覆盖不了市场的多种状态,属于欠拟合;从单个策略看,表现高度依赖参数选择,均线周期、标准差倍数稍微一动,回测曲线就面目全非,属于过拟合。这两件事听着矛盾,实际是同一个原因的两个面:规则空间太窄,只能在参数上做文章。
下面这段代码是规则模型最典型的样子,也是它“只给方向”这个缺陷最直观的体现:
import numpy as np import pandas as pd def dual_ma_signal(close: pd.Series, fast=20, slow=60): """双均线:快线上穿慢线给 +1,下穿给 -1,其余 0(持仓不变)""" ma_f = close.rolling(fast).mean() ma_s = close.rolling(slow).mean() raw = np.where(ma_f > ma_s, 1, -1) sig = pd.Series(raw, index=close.index) sig[ma_f.isna() | ma_s.isna()] = 0 return sig def atr_position(close: pd.Series, high: pd.Series, low: pd.Series, signal: pd.Series, atr_n=14, risk_per_unit=0.01, capital=1e6): """ ATR 波动率归一化仓位:让每笔交易的风险预算大致相等 risk_per_unit: 单笔风险占总资金比例,1% 是常见起点 """ tr = pd.concat([high - low, (high - close.shift()).abs(), (low - close.shift()).abs()], axis=1).max(axis=1) atr = tr.rolling(atr_n).mean() risk_cash = capital * risk_per_unit # 单笔可承受的亏损金额 lots = risk_cash / (atr * 10) # 假设合约乘数 10,按 ATR 折算手数 return (signal * lots).fillna(0)第一部分是纯规则信号,输出只有 -1、0、1 三个取值,它回答“方向”,完全不回答“幅度”。第二部分补上了这个缺口:用 14 日 ATR 度量当前波动,把单笔风险预算固定为总资金的 1%,反推手数。这样做的直接效果是——高波动时自动缩仓,低波动时自动加仓,净值波动的稳定性大幅提升,这也是很多规则策略“看起来变聪明了”的真实原因。参数上,atr_n取 14 是行业习惯,取 10 到 20 差异不大;risk_per_unit是真正的调节旋钮,1% 偏保守,2% 以上在商品期货的跳空风险下容易被打穿,需要配合品种间的相关性约束一起用。合约乘数写死成 10 只是示意,实际要按品种表读取,不同品种差异很大。
3.3 预测模型:从“给方向”到“给幅度”,代价是过拟合风险陡增
预测型时序模型与规则模型最大的区别在于输出:前者不只给方向,还给预期的变化幅度。这个差别听起来小,实际影响很大——有了幅度,仓位可以直接由信号强度决定,不需要外挂规则;信号换手更高,除了捕捉大时间尺度的趋势,在震荡行情里也能靠小尺度波动赚钱。
构建流程跟股票量化的处理方式很像,大致三步:数据清洗、特征工程、拟合工程。差异集中在三处——目标函数怎么设(预测收益率、预测波动率、还是预测方向概率)、特征生成偏好什么(量价、期限结构、持仓量变化)、拟合目标选什么周期。也有产品走端到端路线,把特征工程和拟合工程揉进一个网络里一起解,省掉人工特征设计。
但这条路有个硬约束:CTA 可选标的比股票少一个数量级,样本量天然稀缺,过拟合风险比股票策略高得多;特征构造的限制也更紧,可挖掘的 alpha 来源更少。所以同样一套机器学习流水线,搬到商品期货上更容易“回测惊艳、实盘平庸”。
反过来说,如果真做出可行的时序预测模型,它的地位会很特殊——理论上可以完全包容截面模型和后续的统计套利模型,因为截面模型本质上是在同一时点上做的横向预测,统计套利是在价差序列上做的预测,都属于同一个框架的特例。这也是“大一统模型”这个说法在 CTA 领域反复出现的原因。现实里更常见的是混合路线:预测模型管中短周期信号,规则模型管长周期仓位,两者互为约束。
4. 截面与统计套利:把品种池排序之后发生了什么
4.1 三类经典因子的经济学解释,比公式本身重要
截面模型的做法与股票多因子同构:选一组因子,把品种池排序,按排名多空开仓,让组合在市值(这里是保证金占用)上中性。常见的因子大类包括动量、偏度、期限结构,每一个背后都应该有一条能讲通的经济逻辑,否则就是纯数据挖掘。
仓单因子的逻辑是交割意愿。标准仓单是交易所指定交割仓库签发的提货凭证,仓单数量变化反映多空双方的交割意愿:大量仓单生成,说明期货价格高于现货、空头交割意愿强,空头力量占优;大量仓单注销,说明现货紧张、多头占优。据此可以做多仓单减少的品种、做空仓单增加的品种。
截面动量的逻辑是强者恒强,赌品种之间的相对强弱能够延续。这一点与时序动量同源但不同用:时序动量赌单个品种自己跟自己比,截面动量赌一批品种互相之间比。
期限结构的逻辑是库存与升贴水。近月价格高于远月叫反向结构,反映当前库存紧张、可能存在供不应求;远月高于近月叫正向结构,反映库存充足。于是做多贴水结构、做空升水结构,本质上是在做多“现货紧张”这件事。
把这三类因子放在一起对比,能看出它们的信息来源完全不同:
| 因子 | 信息来源 | 经济学解释 | 主要风险 |
|---|---|---|---|
| 仓单 | 交易所仓单日报 | 交割意愿强弱 | 仓单数据滞后、制度变更 |
| 截面动量 | 品种历史收益率 | 相对强弱延续 | 趋势反转期集体失效 |
| 期限结构 | 近远月价差 | 库存紧张程度 | 展期成本吞噬收益 |
| 偏度 | 收益率分布形态 | 极端行情定价偏差 | 样本少、估计不稳定 |
4.2 截面模型的先天缺陷:标的少、风控简陋、尾部风险可能更大
截面模型相对时序策略的一个明显进步,是研究范式更统一——有明确的因子库、排序规则、评价指标,不像时序策略那样容易变成“艺术发挥”。但它的缺陷同样明显,而且是结构性的。
第一个缺陷是标的少导致的显著性存疑。股票多因子可以拿几千只股票做截面回归,商品期货的品种池只有几十个,还要剔除流动性差的,真正能进组合的可能就二三十个。样本量小,排序结果的统计显著性就弱,因子表现的随机性被放大。
第二个缺陷是风控维度缺失。股票多因子有成熟的风格风险模型,能约束行业暴露、市值暴露、波动率暴露;商品截面模型通常只能做到保证金中性或等权多空,没有对应的风险模型去约束品种间的相关性、板块集中度、展期结构。这就带来一个反直觉的结论:多空对冲之后的组合,尾部风险可能比单边暴露的策略更大。因为单边策略在极端行情里方向明确地亏或赚,而多空组合可能在某个品种逼仓、涨跌停、流动性消失的时候,两条腿同时朝不利方向撕开。
第三个缺陷是信号与交易的耦合。截面排序给出的是目标持仓,但从当前持仓调到目标持仓需要交易,品种流动性差异大,滑点和冲击成本会啃掉相当一部分理论收益,尤其在小品种上。
下面这段代码是截面动量打分与多空分组的骨架,重点不在排序本身,而在分组时的约束条件:
import pandas as pd def cross_section_momentum(close_panel, lookback=20, skip=1, top_n=3, min_amount=5e7): """ close_panel: 行=日期, 列=品种收盘价(已复权/拼接主力连续) lookback: 动量回看窗口 skip: 跳过最近 N 日,规避短期反转 top_n: 多空各取前 N 名 min_amount: 日均成交额下限,剔除流动性不足品种 """ ret = close_panel.shift(skip) / close_panel.shift(skip + lookback) - 1 amount = close_panel.rolling(lookback).mean() # 流动性代理 liquid = amount > min_amount score = ret.where(liquid) # 非流动性品种置 NaN longs, shorts = {}, {} for dt, row in score.iterrows(): valid = row.dropna().sort_values(ascending=False) if len(valid) < top_n * 2: continue # 品种不够就不开仓 longs[dt] = list(valid.index[:top_n]) shorts[dt] = list(valid.index[-top_n:]) return pd.DataFrame({"long": longs, "short": shorts})skip=1是为了避开最近一日的短期反转效应,lookback=20对应约一个月的动量周期,这两个参数是最敏感的部分,扰动一下就能看出策略是稳的还是拟合出来的。min_amount这道流动性闸门非常关键——不设它,回测里会混进一堆成交清淡的品种,实盘根本调不进去,收益全是假的。top_n取 3 是为了让多空两侧各有一定分散度,取 1 会让单品种风险过于集中。注意这段只做排序,不含权重分配和风险约束,实际使用时必须叠加板块暴露上限和品种相关性检查,否则遇到同一板块内的品种同时出现在多空两侧(比如两个高度相关的黑色系品种),名义上是多空对冲,实际是同一笔方向性押注。
4.3 统计套利:高胜率的代价是左偏的尾部
统计套利的做法是同时交易两个或多个相关品种,双向开仓,等价差回归。按类型分,有期现套利、跨期套利、跨品种套利、跨市场套利。期现套利需要结合产业知识和现货信息,往往不在纯量化的范畴里;跨市场套利在国内基本等同于跨境联动,对时间效率要求极高,需要同步获取多个市场的行情。真正被量化体系消化的是跨期和跨品种,做法分两支:一支把调整后的价差曲线当作一个新标的,直接套用趋势跟踪或预测模型;另一支用横截面多因子处理。
收益特征与趋势跟踪截然相反:胜率高、盈亏比低,收益分布左偏。多数时候价差在小范围内波动,策略不断赚小钱,胜率看起来非常漂亮;但只要品种组之间的价差突破历史区间、收敛预期被打破,单次亏损就能吞掉前面几十次的盈利。这类尾部风险的触发往往是基本面的结构性变化——产能格局改变、交割规则调整、库存水平长期偏离历史区间——而不是模型参数没调好。
这就带来一个操作上的判断:统计套利策略的核心能力不在“找到相关性高的品种对”,而在“判断价差区间还成不成立”。协整关系会失效,历史区间会被重定价,风控必须按“价差可能永远不回归”来设计,而不是按“历史上都能回归”来设计。止损纪律在这里比在趋势策略里更重要,因为趋势策略的亏损是分散的小额连续亏损,统计套利的亏损是集中的大额单次亏损。
5. 避坑清单:回测漂亮、实盘翻车的五个高频现场
5.1 信号层与回测层:先怀疑回测,再怀疑市场
现象:回测三年夏普 2 以上,实盘第一个月就回撤,信号频率明显下降。
原因通常是两件事叠加。一是样本内参数寻优——均线周期、通道宽度、阈值在历史上扫了一遍,把最优参数留下来,等于把未来的信息提前用掉了;二是品种池的选择偏差,回测时用的品种池是“今天仍然活跃”的品种,早就退市或者流动性枯竭的品种被自然剔除,这是一条隐性的存活偏差,会让回测收益系统性偏高。
解决:参数不做单点最优,而是看参数平原——把参数在邻域内扫一遍,如果收益曲线在最优值附近是尖峰而不是平台,说明这个参数就是拟合出来的。品种池要按历史时点还原,每个时点只能用当时可交易的品种。另外留出至少一个完整市场状态的样本外区间(单边趋势一段、震荡一段),样本外表现掉一半以上是常态,就得重新考虑。
现象:换手率回测显示很低,实盘手续费和滑点吃掉三成收益。
原因:信号在临界点附近来回抖动,产生大量“假开仓-立刻平仓”,回测里按收盘价成交没有成本,实盘要付双边手续费和冲击成本;再加上期货主力合约换月,展期成本没算进去。
解决:信号加一层带宽或者滞回机制,避免临界抖动;回测里把手续费按品种分档设死,滑点按最小变动价位的固定倍数扣;换月规则必须写进回测引擎,按持仓量和成交量切换主力合约,别用拼接价格当作可成交价格。
5.2 组合与风控层:分散的错觉比集中更危险
现象:加了五只 CTA 产品,组合波动率并没有下降,某个月五只产品同时回撤。
原因:五只产品共享同一个动量信号源,只是品种池和参数不同。滚动相关性一算,日收益相关长期在 0.7 以上,这是伪分散。前面那两段相关性代码就是为这种场景写的,全样本相关系数会被长期上行趋势抬高,必须用滚动窗口看同步性。
解决:入池前先算滚动相关矩阵,把高相关的产品合并成一个“风险单元”,按风险单元分配权重,而不是按产品数量分配。
现象:截面多空组合看着风险很低,某个月某个品种出现极端行情,净值单周跌掉两个月收益。
原因:组合做了名义上的多空对冲,但两条腿落在高度相关的品种上,或者集中在同一板块;同时缺少流动性约束,出问题的品种恰恰是平时成交清淡、跑不掉的那些。
解决:给板块暴露设硬上限,同一板块的净敞口和总敞口分开约束;把流动性和持仓限额作为入池的前置条件而不是事后检查;对单一品种的相关性做聚类,同簇品种只保留一个代表。
现象:趋势策略在某段震荡行情里连续止损十几次,净值断崖,随后趋势来了却因为仓位被砍太小而赚不回来。
原因:仓位固定,没有波动率目标。震荡期的连续止损把可用保证金消耗掉,等到趋势启动时资金已经不够;或者反过来,震荡期波动率低,按固定手数开仓显得很轻,趋势一来波动率放大,仓位相对过重。
解决:把仓位锚在波动率上而不是手数上,用 ATR 或者已实现波动率做归一化,让每笔交易的风险预算恒定;同时给整个策略设一个回撤阈值,触线后按比例降杠杆,恢复条件写清楚,别靠临场判断。
6. 研究体系与风控体系:真正的取舍在覆盖广度和单品深度之间
到这里可以正面回答一个绕不开的问题:CTA 到底该做“全覆盖”还是“单品深耕”。这两种路线不是效率高低之分,而是两种完全不同的风险结构。全覆盖指的是品种全覆盖(股指、国债、商品)加策略类型全覆盖(长周期趋势、时序套利、截面套利各有储备),好处是子策略之间的低相关性能够真正兑现成平滑的净值曲线,坏处是每一块都做不到极致,单一策略的容量和 alpha 强度都受限。单品深耕是把资源压在一类信号上,做出别人复制不了的细节,好处是短期业绩突出,坏处是一旦这类信号失效,没有第二条腿支撑。我的判断是:管理规模到一定量级,全覆盖是必须的,因为规模本身会逼着你寻找低相关的收益来源;规模小的阶段硬做全覆盖,往往是把资源摊薄成五条平庸的曲线。
第二个取舍是波动率目标与固定杠杆。固定杠杆的实现简单、归因清晰,但它在低波动环境里等于变相加杠杆,在高波动环境里又显得仓位不足,风险预算随市场状态漂移。波动率目标让风险预算恒定,代价是信号变得不那么“干净”——同样的趋势信号,在不同波动环境下会给出不同的仓位,业绩归因时很难说清是信号赚的还是仓位管理赚的。这里的经验是:把仓位管理单独当成一个模块来做,用独立的评价体系去考核它,别把它揉进信号里,否则出问题的时候你分不清是哪一层坏了。
第三个取舍是规则与预测的混合比例。规则模型给出的是可解释、可审计的边界,预测模型给出的是更高的信号密度和更细的幅度信息。纯预测模型的问题在于失效时没有兜底,纯规则模型的问题在于永远吃不到震荡行情里的机会。比较务实的做法是分层:长周期方向由规则决定,中短周期由预测模型给强度,两层冲突时以规则层为准。这样即使预测模型阶段性失效,策略的整体行为也不会偏离太远。
验证方法上,我习惯用四道关:样本外时间切分、品种外测试(留出几个品种完全不参与训练)、参数扰动测试(邻域内表现是否稳定)、子策略相关性矩阵(判断融合是真的降波动还是只是加杠杆)。四道关全过,才敢往实盘走一小步。
说个自己的教训。早年做一套截面因子组合,回测曲线漂亮得不像话,我盯着夏普和卡玛比率看了两天,唯独没做品种外测试。上实盘之后才发现,收益的大头来自两个流动性极差的小品种,那两个品种在回测区间里恰好走出一段单边行情,而实盘里根本调不进那么大的量。后来我把“品种外留一验证 + 流动性前置筛选”写进了流程,从那以后每次出策略,不管回测多好看,这两步都强制走一遍,一步都不省。希望帮到你。
本文还有配套的精品资源,点击获取