3. 时间序列动量原理
时间序列动量(Time-Series Momentum, TSM)研究的不是“谁涨得比谁多”,而是“同一个资产过去涨,未来是否更可能继续涨”。它把每个品种的历史收益作为唯一信号来源,做多过去上涨者、做空过去下跌者。要把它开发成可交易的CTA策略,必须回答三个问题:为什么会有动量、它为什么没被套利掉、以及我们看到的收益是否只是噪声。
一、核心原理:从风险补偿到行为偏差
动量效应的经济学解释主要分两条线。第一条是风险补偿:趋势跟随者在市场下跌时承接风险、在恐慌后提供流动性,因此长期获得正的风险溢价;同时,动量组合在宏观冲击后承担了“崩盘风险”,收益是对尾部风险的补偿。第二条是行为金融学:投资者存在处置效应(过早卖出盈利、死扛亏损)、锚定与调整不足、羊群效应和确认偏误,导致价格对信息反应不足,随后又过度反应,形成可被系统化捕捉的趋势。
从机制上看,时间序列动量依赖三个可观测条件:信息扩散需要时间、资金流与仓位调整有惯性、宏观周期具有持续性。当新信息逐步被市场消化,价格会沿同一方向漂移;当趋势被广泛识别后,资金流入又强化了趋势。策略赚的正是这段“漂移窗口”的钱,而不是预测拐点。
二、方法流程:从信号到显著性检验
开发时间序列动量策略,通常按以下流程推进:
- 定义信号:对每个资产计算过去N日收益率,例如
signal = close / close.shift(N) - 1,并做波动率缩放。 - 生成仓位:信号为正做多,为负做空,仓位大小与波动率成反比,控制单品种风险。
- 计算收益:用下一期收益乘以仓位,得到策略日收益序列。
- 统计检验:对收益序列做单样本t检验,原假设为均值小于等于0;同时用自举法处理非正态与自相关。
- 稳健性检验:更换N、样本区间、资产池,观察显著性是否稳定。
- 成本与容量评估:扣除手续费、滑点、冲击成本后,判断是否仍有正期望。
下面是一段最小可运行的Python示例,用于计算动量信号并做t检验:
import numpy as np
import pandas as pd
from scipy import stats
# 假设 df 含 date 与 close
df['ret'] = df['close'].pct_change()
N = 60
df['signal'] = np.sign(df['close'] / df['close'].shift(N) - 1)
df['vol'] = df['ret'].rolling(20).std()
df['position'] = df['signal'] / df['vol']
df['strategy_ret'] = df['position'].shift(1) * df['ret']
# 单样本t检验:H0 均值 <= 0
t_stat, p_two = stats.ttest_1samp(df['strategy_ret'].dropna(), 0)
p_one = p_two / 2 if t_stat > 0 else 1 - p_two / 2
print(f"t={t_stat:.3f}, one-sided p={p_one:.4f}")
三、案例/场景:一次动量检验的完整复盘
假设我们在原油、黄金、铜、大豆四个品种上测试60日时间序列动量,样本为2015—2024年日频数据。初步结果显示:组合年化收益8.6%,夏普0.72,t统计量2.31,单边p值0.011,看似显著。但进一步检查发现:
- 收益主要集中在2020—2022年,剔除该区间后t值降至1.42,不再显著;
- 加入双边0.05%手续费与滑点后,年化收益降至4.1%,夏普0.38;
- 把N从60改为20、120后,t值在1.1—2.4之间波动,说明参数敏感。
这个案例说明:统计显著只是入场券,不是通行证。真正可交易的动量策略,需要在不同市场状态、不同参数、不同成本假设下都保持正期望。
| 检验维度 | 常用方法 | 通过标准 | 常见陷阱 |
|---|---|---|---|
| 均值显著性 | 单样本t检验 | 单边p < 0.05 | 忽略自相关与厚尾 |
| 非正态稳健性 | 自举法 / 块自举 | 置信区间不含0 | 简单重采样破坏时序结构 |
| 多重检验 | Bonferroni / FDR | 校正后仍显著 | 反复调参导致数据窥探 |
| 样本外验证 | 滚动窗口 / 扩展窗口 | 样本外夏普 > 0.5 | 用未来数据做标准化 |
| 成本后收益 | 手续费+滑点+冲击成本 | 净期望为正 | 低估换手与容量限制 |
四、误区与复盘:动量策略最容易踩的坑
误区二:只看t值,不看经济逻辑。 如果一段动量收益完全来自某次极端行情,且没有风险补偿或行为偏差支撑,它很可能只是数据噪声。复盘时要问:这段收益对应什么宏观事件?当时市场结构是否支持趋势延续?
误区三:忽略交易成本与容量。 时间序列动量换手率不低,尤其短周期版本。回测中若未扣成本,t值再高也不可交易。建议在回测阶段就加入成本模型,并做容量压力测试。
误区四:用全样本调参后再做全样本检验。 这等于用未来信息优化过去参数,t值会被严重高估。正确做法是划分训练集与测试集,或采用滚动窗口,每次只用历史数据确定参数。
复盘时建议固定一张检查清单:信号是否有经济学或行为金融学支撑?参数是否稳健?样本外是否显著?成本后是否为正?极端行情下回撤是否可承受?只有全部通过,才进入组合配置与风险预算环节。