第四.13 动量轮动策略

📘 本章重点

  • 理解动量效应的理论基础——为什么“强者恒强”在金融市场中成立
  • 掌握动量轮动的核心逻辑:在多个标的之间动态切换,持续持有近期表现最强的资产
  • 学会动量周期的选择与调仓频率的设计
  • 了解动量轮动策略在趋势行情中的优势和震荡/反转行情中的风险

⚠️ 本章难点

  • 理解“相对动量”与“绝对动量”的区别——前者只关心谁最强,后者还关心是否足够强
  • 掌握动量周期的选择:周期太短信号噪音大,周期太长反应滞后
  • 理解动量轮动在资产高度趋同时会失效(轮动空间消失)
  • 区分动量轮动与行业轮动(第四.12)的本质差异
  • 理解A股市场动量效应的特殊性——短期反转而非中期动量

⏱️ 预估学习时间

  • 45~60分钟

一、策略简述与一句话定性

一句话定性:动量轮动策略是一种“顺势而为”的量化投资方法——在多个备选资产之间,持续持有过去一段时间表现最强的资产,并定期调仓,将资金从弱势资产转移到强势资产,从而捕捉趋势的延续性。

动量轮动策略结合了两个核心概念:动量轮动

动量(Momentum) ,又称“惯性效应”,是指过去一段时间表现强势的资产,在未来短期内仍可能保持相对优势。这一现象被学术界广泛关注,始于Jegadeesh和Titman在1993年发表的经典论文《Returns to Buying Winners and Selling Losers》。动量的来源可以从行为金融学得到解释:

  • 反应不足:市场对新信息的消化需要时间。当一个公司发布利好消息时,股价不会一天涨到位,而是会在几天或几周内逐步上涨——这就产生了“趋势延续”的空间。
  • 羊群效应:当价格开始上涨时,越来越多的投资者会“跟风”买入,进一步推高价格,形成自我强化的正反馈循环。

轮动(Rotation) ,是指根据不同标的的区间表现差异进行动态配置,力求抓住表现较好的标的、剔除表现不佳的标的。单一资产的动量效应可能因市场风格切换而失效,因此需要引入轮动机制——在股票、债券、商品等大类资产间切换,或在行业间、风格间动态调整。

把两者结合起来:动量轮动 = 用动量因子识别强势资产 + 用轮动机制动态切换持仓。

动量轮动是“多品种趋势跟踪”——它不是“如何预测市场”,而是“如何有纪律地追趋势。”

老陈点评
动量效应是金融学中证据最充分的异象之一。Fama和French在1996年承认,他们的三因子模型无法解释动量异常——这一“尴尬”至今未被他们的因子模型完全消化。动量效应在全球多个市场、多种资产类别中都得到了验证。但需要注意的是:动量效应的强度和持续性在不同市场环境中差异巨大——在趋势市中它表现优异,在震荡市中则可能失效。

老王补充
动量轮动策略本质上是一种“追涨”策略——但它是有纪律的追涨。散户追涨是凭感觉,看到涨了就冲进去;动量轮动是凭规则,用数据说话:谁过去一段时间涨得最好,我就买谁。区别在于:一个靠情绪,一个靠统计。

二、策略的使用范围与条件

维度适用范围与条件说明
适用市场股票、行业指数、ETF、大类资产(股/债/商)、风格指数需要有足够多的备选标的,且标的相关性不能太高
品种流动性要求高流动性(ETF为佳)轮动涉及频繁调仓,流动性不足会导致滑点侵蚀收益
适用周期周频或月频调仓原版动量通常以月为单位(如12个月),A股实践中常用20日或4周
资金门槛单品种ETF即可起步,多品种分散更佳
不适合的市场状态标的之间高度趋同、频繁反转的震荡市轮动空间消失,动量信号失效

什么是“轮动空间”?

轮动空间是指备选资产之间的收益率分化程度。如果所有资产的收益率都差不多(比如都在+5%到+8%之间),轮动空间就小——选谁差别不大。如果资产之间分化很大(比如从+20%到-10%),轮动空间就大——选对了能赚更多。

量化指标:可以用备选资产收益率的标准差或极差(最大-最小)来衡量轮动空间。当极差小于某个阈值(如5%)时,说明资产高度趋同,动量轮动策略的效果会大打折扣。

适用品种举例

  • 宽基指数ETF:沪深300、创业板、科创50等
  • 行业指数ETF:消费、医药、科技、新能源、煤炭等
  • 大类资产ETF:国债ETF、黄金ETF、纳指ETF等
  • 风格指数:大盘/小盘、价值/成长

失效案例:在资产高度趋同的市场环境中(如A股与美股在2017-2018年的阶段性同步走势),动量轮动策略的轮动空间被压缩,可能出现显著回撤。当备选资产走势高度趋同时,轮动空间消失,动量策略失效。

老陈点评
动量轮动策略的效果高度依赖于备选资产之间的分化程度。如果所有资产都在同涨同跌,轮动就没有意义。因此在构建动量轮动策略时,选择低相关性的资产组合比优化动量参数更重要。

三、因子拆解与原理

3.1 动量因子(Momentum Factor)——趋势识别因子

动量因子是策略最核心的驱动因素,它回答了“谁在过去一段时间表现最好”这个问题。

常用动量计算方法

方法计算方式特点
收益率法计算过去N日的涨跌幅最常用,直观易懂
均线突破法价格上穿均线为强势信号结合了趋势确认
复合因子法融合估值、波动率等多因子加权更稳健,但复杂度高

动量周期的选择

  • 短周期(5-10日) :信号敏感,但噪音多,交易成本高
  • 中周期(20-60日) :A股实践中常用的窗口,平衡了灵敏度和稳定性
  • 长周期(6-12个月) :原版学术动量,适合大类资产配置

老陈点评
动量周期的选择没有“标准答案”。A股市场散户占比高、情绪波动大,动量效应的持续时间通常比成熟市场更短。有研究建议,在A股市场中适当缩短动量评估周期(如20-60日),并叠加拥挤度因子进行修正。

3.2 轮动机制(Rotation Mechanism)——动态配置因子

轮动机制解决了“如何在不同资产间切换”的问题。

两种轮动方式

方式逻辑适用场景
相对动量轮动只选排名靠前的标的,不管涨跌备选资产都有上行趋势时
绝对动量轮动只有涨幅为正的标的才买入熊市中可空仓避险

绝对动量要求“不仅要比别人强,还要自己也在涨”——这是一个重要的风控机制。如果所有备选资产都在下跌,绝对动量策略会选择空仓(或持有现金/债券),从而规避系统性风险。

案例:区分相对动量与绝对动量

假设你有3个备选ETF,过去20日的收益率分别为:

ETF收益率
ETF-A+8%
ETF-B+3%
ETF-C-5%
策略类型选择结果理由
相对动量(Top 1)买入ETF-A只看排名,谁最强买谁
绝对动量(Top 1且>0)买入ETF-A排名第一且涨幅为正
相对动量(Top 2)买入ETF-A和ETF-B排名前二
绝对动量(Top 2且>0)买入ETF-A和ETF-B前二且涨幅均为正

再看另一种情况:3个ETF的收益率分别为 -3%、-5%、-8%(全部下跌):

策略类型选择结果理由
相对动量买入ETF-A(-3%)虽然跌了但相对最好
绝对动量空仓没有任何一个涨幅为正

绝对动量的价值就在于此:在熊市中,它能让你空仓避险,而不是“矮子里拔将军”硬买。

3.3 A股市场的动量效应:⚠️ 与美股不同

动量效应在美股市场中证据充分,但在A股市场中表现并不稳定。实证研究表明,A股在2015-2025年整体表现为短期显著反转——即过去涨得多的股票,短期内反而可能跌——价格动量因子呈现负向IC。这意味着:在A股直接照搬美股的长周期动量策略,可能会得到相反的结果。

A股动量策略的调整思路

  1. 缩短动量周期:A股动量效应的持续时间较短,建议使用20日或4周的短周期动量
  2. 结合其他因子:单纯价格动量在A股效果有限,可叠加估值、拥挤度、资金流向等因子
  3. 扩大备选池:加入低相关性资产(如债券、黄金、海外ETF),减少对A股单一市场的依赖

老陈点评
A股市场的动量效应与美股存在结构性差异。一方面,A股散户占比高、情绪波动大,导致价格更容易出现“过度反应”,随后产生反转;另一方面,A股的政策驱动特征明显,动量信号容易被政策干预打断。在A股使用动量策略时,保持对市场环境的敏感度比优化参数更重要。

3.4 因子的优缺点

优点缺点
逻辑清晰,易于理解和实现在震荡市中频繁切换,交易成本高
有坚实的学术基础(动量效应)在资产高度趋同时失效
可应用于多种资产类别可能出现连续多次小额亏损
通过轮动实现分散化不会买在最低点、卖在最高点

老王补充
动量轮动最难受的地方是连续止损。你可能连续三四次调仓都是亏的——刚买进去就跌,下次调仓换一个,又跌。这时候你很容易怀疑策略是不是失效了。但这就是动量策略的代价:它用多次小额亏损,换取少数几次大赚。 关键是要坚持执行。

四、仓位、买卖点与风险管理

4.1 入场信号

动量轮动的入场信号不是“某一时刻触发”,而是“定期评估、动态调整” 。

步骤操作说明
Step 1确定备选资产池如:申万一级行业ETF
Step 2计算动量指标如:过去20日收益率
Step 3排序按收益率从高到低排列
Step 4选择Top N买入排名前2-3的标的
Step 5调仓执行卖出不在组合中的标的,买入新进入的标的

简易动量策略的步骤

  1. 确定轮动标的:选择有对应ETF的行业指数(申万一级行业或中信一级行业),尽量选择流动性好、费率低的品种
  2. 选定业绩评价时间:动量参数是策略的关键——周期太短噪音大,周期太长反应滞后
  3. 排序分组:根据评价期收益率排序,选出最优组(3-6个标的)
  4. 持有与轮换:定期(如每周)检查持仓是否仍在组合内——在则保留,不在则卖出换入新标的

一句话概括:以申万一级行业(或中信一级行业)为备选池,计算过去两周的涨跌幅,取排名前几名的行业等权配置,每周调仓一次。

4.2 仓位管理

方式说明适用场景
等权重选中的每个标的分配相同资金最简单,适合初学者
波动率倒数加权波动大的标的分配更少资金追求风险平价
动态权重根据动量强度调整权重强者更强时加大仓位

老王补充
仓位管理在动量轮动中比入场信号更重要。如果你每次都是全仓押一个标的,一次失误就可能把之前的所有利润吐回去。建议至少持有3-5个标的,即使动量最强的那个也不超过30%仓位。

4.3 止损设计

动量轮动策略的止损逻辑与其他策略不同——它的“止损”是通过调仓机制自动实现的:

止损方式触发条件说明
调仓止损持仓标的跌出Top N自动卖出,换入新强势标的
绝对动量止损标的涨幅为负即使排名靠前也不买入
最大回撤止损策略总回撤超过阈值(如-20%)全部平仓,暂停策略

4.4 止盈设计

动量轮动的止盈同样由轮动机制自动完成:

  • 持续强势则持有:只要标的仍在Top N中,就继续持有,让利润奔跑
  • 掉出Top N则卖出:不管盈亏,严格执行
  • 全部下跌则空仓:绝对动量策略在熊市中可空仓避险

4.5 策略失效时的应对

  • 资产趋同失效:当备选资产高度趋同时,轮动空间消失→ 扩大备选池(加入不同类别的资产)
  • 连续亏损:如果连续多次调仓都是亏损 → 检查动量周期是否合适,或暂停策略重新评估
  • 高波动环境:动量策略在高波动或牛熊快速切换时容易失效→ 降低仓位或缩短调仓周期

⚠️ 动量崩溃(Momentum Crash) :

动量策略最大的风险不是震荡市中的连续小亏,而是市场突然反转时的极端亏损。当市场从极端悲观突然转向乐观(或反之),之前表现最差的资产可能突然暴涨,而表现最好的资产可能突然暴跌——动量策略会在反转中“两头挨打”。

如何应对

  • 使用绝对动量过滤(只买涨的),在熊市中空仓
  • 设置最大回撤止损,当策略回撤超过阈值时暂停
  • 分散配置,不要把所有资金押在单一市场的动量上

五、策略的来历、设计者与趣闻

动量效应最早由Jegadeesh和Titman在1993年的论文《Returns to Buying Winners and Selling Losers: Implications for Stock Market Efficiency》中系统提出。他们发现:过去3-12个月表现最好的股票,在未来3-12个月仍会跑赢过去表现最差的股票。这一发现挑战了有效市场假说,成为行为金融学的重要证据。

动量轮动作为动量效应的应用形式,其雏形可以追溯到更早的相对强度策略(Relative Strength Strategy) ——由Robert Levy在1960年代提出,他发现买入过去表现最强的股票可以产生超额收益。

在国内,动量轮动策略最广为人知的形式是“二八轮动” ——在大盘股(沪深300)和小盘股(创业板)之间轮动,谁过去一段时间涨得好就买谁。后来这一思想被扩展到行业轮动、风格轮动和跨资产轮动。

趣闻:有一个经典的动量轮动回测——在创业板、纳指ETF、黄金、国债四个资产之间轮动,比较三者20日涨幅,选择排名第一且突破20日高点的资产,否则持有国债。结果显示:10年累计收益达2408.67%,年化收益33.15%,最大回撤22.92%

⚠️ 冷静看待这个回测结果:这个组合包含了股票、海外股票、商品、债券四类低相关性资产,轮动空间天然较大。此外,回测区间(约10年)恰好是全球资产大牛市,动量策略在这种环境中天然占优。不要将这个回测结果作为实盘的收益预期。

另一个有趣的现象:动量轮动策略在A股熊市中往往表现不佳。有分析指出,当轮动对象局限在A股市场时,一旦遭遇熊市,无论采取何种轮动策略都难以避免损失。解决思路是跳出A股,在全球范围内选择备选资产——加入美股、黄金、债券等低相关性资产,可以在熊市中提供更多轮动空间。

策略拥挤:动量策略的“自我毁灭”

当一个策略被太多人使用时,它的有效性会下降。动量策略尤其如此——如果太多资金都在“追涨”,那么“涨”本身就会变得更贵、更不可持续。这就是为什么公开的动量策略往往不如私有的动量策略有效——知道的人越多,能赚的钱越少。

老陈点评
动量轮动的回测业绩往往非常漂亮——因为历史上大部分时间市场都有趋势。但漂亮回测的背后是对市场环境的隐性假设:假设市场存在可持续的趋势。一旦这个假设不成立(如A股与美股趋同的时期),策略就会失效。永远不要用牛市回测来证明一个策略在熊市中也能赚钱。

老王补充
我见过最搞笑的动量轮动案例:有人用“过去一周涨幅最大”作为动量指标,每天调仓,结果手续费就把收益吃光了。动量的频率要和你的资金规模、交易成本匹配。 小资金做日频还可以,大资金做日频就是给券商打工。

六、Python回测示例

以下代码演示动量轮动策略在多个行业ETF上的回测。采用月频调仓、相对动量选Top 3、等权重配置。

import pandas as pd
import numpy as np
import yfinance as yf
from datetime import datetime, timedelta

# 备选ETF列表(示例:不同行业的A股ETF)
# 注意:yfinance对A股ETF的支持有限。如无法获取数据,建议:
# 1. 使用akshare:import akshare as ak; df = ak.fund_etf_hist_em(symbol="159928")
# 2. 使用tushare(需注册token)
# 3. 使用聚宽/万得等专业数据源

ETF_LIST = {
    '消费': '159928.SZ',   # 消费ETF
    '医药': '159929.SZ',   # 医药ETF
    '科技': '159807.SZ',   # 科技ETF
    '新能源': '516160.SS', # 新能源ETF
    '煤炭': '515220.SS',   # 煤炭ETF
    '酒': '512690.SS',     # 酒ETF
}

def momentum_rotation_strategy(data_dict, 
                               lookback_days=20,      # 动量评估周期
                               top_n=3,               # 选择前N个标的
                               rebalance_freq='M',    # 调仓频率:'W'周频,'M'月频
                               use_absolute_momentum=True,  # 是否使用绝对动量过滤
                               min_momentum_threshold=0.0,  # 最小动量阈值(>0)
                               cost_rate=0.001):      # 交易成本(双边)
    """
    动量轮动策略
    参数:
        data_dict: {名称: DataFrame(含'Close'列)} 的字典
        lookback_days: 动量评估的回看天数
        top_n: 每次选择持有几个标的
        rebalance_freq: 调仓频率
        use_absolute_momentum: 是否要求涨幅为正才买入
        min_momentum_threshold: 最小动量阈值
        cost_rate: 交易成本(双边,如0.001表示0.1%)
    返回:各日期的持仓和净值
    """
    # 1. 合并所有资产的价格数据
    dates = None
    price_df = pd.DataFrame()
    
    for name, df in data_dict.items():
        if not isinstance(df.index, pd.DatetimeIndex):
            df.index = pd.to_datetime(df.index)
        price_df[name] = df['Close']
        if dates is None:
            dates = df.index
        else:
            dates = dates.union(df.index)
    
    price_df = price_df.reindex(dates).fillna(method='ffill')
    
    # 2. 计算动量(收益率),使用前一日数据避免未来信息
    momentum = price_df.pct_change(lookback_days)
    
    # 3. 生成调仓信号
    df = pd.DataFrame(index=dates)
    df['Position'] = ''  # 持仓标的名称列表(用字符串存储)
    
    # 获取调仓日期
    if rebalance_freq == 'W':
        rebalance_dates = dates[dates.weekday == 4]  # 每周五
    else:  # 'M' 月频
        rebalance_dates = dates[dates.is_month_end]
    
    current_positions = []
    prev_positions = []  # 记录上一次持仓,用于计算交易成本
    
    for i, date in enumerate(dates):
        is_rebalance = date in rebalance_dates
        
        if is_rebalance and i > 0:
            # ⚠️ 使用前一个交易日的动量数据,避免未来信息
            mom_row = momentum.loc[dates[i-1]]
            sorted_mom = mom_row.sort_values(ascending=False)
            
            if use_absolute_momentum:
                candidates = sorted_mom[sorted_mom > min_momentum_threshold]
            else:
                candidates = sorted_mom
            
            selected = candidates.head(top_n).index.tolist()
            prev_positions = current_positions
            current_positions = selected
        
        df.loc[date, 'Position'] = ','.join(current_positions) if current_positions else '空仓'
    
    # 4. 计算策略净值(考虑交易成本)
    df['Position_List'] = df['Position'].apply(lambda x: x.split(',') if x != '空仓' else [])
    
    returns = []
    cash = 1.0  # 初始净值1
    current_pos = []  # 当前实际持仓
    
    for i in range(1, len(df)):
        date = df.index[i]
        prev_date = df.index[i-1]
        target_positions = df.loc[date, 'Position_List']
        
        # 计算调仓成本:检查持仓变化
        if i > 1:
            prev_pos = df.loc[df.index[i-1], 'Position_List']
            # 计算换手率:卖出旧持仓 + 买入新持仓
            turnover = len(set(prev_pos) - set(target_positions)) + len(set(target_positions) - set(prev_pos))
            cost = cost_rate * turnover / max(len(prev_pos), 1)
        else:
            cost = 0
        
        if not target_positions:
            daily_ret = 0  # 空仓收益为0(可改为货币基金收益)
        else:
            ret_sum = 0
            for pos in target_positions:
                if pos in price_df.columns:
                    ret = (price_df.loc[date, pos] / price_df.loc[prev_date, pos]) - 1
                    ret_sum += ret
            daily_ret = ret_sum / len(target_positions) - cost
        
        returns.append(daily_ret)
    
    df['Returns'] = [0] + returns
    df['Net_Value'] = (1 + df['Returns']).cumprod()
    
    # 5. 统计指标
    total_return = (df['Net_Value'].iloc[-1] - 1) * 100
    max_drawdown = ((df['Net_Value'].cummax() - df['Net_Value']) / df['Net_Value'].cummax()).max() * 100
    sharpe = df['Returns'].mean() / df['Returns'].std() * np.sqrt(252) if df['Returns'].std() > 0 else 0
    
    print(f"总收益率:{total_return:.2f}%")
    print(f"最大回撤:{max_drawdown:.2f}%")
    print(f"夏普比率:{sharpe:.2f}")
    
    return df, price_df

if __name__ == "__main__":
    # 下载数据(示例:不同行业ETF)
    data_dict = {}
    for name, ticker in ETF_LIST.items():
        try:
            df = yf.download(ticker, start='2020-01-01', end='2025-01-01', progress=False)
            if not df.empty:
                data_dict[name] = df
                print(f"成功加载 {name} ({ticker})")
        except Exception as e:
            print(f"加载 {name} 失败: {e}")
    
    if data_dict:
        result, prices = momentum_rotation_strategy(
            data_dict, 
            lookback_days=20, 
            top_n=3, 
            rebalance_freq='M',
            use_absolute_momentum=True,
            cost_rate=0.001
        )
        print(result[['Position', 'Net_Value']].tail(10))
    else:
        print("未成功加载任何数据,请检查网络或更换数据源")

回测结果简要解读(以实际运行为准):

  • 在趋势明显的行情中(如2020年消费/科技牛市),动量轮动能持续持有强势行业,捕获主要涨幅
  • 在行业频繁切换的震荡市中,策略可能频繁调仓,交易成本上升
  • 绝对动量过滤(只买涨的)可以在熊市中减少亏损,但也可能在反弹初期错过机会
  • 建议读者尝试不同动量周期(10日、20日、60日)和不同Top N(2、3、5),观察参数敏感性

代码说明
本代码为简化版动量轮动策略,核心逻辑是定期计算各标的的历史收益率,排序后持有Top N。实际应用中,可以加入更多因子(如波动率、拥挤度)来优化选股。

老陈点评
回测时要特别注意生存者偏差——回测中使用的ETF可能在当时并不存在。建议使用指数数据(而非ETF数据)进行回测,验证策略逻辑后再映射到可交易的ETF上。

老王补充
实盘中最大的问题是调仓的执行。动量轮动要求你在固定时间点调仓,如果当天市场波动剧烈,你的买卖价格可能与回测假设相差很大。建议使用限价单分批成交,避免一次性大单冲击市场。

七、本章小结与思考题

小结

项目核心要点
策略类型趋势跟踪,基于动量效应
核心逻辑持续持有过去一段时间表现最强的资产
适用行情有明显趋势、资产间分化明显的市场
核心优势逻辑清晰,有学术支撑,易于实现
最大风险震荡市或资产趋同时频繁切换、连续亏损;A股中需注意短期反转效应
资金门槛低,ETF即可起步

动量轮动 vs 行业轮动(第四.12) :

维度行业轮动(第四.12)动量轮动(第四.13)
驱动因素经济周期、景气度、政策价格趋势、历史收益率
决策依据基本面 + 宏观纯技术面(价格)
调仓逻辑预期行业景气度变化历史价格表现延续
适用周期中长期(季度/年度)中短期(周/月)

老陈总结
动量轮动是量化策略中“最诚实”的一种——它不试图预测未来,只是机械地跟随过去的表现。这种诚实让它在大趋势中表现出色,但也让它在大逆转中措手不及。动量轮动的核心不是“预测”,而是“应对”。

老王总结
如果你只有一两个标的,动量轮动没有意义——轮动需要至少3-5个低相关性的标的才能发挥作用。另外,别在手续费高的品种上做高频轮动,否则你赚的钱还不够交手续费。ETF是动量轮动的最佳载体——流动性好、费率低、交易方便。

💡 思考题

  1. 动量轮动策略中,动量周期的选择对策略表现影响巨大。如果周期太短(如5天)会怎样?如果周期太长(如1年)会怎样?
  2. “绝对动量”和“相对动量”的区别是什么?在A股熊市中,哪一种更有利于控制回撤?
  3. 假设你有5个备选ETF,过去一个月的收益率分别为:+15%、+10%、+5%、-5%、-10%。按照Top 2的动量轮动策略,你应该买入哪两个?如果使用绝对动量过滤,结果会有什么不同?
  4. (展望题) 随着ETF市场的快速发展,投资者可以选择的行业ETF越来越多。你认为这会增强还是削弱动量轮动策略的有效性?请从“轮动空间”和“策略拥挤度”两个角度分析。

八、引用/参考出处

网上内容

学术论文(元信息)

  • Jegadeesh, N., & Titman, S. (1993). “Returns to Buying Winners and Selling Losers: Implications for Stock Market Efficiency.” Journal of Finance, 48(1), 65-91.(动量效应的经典文献)
  • Fama, E. F., & French, K. R. (1996). “Multifactor Explanations of Asset Pricing Anomalies.” Journal of Finance, 51(1), 55-84.(动量作为未被解释的异象)

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容