Python动量策略实战:大幅跑赢市场的底层逻辑

作者:老余捞鱼

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

写在前面的话:最近我深入研究了一种基于动量策略的量化投资方法,并用Python实现了它。动量策略的核心是“追涨杀跌”,通过历史数据预测未来趋势。在这篇文章中,我分享了如何用Python从数据获取、策略构建到回测的全过程。如果你对量化投资感兴趣,这篇文章会是一个不错的入门指南。

一、什么是动量投资策略?

动量投资(Momentum Investing) 是一种基于价格趋势和市场情绪的投资策略,旨在通过捕捉价格动量来实现盈利。

动量投资的核心在于“买入强势股,卖出弱势股”

这种投资策略的成功往往依赖于市场的心理因素,因为投资者的情绪和行为会影响资产价格的波动。动量投资适合那些愿意承担一定风险并能够快速反应市场变化的投资者。

动量投资策略通常以下几个步骤进行实施:

  • 筛选股票:投资者会根据过去几个月或几年的表现来筛选出表现优异的股票(即动量股票)和表现不佳的股票(即反动量股票)。
  • 建立投资组合:投资者会将选中的动量股票纳入投资组合,同时可能会卖空反动量股票,以期在价格回调时获利。
  • 定期调整:动量投资者通常会定期重新评估和调整投资组合,以确保持续持有表现良好的股票,并剔除表现不佳的股票。

动量投资是一种强大的策略,旨在利用市场现有趋势的持续性。通过关注过去表现良好的股票,投资者有可能乘势取得可观的回报。

二、动量投资策略设定

我的动量投资战略主要由这两个部分组成:

2.1 选择股票

聪明的投资者都明白“选择”远大于“努力”,在本文中,我们将探讨为 Nifty 50 指数(新兴的印度市场中市值最大的50家公司)中的股票量身定制的动量策略。你没看错,不是美股,更不是MianA,我认为目前全球最适合动量策略实施的地方就是印度股市,没有之一!原因如下:

1. 经济增长潜力巨大

印度是全球增长最快的主要经济体之一,2023年GDP增速达到7.6%,位居全球十大经济体之首。高盛预测,到2050年,印度在全球市场中的份额将从3%提升至8%,并进一步增长至2075年的12%。印度的人口红利是其经济增长的重要驱动力,14.28亿人口中,年龄中位数仅为28.4岁,年轻化的人口结构为消费和经济增长提供了强劲动力。

2. 股市长期表现优异

印度股市以“长牛”著称,自2000年以来,印度SENSEX30指数涨幅达1507%,远超同期标普500的304%和纳斯达克的367%。过去5年,SENSEX30指数上涨198%,远超纳斯达克的160%和日经225指数的118%。这种长期优异表现得益于印度经济的强劲增长和股市制度的完善。

3. 完善的投资者保护制度

印度股市实行严格的注册制和退市制度,确保市场透明度和投资者权益。上市公司一旦被强制退市,必须按交易所评估的公允价格回购公众投资者股份,否则将面临严厉惩罚。此外,印度还实行T+0交易制度,结算周期短,市场流动性强。

4. 外资持续流入

印度股市的外资持股比例高达38%,外资的持续流入为市场提供了充足的流动性和增长动力。高盛、巴克莱等国际机构均看好印度股市,认为其具有“该地区最好的结构性增长前景”。

5. 多样化的投资机会

印度股市涵盖金融、信息技术、能源、消费品等多个行业,为投资者提供了丰富的选择。Nifty50指数成分股中,金融行业占比最高(32.76%),其次是信息技术(13.76%)和能源(12.12%)。此外,印度还允许境外企业IPO,进一步提升了市场的国际化程度。

印度股市凭借其强劲的经济增长、长期优异表现、完善的投资者保护制度、外资持续流入以及多样化的投资机会,成为全球投资者的热门选择,所以这个市场太适合“追涨杀跌”了!

2.2 制定策略

动量投资的前提是:过去表现良好的股票在不久的将来会继续表现良好。我们策略一句话说明:买入在特定时期(如过去 1 年)表现强劲的股票,并在重新评估投资组合之前持有一定时间(如 1 个月)。具体分解就是:

  • 计算过往回报:计算每只股票 12 个月的回报率。
  • 进行股票排名:根据 12 个月的回报率对股票进行排名。
  • 选择热门股票:挑选收益最高的前 10 种股票。
  • 每月重新平衡:每月重新评估和平衡投资组合。

三、策略执行

接下来我们会用Python帮助您实施该策略,并对该策略进行为期3年的回测,再将其结果与Nifty50指数的买入和持有策略进行收益比较。

步骤 1:数据准备

首先,我们需要收集过去三年 Nifty 50 股票的历史价格数据。在这里,我使用雅虎财经 api获取了过去三年的历史数据。

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

# List of Nifty 50 stock symbols
nifty50_symbols = ["RELIANCE.NS", "HDFCBANK.NS", "INFY.NS", "ICICIBANK.NS", "TCS.NS", "KOTAKBANK.NS", 
                   "HINDUNILVR.NS", "SBIN.NS", "BHARTIARTL.NS", "HDFC.NS", "ITC.NS", "BAJFINANCE.NS", 
                   "ASIANPAINT.NS", "HCLTECH.NS", "LT.NS", "MARUTI.NS", "AXISBANK.NS", "ULTRACEMCO.NS", 
                   "WIPRO.NS", "NESTLEIND.NS", "ONGC.NS", "TITAN.NS", "SUNPHARMA.NS", "M&M.NS", 
                   "POWERGRID.NS", "JSWSTEEL.NS", "TATASTEEL.NS", "TECHM.NS", "HDFCLIFE.NS", "COALINDIA.NS", 
                   "BPCL.NS", "INDUSINDBK.NS", "BAJAJ-AUTO.NS", "IOC.NS", "BRITANNIA.NS", "HEROMOTOCO.NS", 
                   "ADANIPORTS.NS", "DRREDDY.NS", "GRASIM.NS", "CIPLA.NS", "DIVISLAB.NS", "EICHERMOT.NS", 
                   "BAJAJFINSV.NS", "SHREECEM.NS", "TATAMOTORS.NS", "SBILIFE.NS", "ADANIENT.NS", 
                   "DABUR.NS", "VEDL.NS", "APOLLOHOSP.NS"]

# Define the time period
end_date = datetime.today()
start_date = end_date - timedelta(days=365*3)  # Last 3 years

# Fetch data
data = yf.download(nifty50_symbols, start=start_date, end=end_date)['Adj Close']

# Fill missing values
data = data.fillna(method='ffill').dropna()

# Display the first few rows of the data
print(data.head())

步骤 2:实施策略并计算收益

我们用下面的代码来实施动量策略,并计算过去三年的投资组合回报。

def calculate_portfolio_returns(data, top_n=10):
    # Calculate monthly returns
    monthly_returns = data.resample('ME').ffill().pct_change()
    
    # Calculate 12-month returns
    twelve_month_returns = monthly_returns.rolling(window=12).apply(lambda x: np.prod(1 + x) - 1, raw=True)
    
    # Initialize an empty list to store monthly portfolio values
    portfolio_values = []
    
    # Start with an initial capital
    initial_capital = 100000  # 1 lakh
    capital = initial_capital
    
    # Loop through each month starting from the 13th month
    for i in range(12, len(twelve_month_returns)):
        # Get the 12-month returns for the current month
        current_returns = twelve_month_returns.iloc[i]
        
        # Rank the stocks by their 12-month returns
        ranked_stocks = current_returns.sort_values(ascending=False)
        
        # Select the top N stocks
        top_stocks = ranked_stocks.head(top_n).index
        
        # Calculate the equal weight for each stock
        weight = 1 / top_n
        
        # Calculate the portfolio return for the current month
        portfolio_return = (monthly_returns.iloc[i][top_stocks] * weight).sum()
        
        # Update the capital
        capital = capital * (1 + portfolio_return)
        
        # Append the current capital to the portfolio values list
        portfolio_values.append(capital)
    
    # Convert the portfolio values list to a pandas Series
    portfolio_values = pd.Series(portfolio_values, index=twelve_month_returns.index[12:])
    
    return portfolio_values

# Calculate the portfolio returns
momentum_portfolio_returns = calculate_portfolio_returns(data)

# Display the portfolio returns
print(momentum_portfolio_returns)

步骤 3:与 Nifty 50 指数比较

为了评估动量策略的表现,我们将其与同期 Nifty 50 指数的收益率进行了比较。

# Fetch Nifty 50 index data
nifty50_index = yf.download("^NSEI", start=start_date, end=end_date)['Adj Close']

# Calculate Nifty 50 monthly returns
nifty50_monthly_returns = nifty50_index.resample('ME').ffill().pct_change()

# Calculate Nifty 50 cumulative returns
nifty50_cumulative_returns = (1 + nifty50_monthly_returns).cumprod()

# Calculate momentum portfolio cumulative returns
momentum_cumulative_returns = (1 + momentum_portfolio_returns.pct_change()).cumprod()

# Plot the results
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 6))
plt.plot(momentum_cumulative_returns, label='Momentum Portfolio')
plt.plot(nifty50_cumulative_returns, label='Nifty 50 Index', linestyle='--')
plt.title('Momentum Portfolio vs Nifty 50 Index')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.grid(True)
plt.show()

四、结果与分析

下图显示了动量投资组合与 Nifty 50 指数在过去三年中的累计回报率对比。以下是一些主要观察结果:

  • 在此期间,动量投资组合的表现普遍优于 Nifty 50 指数,显示了动量策略的有效性。
  • 在一些波动时期,动量投资组合经历了大幅波动,这是动量型策略的典型特征。
  • 总体而言,与单纯持有 Nifty 50 指数相比,动量策略的投资回报率更高。

五、观点总结

过去三年,基于Nifty 50股票的动量投资策略表现亮眼。通过筛选12个月回报率最高的前10只股票,并每月进行投资组合再平衡,该策略成功跑赢了Nifty 50指数。然而,历史表现并不能保证未来收益,投资者在采用这一策略前,务必评估自身风险承受能力和投资目标,谨慎决策。

  • 动量投资策略:依赖于过去表现良好的股票在未来可能继续表现良好的理论,通过选择和持有表现最佳的股票来实现超额回报。
  • 策略实施:通过选择 Nifty 50 指数股票,计算和排名股票的历史回报率,选择表现最佳的股票,以及定期重新平衡投资组合来执行策略。
  • 回溯测试:使用 Python 对动量策略进行了历史数据的回溯测试,证明了该策略在过去三年中的有效性和优于 Nifty 50 指数的表现。
  • 风险提示:虽然动量策略在历史上表现良好,但过去的表现并不保证未来的结果,投资者应谨慎考虑个人的风险承受能力和投资目标。

感谢您阅读到最后,希望本文能给您带来新的收获。祝您投资顺利!如果对文中的内容有任何疑问,请给我留言,必复。


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/961419.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Proteus仿真】【51单片机】多功能计算器系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、LCD1602液晶显示 2、矩阵按键​ 3、加减乘除,开方运算 4、带符号运算 5、最大 999*999 二、使用步骤 基于51单片机多功能计算器 包含:程序&…

链表的介绍

目录 引言优缺点与链表相似的数据结构注意事项单向链表的实现基础实现创建类创建成员变量创建特殊方法 增加数据push_back方法insert方法 删除数据del_back方法del_index方法 clear方法查询数据at方法与重载的中括号运算符toArray方法indexOf方法 修改数据获取链表大小测试方法…

【AIGC学习笔记】扣子平台——精选有趣应用,探索无限可能

背景介绍: 由于近期业务发展的需求,我开始接触并深入了解了扣子平台的相关知识,并且通过官方教程自学了简易PE工作流搭建的技巧。恰逢周会需要准备与工作相关的分享主题,而我作为一个扣子平台的初学者,也想探索一下这…

DeepSeek-R1部署教程(基于Ollama)

虽说在过年,但不能忘了学习。这几天科技圈最火的莫过于deepseek,我抽空也学习一下deepseek的部署过程。 1、下载Ollama并安装 https://github.com/ollama/ollama/releases/latest/download/OllamaSetup.exe 下载好后双击直接运行。 2、安装deepseek …

jenkins-k8s pod方式动态生成slave节点

一. 简述: 使用 Jenkins 和 Kubernetes (k8s) 动态生成 Slave 节点是一种高效且灵活的方式来管理 CI/CD 流水线。通过这种方式,Jenkins 可以根据需要在 Kubernetes 集群中创建和销毁 Pod 来执行任务,从而充分利用集群资源并实现更好的隔离性…

力扣面试150 快乐数 循环链表找环 链表抽象 哈希

Problem: 202. 快乐数 👩‍🏫 参考题解 Code public class Solution {public int squareSum(int n) {int sum 0;while(n > 0){int digit n % 10;sum digit * digit;n / 10;}return sum;}public boolean isHappy(int n) {int slow n, fast squa…

【C++】设计模式详解:单例模式

文章目录 Ⅰ. 设计一个类,不允许被拷贝Ⅱ. 请设计一个类,只能在堆上创建对象Ⅲ. 请设计一个类,只能在栈上创建对象Ⅳ. 请设计一个类,不能被继承Ⅴ. 请设计一个类,只能创建一个对象(单例模式)&am…

LLM 推理

https://www.bilibili.com/video/BV16yqeYhELh/ 大模型推理加速目标:高吞吐、低延迟 TGI vLLM SGLang LMDeploy 商汤 和 上海人工智能实验室 一起开发 缺点 性能对比 分析总结 https://www.bilibili.com/video/BV16yqeYhELh/ 大模型推理加速目标:高吞吐…

UE(UltraEdit) 配置简易C/C++编译运行环境

该类型其他帖子 EmEditor 配置简易C/C 编译运行环境_emeditor 代码运行-CSDN博客 RJ TextEd 配置简易C/C 编译运行环境-CSDN博客 这种配置适合ACM竞赛,即要求不使用现代IDE,又想用一个比较好用、至少支持代码高亮的编辑器。 前提条件 1.Mingw GCC 已…

XSS 漏洞全面解析:原理、危害与防范

目录 前言​编辑 漏洞原理 XSS 漏洞的危害 检测 XSS 漏洞的方法 防范 XSS 漏洞的措施 前言 在网络安全的复杂版图中,XSS 漏洞,即跨站脚本攻击(Cross - Site Scripting),是一类极为普遍且威胁巨大的安全隐患。随着互…

Alfresco Content Services dockerCompose自动化部署详尽操作

Alfresco Content Services docker社区部署文档 Alfresco Content Services简介 Alfresco Content Services(简称ACS)是一款功能完备的企业内容管理(ECM)解决方案,主要面向那些对企业级内容管理有高要求的组织。具体…

LCR 139.训练计划 I

目录 题目过程解法双指针法(两端开始)快慢指针 题目 教练使用整数数组 actions 记录一系列核心肌群训练项目编号。为增强训练趣味性,需要将所有奇数编号训练项目调整至偶数编号训练项目之前。请将调整后的训练项目编号以 数组 形式返回。 过…

AboutDialog组件的功能和用法

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了AlertDialog Widget相关的内容,本章回中将介绍AboutDialog Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的AboutDialog是一种弹出式窗口,和上一章回中介绍的Al…

Redis学习之哨兵二

一、API 1.sentinel masters:展示被监控的主节点状态及相关的统计信息 2.sentinel master <master name>:展示指定的主节点的状态以及相关的统计信息 3.sentinel slaves <master name>:展示指定主节点的从节点状态以及相关的统计信息 4.sentinel sentinels <mas…

03链表+栈+队列(D2_栈)

目录 讲解一&#xff1a;栈 一、基本介绍 二、代码示例 ------------------------------ 讲解二&#xff1a;单调栈 一、基本介绍 二、适用场景 三、情形示例 1. 寻找左边第一个小于它的数 2. 寻找左边第一个小于它的数的下标 3. 寻找右边第一个大于它的数 4. 寻找右…

春晚魔术中的数学知识

蛇年春晚刘谦魔术又和大家普及了一下编程中的冒泡排序法&#xff0c;思考深入一点&#xff0c;它还涉及到群论和组合数学中的一些知识。 游戏规则和操作步骤&#xff0c;任意打乱三种餐具作为初始状态&#xff1a; 1.筷子和左边的东西互换&#xff0c;如果筷子就在左边&#…

OpenCV:开运算

目录 1. 简述 2. 用腐蚀和膨胀实现开运算 2.1 代码示例 2.2 运行结果 3. 开运算接口 3.1 参数详解 3.2 代码示例 3.3 运行结果 4. 开运算应用场景 5. 注意事项 6. 总结 相关阅读 OpenCV&#xff1a;图像的腐蚀与膨胀-CSDN博客 OpenCV&#xff1a;闭运算-CSDN博客 …

基于Springboot的健身房管理系统【附源码】

基于Springboot的健身房管理系统 效果如下&#xff1a; 系统登陆页面 管理员主页面 器材类型管理页面 健身房管理页面 教练管理页面 用户管理页面 个人信息页面 课程管理页面 研究背景 随着健康意识的不断增强和人们生活水平的提高&#xff0c;健身房已经成为了现代城市中不…

扣子平台音频功能:让声音也能“智能”起来。扣子免费系列教程(14)

在数字化时代&#xff0c;音频内容的重要性不言而喻。无论是在线课程、有声读物&#xff0c;还是各种多媒体应用&#xff0c;音频都是传递信息、增强体验的关键元素。扣子平台的音频功能&#xff0c;为开发者和内容创作者提供了一个强大而灵活的工具&#xff0c;让音频的使用和…

初始Python篇(8)—— 异常

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; Python 目录 异常介绍 异常的处理 try-except try-except-else try-except-else-finally 异常的抛出 常见的异常类型 异常介绍 在…