【Python量化实战宝典 #20】动量、反转择时手册:趋势跟随与均值回归(Python 可跑)
手册定位:模块三第 4 篇。两种相反的择时逻辑:动量(追涨、趋势跟随)与反转(抄底、均值回归)。本篇讲怎么构建并对比两者,帮你选适合当下市况的那一个。
数据来源复用 #02 历史K线(close)+ #13 动量因子思路。
1. 你将得到什么
- 趋势跟随信号:N 日动量 > 0(或价格 > 均线)持仓;
- 均值回归信号:价格跌破 N 日均线一定幅度后买入、回归均线卖出;
- 两种信号的收益/回撤对比代码;
- 动量/反转的 4 个坑(风格切换、参数、双边成本、样本期)。
2. 取数约定(复用)
| 信号 | 来源 | 见 |
|---|---|---|
| 日线 close | /hs/history/{代码}.{市场}/d/n |
#02 |
3. 数据来源(复用,不重复罗列)
详见 #02 历史K线接口手册(日线端点)。
4. 核心模板函数(自包含可跑)
python
import pandas as pd
import numpy as np
_MOCK = True
def trend_signal(close, n=20):
s = pd.Series(close)
mom = s / s.shift(n) - 1
return (mom > 0).astype(int) # 动量>0 持仓
def mean_reversion_signal(close, n=20, band=0.05):
s = pd.Series(close)
ma = s.rolling(n).mean()
dev = s / ma - 1
# 跌破均线 band 且未超跌过多 -> 买入(1);回归均线 -> 卖出(0)
return ((dev < -band) & (dev > -2 * band)).astype(int)
def signal_return(close, sig):
s = pd.Series(close)
ret = s.pct_change().fillna(0)
pos = pd.Series(sig).shift(1).fillna(0) # 次日才持仓,避免前视
return (pos * ret).sum()
def run_check():
rng = np.random.default_rng(1)
n = 250
close = 100 * np.cumprod(1 + rng.normal(0.0005, 0.02, n)) # 模拟带趋势的价格
t = trend_signal(close, n=20)
m = mean_reversion_signal(close, n=20, band=0.05)
rt = signal_return(close, t)
rm = signal_return(close, m)
assert np.isfinite(rt) and np.isfinite(rm)
print("校验通过 | 趋势收益=%.3f 反转收益=%.3f" % (rt, rm))
return t, m
if __name__ == "__main__":
run_check()
5. 跑通示例
python
t, m = run_check()
# 实盘可二选一或按市场状态切换
print("趋势信号末态:", "持仓" if t.iloc[-1] else "空仓", " 反转信号末态:", "买入区" if m.iloc[-1] else "观望")
6. 坑与注意事项
- 风格切换:动量在趋势市赢、反转在震荡市赢,单一信号长期会轮空,最好按市场状态切换。
- 参数:N 日窗口决定风格,长窗口偏趋势、短窗口偏反转,别过度优化。
- 双边成本:两种信号都换手,反转更高,回测必须扣交易成本才可信。
- 样本期:在单边牛市回测反转会很难看,要跨多段市况(牛/熊/震)验证稳健性。
7. 小结与下一篇预告
动量/反转择时给了两种互相对冲的逻辑。下一篇讲北向资金跟随------用聪明钱(北向)的净流入做择时信号。
下一篇预告:《【Python量化实战宝典 #21】北向资金跟随手册:聪明钱择时信号(Python 可跑)》
8. 免责声明
本文为择时方法示例,演示数据为模拟,不构成投资建议。