37 lines
1.3 KiB
Python
37 lines
1.3 KiB
Python
"""04 | 动量轮动策略
|
|
目标:从"单票择时"升级到"多标的轮动"。
|
|
策略:每月末看过去 N 日涨幅,持有最强的一只。
|
|
"""
|
|
import pandas as pd, numpy as np
|
|
from lib_quant import get_daily, net_value, stats
|
|
|
|
POOL = {"600519": "贵州茅台", "000001": "平安银行", "300750": "宁德时代",
|
|
"601318": "中国平安", "000858": "五粮液"}
|
|
LOOKBACK, FREQ = 20, 20 # 回看20日,每20个交易日调仓
|
|
|
|
px = {}
|
|
for c in POOL:
|
|
d = get_daily(c, "20200101", "20241231")[["日期", "收盘"]].set_index("日期")
|
|
px[c] = d["收盘"]
|
|
prices = pd.DataFrame(px).dropna()
|
|
mom = prices.pct_change(LOOKBACK)
|
|
|
|
rets = []
|
|
cur = None
|
|
for i in range(LOOKBACK, len(prices) - 1):
|
|
if (i - LOOKBACK) % FREQ == 0: # 调仓日
|
|
cur = mom.iloc[i].idxmax() # 动量最强
|
|
if cur is not None:
|
|
r = prices[cur].iloc[i + 1] / prices[cur].iloc[i] - 1
|
|
rets.append(r)
|
|
else:
|
|
rets.append(0.0)
|
|
|
|
s = pd.Series(rets)
|
|
print("== 动量轮动 ==", stats(s))
|
|
print("== 等权买入持有 ==", stats(prices.pct_change().mean(axis=1).iloc[LOOKBACK:]))
|
|
|
|
# 思考题:
|
|
# 1) 换 LOOKBACK (10/60/120) 看结果——动量在A股有效吗?
|
|
# 2) 为什么不持有全部、按动量加权?(提示: 集中 vs 分散)
|