Skip to content

周五买入,周一数钱?这个简单的轮动策略能让你跑赢90%的投资者

作 者:老余捞鱼

原创不易,转载请标明出处及原作者。

写在前面的话:今天给大家分享的是一个动量轮动策略:每周五买入过去3个月表现最好的资产,持有到下周五再调整。这个策略不预测市场,只跟随趋势。回测显示它轻松跑赢了等权重组合(年化收益率达56.83%,夏普比率1.38),这个方法简单有效,新手也能上手。

一、什么是动量轮动策略?

动量效应是金融市场中最持久且广泛存在的现象之一。简单来说,就是之前涨得好的资产,短期内继续上涨的可能性更大。这就像运动中的物体有惯性一样,上涨的资产也有继续保持上涨的“动量”。

学术界对动量效应早有深入研究。自从Jegadeesh和Titman发现动量效应以来,这一可以获得超额收益的策略越来越广泛地应用到投资组合管理当中。研究发现,90%的基金经理都倾向使用动量策略进行投资实践和组合配置

我这个策略的核心思想非常简单:买入近期表现最强的资产,每周调整一次。因为买强势资产比猜市场方向聪明多了。不用复杂模型,就能跟着市场强势走。

具体来说,就是每周五选择过去一段时间内表现最好的资产,然后买入持有到下一周,如此循环往复。

🔁背后的逻辑和策略核心规则

这个策略有效的背后,主要有三个原因:

反应不足:市场对利好消息不能一次完全消化,会持续在股价上体现,形成持续的上涨趋势。

正反馈效应:赢家恒赢,表现好的资产会吸引更多投资者关注,形成正向循环。

过度反应:投资者往往会过度追捧表现好的资产,推动其价格进一步上涨。

这个策略有几个关键规则:

只在周五调仓:每周五检查持仓,卖出不符合条件的资产,买入新的强势资产。

选择近期表现最佳的资产:基于过去63天(约3个月)的收益率排名。

只选择表现正面的资产:排除所有近期收益为负的资产。

等权重分配:每个入选资产分配相同的资金。

二、手把手教学

接下来,我详细讲解如何用Python实现这个策略。别担心,即使你是编程新手,也能跟着一步步做出来。

第一步:准备工作

首先,我们需要导入一些Python库:

import pandas as pd
import numpy as np
import yfinance as yf
import matplotlib.pyplot as plt

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

第二步:设置策略参数

我们的例子用了6只美国大公司股票:苹果、微软、亚马逊、谷歌、特斯拉、英伟达。

你可以换成其他,比如行业基金、国家指数、加密如比特币、以太坊等,看你想玩什么。

在国内可以用A股大盘股如贵州茅台、宁德时代、中国平安、比亚迪、腾讯控股、阿里巴巴。

# 策略参数设置
TICKERS = ["AAPL", "MSFT", "AMZN", "GOOGL", "TSLA", "NVDA"]  # 股票池
START_DATE = "2020-01-01"    # 回测开始日期
END_DATE = "2025-07-01"      # 回测结束日期
MOM_DAYS = 63                # 动量计算周期,63天约等于3个月
TOP_N = 2                    # 每次选择的资产数量
COST_BPS = 5                 # 交易成本,万分之五

每个资产用过去一段时间涨幅打分。时间窗可调,用天数。 参数是强势天数:63天,大概3个月。 你也可以根据自己的需求调整这些参数。

第三步:获取数据

从Yahoo Finance拉开盘和收盘价。数据对齐,填空。

# 下载历史数据
data = {}
for t in TICKERS:
    df = yf.download(t, start=START_DATE, end=END_DATE, progress=False)
    data[t] = df

# 整理开盘价和收盘价数据
opens = pd.concat([data[t]["Open"] for t in TICKERS], axis=1)
closes = pd.concat([data[t]["Close"] for t in TICKERS], axis=1)
opens.columns = TICKERS
closes.columns = TICKERS

第四步:计算动量信号

这种计算动量的方法是金融领域的常见做法,即使用一定时间内的收益率来衡量资产的动量强弱。

# 计算动量:使用收益率作为动量指标
momentum = closes.pct_change(MOM_DAYS)

# 确定调仓日期(每周五)
is_friday = closes.index.weekday == 4
rebalance_dates = closes.index[is_friday]

# 构建投资组合
portfolio = pd.Series(index=closes.index, dtype=object)

for date in rebalance_dates:
    # 选择表现最好的TOP_N个资产
    top_assets = momentum.loc[date].nlargest(TOP_N)
    # 只选择动量为止的资产
    winners = top_assets[top_assets > 0].index.tolist()
    
    if len(winners) == 0:
        # 没有正动量资产,持有现金
        portfolio.loc[date] = ["CASH"]
    else:
        portfolio.loc[date] = winners

# 填充非调仓日的持仓
portfolio = portfolio.ffill()

第五步:计算收益

回报是按开盘价计算的,即以今天开盘价买入,以明天开盘价卖出。这避免了前瞻偏差并与实际再平衡的发生方式相匹配。

# 计算开盘价到开盘价的收益率(避免使用未来数据)
open_ret = opens.pct_change().fillna(0)
open_ret["CASH"] = 0.0  # 现金收益率为0

# 构建权重矩阵
assets = opens.columns.tolist() + ["CASH"]
weights = pd.DataFrame(0.0, index=opens.index, columns=assets)

for date, selected_assets in portfolio.items():
    weight = 1.0 / len(selected_assets)  # 等权重
    for asset in selected_assets:
        weights.at[date, asset] = weight

# 向前填充权重
weights = weights.ffill()

# 计算策略收益
strategy_returns = (weights.shift() * open_ret).sum(axis=1)

# 考虑交易成本
rebalance_days = (weights != weights.shift()).any(axis=1)
strategy_returns[rebalance_days] -= COST_BPS / 10000

每次重新平衡时,我们会将资金平均分配给所选股票。如果符合条件的股票数量少于目标数量,则剩余的权重将转换为现金。

第六步:绘制收益曲线

我们将轮换策略和个人买入并持有收益进行了图形化比较。

# 计算策略净值曲线
equity_curve = (1 + strategy_returns).cumprod()

# 计算等权重基准
equal_weight_returns = open_ret[TICKERS].mean(axis=1)
equal_weight_curve = (1 + equal_weight_returns).cumprod()

# 绘制收益曲线对比图
plt.figure(figsize=(12, 6))
plt.plot(equity_curve, label='动量轮动策略', linewidth=2)
plt.plot(equal_weight_curve, label='等权重组合', linestyle='--')
plt.title('动量轮动策略 vs 等权重组合')
plt.xlabel('日期')
plt.ylabel('净值')
plt.legend()
plt.grid(True)
plt.show()

从上图中可以看到,动量轮动策略的净值曲线明显跑赢了等权重组合,体现了策略的有效性。

三、策略效果数据分析

我们会将投资组合持有量随时间的变化进行可视化,以显示每周选择了哪些资产。

# 持有时间线
fig, ax = plt.subplots(figsize=(13,2))
idx_map = {t:i for i,t in enumerate(TICKERS+['USD'])}

if TOP_N == 1:
    hold = basket.map(lambda x: x[0])
    hold_idx = hold.map(idx_map)
    ax.step(basket.index, hold_idx, where="post", linewidth=2)
else:
    for pos in range(TOP_N):
        series = basket.map(lambda x: x[pos] if pos < len(x) else 'USD')
        series_idx = series.map(idx_map)
        ax.step(basket.index, series_idx, where="post", linewidth=2)

ax.set_yticks(list(idx_map.values()))
ax.set_yticklabels(list(idx_map.keys()))
ax.set_xlabel("Date")
ax.set_title("Holding Timeline")
ax.grid(axis="y", alpha=0.3)
plt.tight_layout()
plt.show()

最后,为了全面评估策略表现,我们计算几个关键指标:

# 计算年化收益率
years = len(strategy_returns) / 252
cagr = equity_curve.iloc[-1] ** (1 / years) - 1

# 计算年化波动率
volatility = strategy_returns.std() * np.sqrt(252)

# 计算夏普比率
sharpe = strategy_returns.mean() / strategy_returns.std() * np.sqrt(252)

# 计算最大回撤
max_drawdown = (equity_curve / equity_curve.cummax() - 1).min()

print(f"年化收益率: {cagr:.2%}")
print(f"年化波动率: {volatility:.2%}")
print(f"夏普比率: {sharpe:.2f}")
print(f"最大回撤: {max_drawdown:.2%}")

回测结果如下表所示:

指标动量轮动策略等权重组合
年化收益率56.83%18.30%
年化波动率37.93%20.10%
夏普比率1.380.91
最大回撤-54.75%-40.50%

从这些指标可以看出,动量轮动策略在收益方面表现极其出色,年化收益率达到56.83%,远超等权重组合。虽然波动率和最大回撤相对较高,但夏普比率1.38表明策略的风险调整后收益依然优秀。

四、策略的局限与改进

虽然这个策略表现不错,但任何策略都不是完美的。这个动量轮动策略主要有以下局限性:

4.1 动量崩溃风险

在极端市场环境下,尤其是在市场持续下跌后突然反弹,并且事前市场波动率处于较高水平时,动量策略的收益可能出现极端损失,这种现象被学术界称为”动量崩溃“。

2008-2009年全球金融危机期间,传统动量策略就经历了显著的崩盘。

4.2 改进方法

波动率择时:当市场波动率过高时,暂停动量策略。研究表明,基于波动率阈值函数的择时动量策略能有效规避动量崩溃风险。

# 简单的波动率过滤示例
market_volatility = closes.pct_change().rolling(30).std() * np.sqrt(252)
high_vol_period = market_volatility > 0.4  # 年化波动率超过40%

# 在高波动期持有现金
for i, date in enumerate(rebalance_dates):
    if high_vol_period.loc[date].any():
        portfolio.loc[date] = ["CASH"]
    else:
        # 正常动量选股逻辑
        top_assets = momentum.loc[date].nlargest(TOP_N)
        winners = top_assets[top_assets > 0].index.tolist()
        portfolio.loc[date] = winners if len(winners) > 0 else ["CASH"]
  • 多因子结合:将动量因子与其他因子如价值、质量等结合,构建综合评分系统。
  • 动态调仓频率:根据市场波动率调整调仓频率,高波动时降低调仓频率以控制交易成本。

4.3 实际应用建议

如果你想在实际投资中应用这个策略,这里有一些建议:

  • 起步资金:建议至少10万元,以便分散投资并控制交易成本的影响。
  • 标的池选择:可以选择不同行业的龙头股,或者主要ETF基金,确保标的池 diversified。
  • 交易执行:最好在周五下午收盘前完成调仓操作,严格遵循策略信号。
  • 心理准备:策略会有回撤期,需要坚持执行,避免因短期表现不佳而放弃。

五、观点总结

动量轮动策略是一个简单且历史悠久的投资策略,它的魅力在于不试图预测市场,而是跟随市场已经显示出的趋势。这个策略最适合趋势明显的市场环境,而在震荡市中可能会经历一定的回撤。

  • 策略逻辑简单明了,只需每周五调仓,选择近期表现最佳的资产。
  • 回测表现优异,年化收益率达56.83%,远超基准组合。
  • 夏普比率1.38,风险调整后收益表现优秀。
  • 可通过波动率择时等方法控制-54.75%的最大回撤。
  • 代表了”简单有效”的投资哲学,无需复杂模型也能获得好回报。

▶️ 完整代码下载

Google Colab地址:请留言获取

代码打包下载地址:请留言获取

#关键词

#动量策略 #量化投资 #股票轮换 #Python教学 #资产配置 #A股实战 #加密货币 #高回报秘籍 #每周调仓 #现金保本

希望这篇文章为您带来了新的启发和实用的知识!如果觉得有帮助,请不吝点赞和分享,您的支持是我持续创作的动力。祝您投资顺利,收益长虹!如果对文中内容有任何疑问,欢迎留言,我会尽快回复!


本文内容仅限技术探讨和学习,不构成任何投资建议。

Published inAI&Invest专栏

Be First to Comment

发表回复