新闻详情

新闻详情

首页 / 资讯中心 / 详情

Python时间序列分析股票预测:从ARIMA到LSTM的完整实现与避坑指南

发布时间:2026/9/28 14:51:15来源:尧图网络
Python时间序列分析股票预测:从ARIMA到LSTM的完整实现与避坑指南
简介这份资源面向金融、数据分析方向的学生与从业者围绕时间序列分析在股票场景中的完整应用展开覆盖从数据获取到策略回测的全流程适合正在完成金融作业或希望系统练习Python量化分析的学习者。包内共9个文件包含5个ipynb、3个py与1个md压缩包约567KBnotebook用于分步演示与结果呈现脚本便于直接运行复用md则提供整体说明。内容涵盖台股近半年股价的均值、标准差、最高最低价及成交量前三名筛选五日每日报价表与EPS条件筛选多数据源合并与前十名涨跌幅统计RSI超买超卖信号检测与多股绘图ARIMA与Prophet的30天股价预测及经验总结以及回测对标和投资组合损益计算。已有1375人学习下载可帮助读者掌握数据抓取、指标计算、信号识别、预测建模与组合评估的完整链路并积累可迁移的排错与调参经验。1. 时间序列分析做股票预测一份能直接跑通的 Python 实现路径很多人第一次接触时间序列分析都是在金融作业或者量化入门项目里题目往往就一句话用 Python 对某只股票做时间序列分析并预测。听起来简单真动手才发现坑一个接一个——数据从哪来、平稳性怎么检验、ARIMA 的 p d q 怎么定、LSTM 又该怎么搭、预测出来的结果为什么和真实价格差一大截。这份实现说明就是冲着这些问题来的目标是把「时间序列分析 股票分析 Python 代码」这条链路完整走一遍从数据获取、平稳性检验、模型选型到预测评估每一步都给可复现的代码和参数解释。适合正在做金融作业的学生也适合想用 Python 量化交易策略代码做入门验证的从业者。下面按实际动手顺序展开不绕弯子。2. 数据获取与预处理把股票数据变成能喂给模型的格式2.1 用 yfinance 或 akshare 拉取日线数据股票时间序列分析的第一步永远是拿到干净的数据。常见做法是用yfinance拉美股用akshare拉 A 股。两者都返回 DataFrame列名略有差异需要统一成date, open, high, low, close, volume这种结构。下面这段代码用 akshare 拉平安银行日线并做基础清洗。import akshare as ak import pandas as pd import numpy as np # 拉取平安银行日线数据adjustqfq 表示前复权 df ak.stock_zh_a_hist(symbol000001, perioddaily, start_date20200101, end_date20241231, adjustqfq) # 统一列名akshare 返回中文列名 df df.rename(columns{ 日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume }) # 只保留需要的列并按日期排序 df df[[date, open, high, low, close, volume]].copy() df[date] pd.to_datetime(df[date]) df df.sort_values(date).reset_index(dropTrue) # 缺失值处理股票数据一般用前向填充 df df.ffill().dropna() print(df.shape, df.head())逻辑说明adjustqfq前复权是关键参数不复权的话除权除息日会出现价格跳空直接破坏时间序列的连续性。ffill()前向填充适合股票数据因为停牌日没有交易用前一天收盘价填充比插值更合理。参数上start_date和end_date建议至少覆盖 3 年以上否则 ARIMA 的季度周期性根本学不出来。2.2 平稳性检验与差分ADF 检验怎么读结果时间序列分析的核心前提是平稳性。股票收盘价几乎一定是非平稳的直接建模会得到虚假回归。ADF 检验Augmented Dickey-Fuller是判断平稳性最常用的方法原假设是「存在单位根序列非平稳」。from statsmodels.tsa.stattools import adfuller def adf_test(series, nameseries): result adfuller(series.dropna(), autolagAIC) print(f{name} ADF Statistic: {result[0]:.4f}) print(f{name} p-value: {result[1]:.4f}) print(fCritical Values: {result[4]}) return result[1] # 对收盘价做检验 p_close adf_test(df[close], close) # 一阶差分后再检验 df[close_diff] df[close].diff() p_diff adf_test(df[close_diff], close_diff)逻辑说明autolagAIC让 statsmodels 自动选择滞后阶数比手动指定更稳。判断标准很简单——p-value 小于 0.05 就拒绝原假设认为序列平稳。实际跑下来收盘价的 p-value 通常接近 1一阶差分后往往降到 0.05 以下。如果一阶差分还不平稳就做二阶差分但二阶差分在股票上很少需要过度差分会丢失长期信息。这里有个血泪经验差分次数不是越多越好d 参数超过 2 基本说明数据本身有问题。2.3 训练集测试集切分时间序列不能随机打乱这是新手最容易翻车的地方。时间序列的切分必须按时间顺序不能像普通机器学习那样train_test_split(shuffleTrue)。常见做法是留最后 20% 作为测试集。# 按时间顺序切分前 80% 训练后 20% 测试 split_idx int(len(df) * 0.8) train df.iloc[:split_idx].copy() test df.iloc[split_idx:].copy() print(f训练集: {train[date].min()} 到 {train[date].max()}, 共 {len(train)} 条) print(f测试集: {test[date].min()} 到 {test[date].max()}, 共 {len(test)} 条)逻辑说明split_idx用整数索引切分保证训练集时间全部早于测试集。如果打乱顺序模型会「看到未来」评估结果虚高这在作业里是致命错误。测试集比例 20% 是常见选择数据量少于 500 条时建议降到 15%否则测试集样本太少评估指标波动大。3. ARIMA 建模p d q 三个参数到底怎么定3.1 用 ACF 和 PACF 图定阶ARIMA 的 p 是自回归项d 是差分次数q 是移动平均项。d 已经通过 ADF 检验确定为 1剩下 p 和 q 靠 ACF自相关和 PACF偏自相关图判断。规则是PACF 截尾、ACF 拖尾用 ARACF 截尾、PACF 拖尾用 MA两者都拖尾用 ARMA。import matplotlib.pyplot as plt from statsmodels.graphics.tsaplots import plot_acf, plot_pacf fig, axes plt.subplots(2, 1, figsize(12, 8)) plot_acf(df[close_diff].dropna(), lags40, axaxes[0]) plot_pacf(df[close_diff].dropna(), lags40, axaxes[1]) plt.tight_layout() plt.savefig(acf_pacf.png, dpi120) plt.show()逻辑说明lags40表示看 40 个滞后阶日线数据一般看 20 到 40 就够。图上蓝色阴影区域是置信区间超出阴影的滞后阶才显著。实际看股票差分序列ACF 和 PACF 往往都在前几阶显著然后快速衰减p 和 q 取 1 到 3 之间比较常见。这里别死磕图形图形只是初筛最终还要靠 AIC/BIC 网格搜索确认。3.2 网格搜索最优 p d q 组合图形法定阶主观性太强工程上更可靠的做法是网格搜索用 AIC 或 BIC 选最优。import warnings from statsmodels.tsa.arima.model import ARIMA warnings.filterwarnings(ignore) best_aic np.inf best_order None best_model None # d 固定为 1p 和 q 在 0-4 之间搜索 for p in range(5): for q in range(5): try: model ARIMA(train[close], order(p, 1, q)) fitted model.fit() if fitted.aic best_aic: best_aic fitted.aic best_order (p, 1, q) best_model fitted except Exception as e: continue print(f最优阶数: {best_order}, AIC: {best_aic:.2f})逻辑说明order(p, 1, q)里 d 固定为 1因为前面 ADF 已经确认一阶差分平稳。AIC 越小模型越好但要注意 AIC 会奖励拟合优度、惩罚参数数量所以不会无脑选高阶。warnings.filterwarnings(ignore)是因为部分阶数组合不收敛会刷屏警告不影响搜索。跑完通常会发现最优阶数在 (1,1,1) 到 (3,1,2) 之间如果搜出来 p 或 q 等于 4要警惕过拟合。3.3 预测与评估MAPE 和 RMSE 怎么算模型定好后用forecast或get_forecast做样本外预测再和测试集对比。from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error # 用最优模型预测测试集长度 forecast best_model.get_forecast(stepslen(test)) pred forecast.predicted_mean.values conf_int forecast.conf_int() # 评估指标 rmse np.sqrt(mean_squared_error(test[close], pred)) mape mean_absolute_percentage_error(test[close], pred) print(fRMSE: {rmse:.2f}, MAPE: {mape:.4f}) # 画图对比 plt.figure(figsize(12, 5)) plt.plot(train[date], train[close], labeltrain) plt.plot(test[date], test[close], labelactual) plt.plot(test[date], pred, labelforecast) plt.fill_between(test[date], conf_int.iloc[:, 0], conf_int.iloc[:, 1], colorgray, alpha0.3) plt.legend() plt.savefig(arima_forecast.png, dpi120) plt.show()逻辑说明get_forecast(stepslen(test))做多步预测predicted_mean是点预测conf_int()给置信区间。RMSE 衡量绝对误差MAPE 衡量相对误差股票预测里 MAPE 在 2% 到 5% 算不错超过 10% 基本说明模型没学到东西。注意 ARIMA 多步预测会快速收敛到均值预测步数越长越平这是模型特性不是 bug。如果作业要求预测未来 30 天建议只信前 5 到 10 天的结果。4. LSTM 建模什么时候该上深度学习4.1 用 MinMaxScaler 做归一化并构造滑动窗口ARIMA 处理线性关系强但股票里有非线性成分LSTM 能捕捉。上 LSTM 前必须做归一化否则梯度爆炸。滑动窗口是把时间序列转成监督学习样本的关键。from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler(feature_range(0, 1)) close_scaled scaler.fit_transform(df[[close]]) def create_sequences(data, window60): X, y [], [] for i in range(window, len(data)): X.append(data[i-window:i, 0]) y.append(data[i, 0]) return np.array(X), np.array(y) window 60 X, y create_sequences(close_scaled, window) X X.reshape((X.shape[0], X.shape[1], 1)) # 按时间切分 split int(len(X) * 0.8) X_train, X_test X[:split], X[split:] y_train, y_test y[:split], y[split:]逻辑说明MinMaxScaler把价格压到 0 到 1fit_transform只在全量数据上做一次严格来说应该只在训练集上 fit但作业场景下差异不大。window60表示用过去 60 个交易日预测下一天这个参数对应约 3 个月是常见选择。窗口太小模型看不到趋势太大训练慢且容易过拟合。reshape成三维是因为 LSTM 输入要求(样本数, 时间步, 特征数)。4.2 搭一个两层 LSTM 并训练from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping model Sequential([ LSTM(50, return_sequencesTrue, input_shape(window, 1)), Dropout(0.2), LSTM(50, return_sequencesFalse), Dropout(0.2), Dense(25, activationrelu), Dense(1) ]) model.compile(optimizeradam, lossmse) early_stop EarlyStopping(monitorval_loss, patience10, restore_best_weightsTrue) history model.fit(X_train, y_train, epochs100, batch_size32, validation_split0.1, callbacks[early_stop], verbose1)逻辑说明第一层 LSTMreturn_sequencesTrue把序列传给第二层第二层return_sequencesFalse只输出最后一步。Dropout(0.2)防过拟合股票数据噪声大dropout 很有必要。EarlyStopping的patience10表示验证损失 10 轮不降就停restore_best_weightsTrue恢复最优权重避免最后一轮过拟合。batch_size32是默认值数据量小可以降到 16。4.3 反归一化并对比 ARIMApred_scaled model.predict(X_test) pred scaler.inverse_transform(pred_scaled) actual scaler.inverse_transform(y_test.reshape(-1, 1)) rmse_lstm np.sqrt(mean_squared_error(actual, pred)) mape_lstm mean_absolute_percentage_error(actual, pred) print(fLSTM RMSE: {rmse_lstm:.2f}, MAPE: {mape_lstm:.4f})逻辑说明inverse_transform把预测值还原到原始价格尺度否则算出来的误差没有意义。实际对比下来LSTM 在短期预测上往往比 ARIMA 好一点但优势没有想象中大而且训练时间长、调参麻烦。如果作业只要求时间序列分析ARIMA 足够如果要求「用深度学习」再上 LSTM。别为了炫技硬上 LSTM调不好还不如 ARIMA。5. 避坑与排查股票时间序列分析最常见的 5 个翻车点5.1 现象模型预测是一条直线原因ARIMA 多步预测会收敛到均值或者 d 参数设错导致模型学不到趋势。解决检查差分次数确认 d 与 ADF 检验一致预测步数控制在 10 步以内如果必须长步预测改用带趋势的模型或 LSTM。5.2 现象MAPE 小于 1% 但预测明显不对原因数据泄漏。常见于归一化时用了全量数据 fit或者切分时打乱了顺序。解决scaler 只在训练集 fit测试集 transform切分严格按时间顺序用iloc而不是sample。5.3 现象LSTM 训练损失不下降原因学习率太大、窗口太小、或者没做归一化。解决确认输入在 0 到 1 之间window至少 30把adam换成adam(learning_rate0.001)显式指定学习率检查数据里有没有 NaN。5.4 现象ADF 检验 p-value 一直大于 0.05原因数据有季节性或者结构突变。解决先做对数变换再差分检查是否有除权除息未复权用seasonal_decompose看趋势和季节性必要时上 SARIMA。5.5 现象akshare 拉数据报错或返回空原因接口限流或股票代码格式不对。解决A 股代码不带前缀如000001加time.sleep(1)避免频繁请求换yfinance拉美股对比测试。这类接口问题没有后悔药只能多试几个数据源。6. 把预测结果落到交易信号一个可验证的进阶技巧模型跑通只是第一步真正有价值的是把预测转成可执行的信号。我一般会用一个简单但有效的规则预测下一日收益率大于阈值就买入小于负阈值就卖出否则持有。下面这段代码把 ARIMA 预测转成信号并做回测。# 用滚动预测生成每日信号 signals [] threshold 0.005 # 0.5% 阈值 for i in range(len(test)): # 用训练集 测试集前 i 天重新拟合模拟实盘 history pd.concat([train[close], test[close].iloc[:i]]) model ARIMA(history, orderbest_order).fit() next_pred model.forecast(steps1).iloc[0] last_close history.iloc[-1] ret (next_pred - last_close) / last_close if ret threshold: signals.append(1) elif ret -threshold: signals.append(-1) else: signals.append(0) test test.copy() test[signal] signals test[ret] test[close].pct_change().shift(-1) test[strategy_ret] test[signal] * test[ret] cum_strategy (1 test[strategy_ret].fillna(0)).cumprod() cum_buy_hold (1 test[ret].fillna(0)).cumprod() print(f策略累计收益: {cum_strategy.iloc[-1]:.4f}) print(f买入持有累计收益: {cum_buy_hold.iloc[-1]:.4f})逻辑说明滚动预测是模拟实盘的关键每次只用当前可见的历史数据重新拟合避免未来函数。threshold0.5%是过滤噪声的阈值太小会被交易成本吃掉太大信号太少。shift(-1)把次日收益对齐到当日信号保证信号和收益的时间对应正确。回测结果通常会发现策略跑不赢买入持有这很正常——股票预测模型的价值不在于稳赚而在于理解序列结构和风险边界。几个参数调整建议阈值可以试 0.3% 到 1%看策略收益和交易频率的平衡best_order如果每次滚动都重新搜索会很慢可以固定为前面网格搜索的结果回测里没扣交易成本实盘要减去手续费和滑点否则结果虚高。我自己的习惯是任何股票预测模型上线前先用滚动回测跑一遍再和买入持有对比跑不赢就老老实实承认模型没学到 alpha别硬吹。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

从银行营销数据到认购概率:Python机器学习建模实战 2026/9/28 15:52:43

从银行营销数据到认购概率:Python机器学习建模实战

简介:基于机器学习的银行客户认购产品预测项目,是一套面向计算机专业毕业设计及项目实战学习的完整可运行源码包。项目围绕银行营销场景下的客户定期存款认购行为,利用数据集完成清洗、可视化、特征构造与模型调优,输出二分类预测…

阅读更多 →
Simplorer与Simulink联合仿真实现PMSM FOC控制实战指南 2026/9/28 15:52:43

Simplorer与Simulink联合仿真实现PMSM FOC控制实战指南

1. 先说清楚:为什么偏要用Simplorer和Simulink联合仿真1.1 纯Simulink模型的“理想病”在Simulink里面搭永磁同步电机(PMSM)控制系统,大家最熟悉的做法是直接拖一个“Permanent Magnet Synchronous Machine”模块,内部…

阅读更多 →
MT32F006与MAX17048的I2C通信实战:从波形异常到稳定读取电量 2026/9/28 15:52:43

MT32F006与MAX17048的I2C通信实战:从波形异常到稳定读取电量

大家好,我前段时间用MT32F006开发板调试MAX17048电量计,从最开始的I2C波形乱飞,到最终稳定读取电池电量、电压和剩余百分比,整个过程踩了不少坑。这篇文章把完整的I2C通信流程、寄存器操作细节和排障经验整理出来,希望…

阅读更多 →
AI日报自动化链路:从定时任务到微信推送的工程实践 2026/9/28 15:52:42

AI日报自动化链路:从定时任务到微信推送的工程实践

1. 这不是“发消息”,而是一套轻量级企业级自动化链路“我给 WorkBuddy 设了个闹钟:每天上午十点半,一份 AI 日报自动送进微信”——这句话乍看像极了个人效率小技巧,但实际拆解下来,它背后是一条横跨AI推理、服务编排…

阅读更多 →
基于ViT的CIFAR10分类实战:源码解析与训练避坑指南 2026/9/28 15:52:42

基于ViT的CIFAR10分类实战:源码解析与训练避坑指南

简介:基于Vision Transformer(ViT)实现CIFAR10分类任务的完整Python源码,面向计算机、通信、人工智能、自动化等专业的学生、教师及从业者,适用于课程设计、毕业设计和深度学习入门进阶。项目将图像切分为patch序列&am…

阅读更多 →
Stewart平台运动学逆解详解:从坐标变换到MATLAB代码实现 2026/9/28 15:52:36

Stewart平台运动学逆解详解:从坐标变换到MATLAB代码实现

搞并联机器人的应该都有这个印象——网上聊Stewart平台正解的资料一大堆,但真轮到自己要写逆解代码的时候,反而要翻半天。我第一次接触这个是在做六自由度运动模拟台的时候,当时最急的还不是控制策略,而是先把一条最基本的链路跑通…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉