社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 量化金融实战:用时间序列动量策略预测股市收益

数据科学实战 • 2 周前 • 59 次点击  

欢迎加入专注于财经数据与量化投研的【数据科学实战】知识星球!在这里,您将获取持续更新的《财经数据宝典》和《量化投研宝典》,这两部宝典相辅相成,为您在量化投研道路上提供明确指引。 《量化投研宝典》精选了业内持续维护且实用性强的开源工具(Backtrader、Qlib、VeighNa等),配合详细教程与代码示例,帮助您快速构建量化策略;《财经数据宝典》则汇集了多年财经数据维护经验,全面介绍从 AKShare、Tushare 到 Wind、iFind 等国内外数据源,并附有丰富的使用技巧。 无论您是量化投资新手还是经验丰富的研究者,星球社区都能帮您少走弯路,事半功倍,共同探索数据驱动的投资世界!

引言

在量化金融领域,时间序列动量策略是一种经典的投资方法,它基于"强者恒强,弱者恒弱"的市场规律。今天,我们将通过 Python 实现一个完整的时间序列动量分析项目,从数据获取到模型评估,帮你掌握机器学习在金融领域的实际应用。

本文将带你构建线性回归模型来预测未来收益,并通过正则化技术解决过拟合问题,让你深入理解模型优化的核心技巧。

核心概念解析

时间序列动量

时间序列动量策略认为,过去表现良好的资产在未来一段时间内将继续表现良好。这种现象在金融市场中普遍存在,是量化投资的重要基础。

模型的过拟合与欠拟合

  • 欠拟合:模型过于简单,无法捕捉数据中的规律,在训练集和测试集上表现都很差
  • 过拟合:模型过度学习训练数据,包括噪声,在训练集上表现优秀但无法泛化到新数据

正则化技术

正则化通过对模型系数添加惩罚项来防止过拟合:

  • Ridge 回归:将系数压缩至接近零
  • Lasso 回归:可将系数压缩至零,实现特征选择
  • Elastic Net:结合 Ridge 和 Lasso 的优点

实战步骤详解

步骤 1:导入库和获取数据

首先,我们需要导入必要的 Python 库并下载标普 500 指数 ETF(SPY)的历史数据:

import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split, GridSearchCV, RepeatedKFold
from sklearn.preprocessing import MinMaxScaler

# 获取 SPY ETF 的历史市场数据
df = yf.download("SPY", start="2000-01-01", end="2025-01-01")

步骤 2:创建特征变量

接下来,我们构建模型的特征,计算不同时间窗口的历史收益率:

# 计算日收益率
df["Ret" ] = df["Close"].pct_change()
name = "Ret"

# 计算不同时间窗口的滚动复合收益率
df["Ret10_i"] = (df[name].rolling(10).apply(
    lambda x: 100 * ((np.prod(1 + x)) - 1)))  # 10 天收益率
df["Ret25_i"] = (df[name].rolling(25).apply(
    lambda x: 100 * ((np.prod(1 + x)) - 1)))  # 25 天收益率
df["Ret60_i"] = (df[name].rolling(60).apply(
    lambda x: 100 * ((np.prod(1 + x)) - 1)))  # 60 天收益率
df["Ret120_i"] = (df[name].rolling(120).apply(
    lambda x: 100 * ((np.prod(1 + x)) - 1)))  # 120 天收益率
df["Ret240_i"] = (df[name].rolling(240).apply(
    lambda x: 100 * ((np.prod(1 + x)) - 1)))  # 240 天收益率

# 清理数据框,删除不需要的列
del df["Open"]
del df["Close"]
del df["High"]
del df["Low"]
del df["Volume"]
df = df.dropna()

步骤 3:定义目标变量

我们的目标是预测未来 25 天的收益率:

# 创建目标变量:未来 25 天的收益率
df["Ret25"] = df["Ret25_i"].shift(-25)
df = df.dropna()

步骤 4:构建和训练线性回归模型

现在开始构建第一个模型,将数据分为训练集和测试集:

# 分离特征和目标变量
X, y = df.iloc[:, 0:-1], df.iloc[:, -1]

# 划分训练集和测试集(50% 用于测试)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=int(len(y) * 0.5), shuffle=False
)

# 训练线性回归模型
reg = linear_model.LinearRegression().fit(X_train, y_train)

# 进行预测
y_pred = reg.predict(X_train)  # 训练集预测
y_pred_test = reg.predict(X_test)  # 测试集预测

步骤 5:评估模型性能

让我们看看模型的表现如何:

print("样本内性能:")
print("均方误差:%.5f" % mean_squared_error(y_train, y_pred))
print("决定系数(R2):%.5f" % r2_score(y_train, y_pred))

print("\n样本外性能:")
print("均方误差:%.5f" % mean_squared_error(y_test, y_pred_test))
print("决定系数(R2):%.5f" % r2_score(y_test, y_pred_test))

输出结果:

样本内性能:
均方误差:0.05237
决定系数(R2):0.00905

样本外性能:
均方误差:0.03690
决定系数(R2):-0.05915

样本外的负 R² 值表明模型的预测能力极差,存在严重的欠拟合问题。

步骤 6:应用 Elastic Net 正则化

虽然模型存在欠拟合,但应用正则化仍有其价值:它能让模型更稳定,减少对噪声的敏感性。

from sklearn.linear_model import ElasticNet

# 训练 Elastic Net 模型
e_net = ElasticNet(alpha=0.0001, l1_ratio=0.1)
e_net.fit(X_train, y_train)

# 进行预测
y_pred_elastic = e_net.predict(X_test)
mean_squared_error_elastic = np.mean((y_pred_elastic - y_test) ** 2)
print("测试集均方误差(Elastic Net):", mean_squared_error_elastic)

步骤 7:超参数调优

使用网格搜索找到最佳的超参数组合:

model = ElasticNet()
# 设置交叉验证
cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)

# 定义参数网格
grid = dict()
grid["alpha"] = [1e-51e-41e-31e-21e-10.01.010.0100.0]
grid["l1_ratio"] = [00.010.10.20.50.71]

# 执行网格搜索
search = GridSearchCV(model, grid, scoring="neg_mean_squared_error", cv=cv, n_jobs=-1)
results = search.fit(X_train, y_train)

print("最佳 MSE:%.3f" % results.best_score_)
print("最佳参数:%s" % results.best_params_)

案例分析:为什么模型表现不佳?

通过上述实验,我们发现即使经过超参数调优,模型的改进也微乎其微。这个结果揭示了几个重要问题:

1. 线性假设的局限性

股票市场的复杂性远超线性关系所能描述的范围。市场受到宏观经济、政策变化、投资者情绪等多重因素影响,简单的线性模型难以捕捉这些复杂的非线性关系。

2. 信噪比过低

金融数据中的噪声远大于有效信号。仅凭历史价格信息预测未来收益,就像在嘈杂的环境中试图听清微弱的声音。

3. 特征工程的重要性

单纯使用历史收益率作为特征过于简单。实际应用中,我们需要引入更多技术指标,如:

  • 移动平均线
  • RSI(相对强弱指标)
  • MACD(异同移动平均线)
  • 成交量指标

改进方向

基于实验结果,我们可以从以下几个方向改进模型:

1. 丰富特征集

# 示例:添加技术指标
def add_technical_indicators(df):
    # 添加简单移动平均线
    df['SMA_20'] = df[ 'Close'].rolling(window=20).mean()
    df['SMA_50'] = df['Close'].rolling(window=50).mean()
    
    # 添加 RSI 指标
    delta = df['Close'].diff()
    gain = (delta.where(delta > 00)).rolling(window=14).mean()
    loss = (-delta.where(delta 00)).rolling(window=14).mean()
    rs = gain / loss
    df['RSI'] = 100 - (100 / (1 + rs))
    
    return df

2. 尝试非线性模型

考虑使用更复杂的模型,如:

  • 支持向量机(SVM)
  • 随机森林
  • 梯度提升树
  • 神经网络

3. 转换为分类问题

将回归问题转换为分类问题,预测价格涨跌方向而非具体收益率:

# 示例:创建分类标签
def create_classification_labels(returns, threshold=0):
    """
    将收益率转换为分类标签
    返回值大于阈值为 1(上涨),否则为 0(下跌)
    """

    return (returns > threshold).astype(int)

总结

本文通过一个完整的 Python 量化金融项目,展示了如何使用时间序列动量策略预测股市收益。虽然简单的线性模型表现不佳,但这个过程让我们深入理解了:

  1. 金融市场预测的复杂性和挑战性
  2. 模型欠拟合和过拟合的识别方法
  3. 正则化技术的应用场景和局限性
  4. 超参数调优的实施步骤

更重要的是,我们学会了如何科学地评估模型性能,识别问题所在,并思考改进方向。在量化金融领域,失败的实验往往比成功的更有价值,因为它们告诉我们什么方法行不通,指引我们探索新的可能性。

记住,量化投资不是寻找"圣杯",而是在不确定性中寻找概率优势。继续学习,不断实践,你将在这个充满挑战的领域中找到属于自己的投资逻辑。

参考文章

加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取完整研究解析、详细回测框架代码实现和完整策略逻辑实操指南。

财经数据与量化投研知识社区

核心权益如下:

  1. 赠送《财经数据宝典》完整文档,汇集多年财经数据维护经验
  2. 赠送《量化投研宝典》完整文档,汇集多年量化投研领域经验
  3. 赠送《PyBroker-入门及实战》视频课程,手把手学习量化策略开发
  4. 每日分享高质量量化投研文章、代码和相关资料
  5. 定期更新高频财经数据
  6. 参与年度不少于 10 次专属直播与录播课程
  7. 与核心开发者直接交流,解决实际问题
  8. 获取专业微信群交流机会和课程折扣

星球已有丰富内容积累,包括量化投研论文、财经高频数据、 PyBroker 视频教程、定期直播、数据分享和答疑解难。适合对量化投研和财经数据分析有兴趣的学习者及从业者。欢迎加入我们!

好文推荐

1. 用 Python 打造股票预测系统:Transformer 模型教程(一)

2. 用 Python 打造股票预测系统:Transformer 模型教程(二)

3. 用 Python 打造股票预测系统:Transformer 模型教程(三)

4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)

5. 揭秘隐马尔可夫模型:因子投资的制胜武器

6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用

7. 金融 AI 助手:FinGPT 让你轻松掌握市场分析

8. 量化交易秘籍:为什么专业交易员都在用对数收益率?

9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解

10. 掌握金融波动率模型:完整 Python 实现指南

好书推荐

《Python编程:从入门到实践(第3版)》是一本广受欢迎的 Python 入门经典教材,由经验丰富的程序员 Eric Matthes 编写。该书采用循序渐进的教学方式,从基础语法讲解到实战项目开发,内容编排合理,实例丰富,语言通俗易懂。全书配有大量练习题和完整项目实战,包括数据可视化、网络爬虫、Web 应用开发等,让读者在实践中掌握编程技巧。第3版还增加了 f-string、海龟绘图等最新的 Python 特性内容。这本书不仅适合零基础读者入门学习,也非常适合想系统掌握 Python 的编程爱好者以及数据分析、人工智能等领域的学习者。它不仅教授编程知识,更注重培养读者的编程思维,是一本非常值得投资的 Python 学习指南。


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/185461
 
59 次点击