基于LSTM的股票价格趋势预测Python仿真代码解析

发布时间:2026/10/3 2:50:03

基于LSTM的股票价格趋势预测Python仿真代码解析 简介压缩包内含基于机器学习预测股票价格趋势的完整Python仿真项目专为毕业设计、期末大作业和课程设计场景打造。项目以LSTM等机器学习方法为核心结合股票指数历史数据完整覆盖数据处理、特征构造、模型训练、预测评估等关键环节。代码包含清晰注释即使是新手也能理解建模思路下载部署后即可复现预测流程适合作为高分课程设计或毕设参考。整个压缩包仅356KB共13个文件5个Python源码文件负责模型实现与训练评估1个Markdown说明文档梳理环境配置与使用步骤1个CSV历史行情数据文件和1个pkl数据集文件供模型直接调用2张PNG图片直观展示预测结果与对比效果另有少量pyc缓存文件。目前已有303人浏览与学习项目得分98分导师认可度高兼具教学与实用价值可帮助读者快速打通“数据—模型—结果”全链路。1. 预测股票价格趋势这份基于机器学习的 Python 仿真代码能干嘛、适合谁刚拆开这个项目压缩包时我第一反应是“又是那种跑个 LSTM 就号称预测股票的玩具”。但把train.py、dataset.py、LSTMModel.py和000001SH_index.csv串起来看了一遍后我得说这是一份适合拿来当毕业设计、期末大作业和课程设计的完整仿真工程不是只有几段零散代码的 demo。它的数据是上证指数日线行情模型走的是 LSTM 时间序列预测路线代码带注释、带训练好的模型文件、带评估脚本甚至还把训练过程的可视化结果放在了img目录里。你下载下来要做的就是补环境、调参数、跑通、换数据。适合谁两类人一类是机器学习方向的学生需要一份能讲清楚“数据怎么切、模型怎么训、结果怎么评估”的完整项目另一类是刚开始接触 Python 量化或时间序列预测的从业者想找一个从数据到预测曲线全链路可复现的参考实现。2. 数据与预处理dataset.py 怎么把行情 CSV 喂给 LSTM2.1 先看数据000001SH_index.csv 里到底有什么整个项目的起点是data/000001SH_index.csv。文件名里的000001SH是上证指数的常见代码写法index表示这是指数日线数据而不是单只股票。拿到数据后不要急着跑模型先花两分钟确认字段和日期范围。我一般会直接用 pandas 读进来扫一眼import pandas as pd df pd.read_csv(data/000001SH_index.csv, encodinggbk) print(df.head()) print(df.tail()) print(df.columns.tolist()) print(df.isnull().sum())这段代码里encodinggbk是第一个可能翻车的点。这类从国内数据源导出的 CSV 大量使用 GBK 编码直接用 pandas 默认的 UTF-8 读取会报UnicodeDecodeError。列名通常是date, open, high, low, close, volume这一组标准 OHLCV 字段isnull().sum()是为了确认有没有空值——如果有要用df df.dropna()或者df.fillna(methodffill)补掉不然后面构造时序窗口时会出现“真空”样本。确认完数据结构后我们真正需要喂给模型的特征通常只取close收盘价。原因很简单趋势预测的首要目标是判断收盘价的走势方向用 OHLCV 全部字段虽然信息更全但特征维度变高后训练曲线会明显波动加大对入门级仿真项目来说得不偿失。这个项目的数据文件只有一根 K 线的字段走的也是“单变量序列预测”路线。2.2 窗口切片与归一化dataset.py 的核心实现dataset.py文件是整个项目里最值得反复读的部分因为 LSTM 的数据组织方式和普通 MLP 完全不同。MLP 的输入是一行样本对应一个标签而 LSTM 的输入要求是“一段连续的时间窗口”。这里我用项目里常见的实现思路把核心逻辑还原一下import numpy as np import torch from torch.utils.data import Dataset class StockDataset(Dataset): def __init__(self, data, seq_len20): self.data data.astype(np.float32) self.seq_len seq_len def __len__(self): return len(self.data) - self.seq_len def __getitem__(self, index): x self.data[index: index self.seq_len] y self.data[index self.seq_len] return torch.from_numpy(x), torch.tensor(y)这里的seq_len是时间窗口长度也就是“用过去多少天的收盘价预测下一天”。20 天是短期均线级别的时间窗口对趋势跟踪来说够用如果你想预测周线级别的趋势可以调到 50 甚至 60。代码里x取的是[index, index seq_len)这个左闭右开区间而y是窗口后一天的真实收盘价这叫“滚动一步预测”。注意没有做数据增强没有加噪声数据量不大时不建议乱加因为金融时序本身就非平稳人为扰动容易破坏真实趋势结构。归一化步骤通常也在这个文件里用MinMaxScaler把价格映射到[0, 1]区间。为什么要归一化LSTM 内部用的是 tanh 激活函数输出范围本身就在[-1, 1]如果你把价格 3000、4000 这样的大数值直接丢进去梯度会在 tanh 的饱和区出现严重的“假死”现象loss 曲线几乎不动。常见做法是from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler(feature_range(0, 1)) price df[close].values.reshape(-1, 1) scaled_price scaler.fit_transform(price)fit_transform是对整个历史数据做的这在单段训练里没有大问题但做多段滚动回测时要注意标准做法是只用训练集数据fit再用同一个 scaler 去transform验证集和测试集防止把测试集的统计量“泄露”到训练阶段。这个 project 里训练集和验证集是同一段数据切出来的影响不大但如果你想拿它改造成真实验证场景务必记下这一点。2.3 训练集和验证集的划分边界这是时间序列任务最容易被新手搞混的地方。分类任务可以train_test_split(random_state42)随机打乱时序预测绝对不行。随机打乱意味着模型在训练时已经看过“未来”的数据模式验证集的评估结果会虚高答辩被老师一追问就露馅。正确做法是按时序顺序切分前 80% 的历史行情做训练中间的 10% 做验证最后 10% 做测试也就是“用过去预测未来而不是用未来预测历史”。train_size int(len(scaled_price) * 0.8) val_size int(len(scaled_price) * 0.1) train_data scaled_price[:train_size] val_data scaled_price[train_size:train_size val_size] test_data scaled_price[train_size val_size:]注意切分要按收盘价序列的原始顺序不要做任何形式的排序。切完后每一个数据点对应的日期索引仍然连续这样StockDataset在构造窗口时窗口内部的时间顺序才是对的。参数方面train_size和val_size比例可以按数据量调整数据长可以适当调到 85/5/10数据短就保持 75/10/15原则是训练集不能太少。另外这个项目里dataset.py下的__pycache__里有dataset.cpython-36.pyc说明原开发环境是 Python 3.6你本地如果是 3.8 以上版本直接删掉__pycache__目录再重新跑即可避免 Python 加载旧字节码后出现莫名其妙的异常。3. 模型结构与训练LSTMModel.py 的参数含义和 train.py 的调参逻辑3.1 为什么是 LSTM先定模型再解释数据在拆LSTMModel.py之前值得花点篇幅说清楚“为什么这个项目选 LSTM”而不是 ARIMA 或者普通全连接网络。ARIMA 是线性模型擅长捕捉价格序列里的线性自相关关系但现实中的行情走势包含明显的非线性特征和长程依赖比如一个上涨趋势往往由跟风资金推动这种“趋势惯性”很难用线性差分方程描述。普通 MLP 的问题是输入长度固定且没有“记忆”你给它 20 天窗口它就只看到这 20 天天与天之间的递进关系被压扁成了独立的 20 个特征丢失了时序本身的先后关系。LSTM 的定位是“带门控记忆的循环网络”它内部有输入门、遗忘门、输出门三个门控机制通过一个携带记忆的 cell state 把前面很多步的有效信息继续保留到当前步。用在股票趋势预测上的直观理解是如果过去 5 天连续放量上涨LSTM 会通过遗忘门决定保留多少“上涨动能”的记忆再通过输入门决定当前这天的数据对记忆的更新权重最后通过输出门决定输出值。这种机制天然适合“趋势延续”或“趋势反转”这类具有状态依赖性的序列问题。这个项目用 LSTM 做预测选型是对的不是单纯为了赶深度学习的时髦。3.2 模型定义的关键参数input_size、hidden_size、num_layersLSTMModel.py里的模型定义看起来短但每个参数都有实际意义。我用这个项目典型的写法把它还原出来import torch.nn as nn class LSTMModel(nn.Module): def __init__(self, input_size1, hidden_size64, num_layers2, output_size1): super(LSTMModel, self).__init__() self.lstm nn.LSTM( input_sizeinput_size, hidden_sizehidden_size, num_layersnum_layers, batch_firstTrue ) self.fc nn.Linear(hidden_size, output_size) def forward(self, x): out, _ self.lstm(x) out out[:, -1, :] out self.fc(out) return out参数含义拆开讲。input_size1表示每个时间步喂入的特征维度是 1因为前面我们只用了收盘价一个特征如果你把 open、high、low、volume 也拼进输入这个值就要改成 4 或 5。hidden_size64是 LSTM 记忆单元的数量决定模型容量隐藏层越大拟合能力越强但越容易过拟合行情数据本身信噪比低64 是个比较平衡的起点。num_layers2是堆叠两层 LSTM第二层把第一层输出的隐藏状态序列作为自己的输入序列能学到更高层的时间抽象特征不是越多越好三层以上在数据量不够时收敛明显变慢。batch_firstTrue表示输入的维度排列是[batch, seq_len, input_size]习惯上我把这条写死为 True避免在构造数据时反复调整张量维序。代码里out[:, -1, :]这行是关键。LSTM 对每个时间步都会输出一个hidden_state但我们做的是“用过去 20 天预测第 21 天”只需要最后一个时间步的输出作为全序列的“汇总特征”再通过nn.Linear映射为一个实数——预测的收盘价。model stock.pkl就是把包括state_dict和scaler在内的对象整体序列化保存下来的结果加载后可以直接 evaluate不需要重新训练。3.3 train.py 训练回路与参数备份train.py的训练回路比较常规但有几个参数值得单独拎出来讲。完整的关键训练代码如下model LSTMModel(input_size1, hidden_size64, num_layers2) criterion nn.MSELoss() optimizer torch.optim.Adam(model.parameters(), lr0.001) num_epochs 100 for epoch in range(num_epochs): model.train() for batch_x, batch_y in train_loader: optimizer.zero_grad() output model(batch_x) loss criterion(output, batch_y.unsqueeze(-1)) loss.backward() nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0) optimizer.step()四件事说明一下。第一损失函数用的MSELoss均方误差这是回归任务的标准选择预测价格与真实价格之间的平方差越小越好如果你想更侧重“涨跌方向是否判断对”可以改成交叉熵做分类但那是另一个优化目标了。第二lr0.001是 Adam 优化器的常规起始学习率epoch 跑到一半如果 loss 曲线出现剧烈震荡优先把学习率降到 0.0005 而不是去调网络结构。第三clip_grad_norm_这条是我建议大家保留的它对梯度做裁剪防止 LSTM 在 BPTT 反向传播过程中梯度爆炸导致 loss 变成nan。第四batch_y.unsqueeze(-1)是因为模型输出的形状是[batch, 1]而batch_y的形状是[batch]不对齐维度直接算 loss 会报形状不匹配错误。训练过程中保存模型也是必须做的一步。常见做法是每个 epoch 结束后在验证集上算一次 loss连续 5 个 epoch 验证 loss 不降就早停并把最好的那轮参数保存下来。Python 里做保存很简单torch.save({ model_state_dict: model.state_dict(), scaler: scaler }, model/stock.pkl)注意用torch.save保存整个字典对象时文件后缀建议用.pkl或.pt加载时用torch.load读进来再恢复state_dict。不要直接保存模型实例万一换了 Python 或 PyTorch 版本反序列化会报module找不到之类的错误保存state_dict是兼容性最好的选择。3.4 训练后的评估逻辑evaluate.py 在看什么evaluate.py做的事就是把训练好的模型拿回来在测试集上做前向推理然后把预测结果反归一化回原始价格尺度。评估时要用model.eval()模式并且把梯度计算关掉model.eval() with torch.no_grad(): test_pred model(test_x) test_pred scaler.inverse_transform(test_pred.numpy())model.eval()的作用是关闭 dropout 和 batch normalization 在训练时的随机行为保证预测结果稳定可控但 LSTM 在数据量小的时候容易出现“预测值比真实值平滑”的滞后现象也就是预测曲线比真实曲线平移了约一个窗口长度这是测试集上最常见的表现不是代码 bug。后面避坑章节我会展开讲。evaluate.py最终会画出两条曲线真实收盘价曲线和模型预测曲线输出到img/17.png和img/18.png这两张图是你答辩时最直接的展示材料有对比才有说服力。4. 避坑与排查从 PyTorch 版本到数据泄露的常见翻车点4.1 现象跑train.py报错UnicodeDecodeError或者module找不到拿到压缩包直接执行训练最常见的报错是读 CSV 时编码不对或者加载stock.pkl时提示某个类反序列化失败。原因通常是两个CSV 编码不是 UTF-8以及保存的模型是在不同版本 PyTorch 下生成的接口不兼容。解决方法是 CSV 读取时指定encodinggbk或encodinggb18030模型文件则不要强依赖那个现成 pkl而是自己重新训练一轮用自己的参数覆盖保存一份。从项目结构看__pycache__里的cpython-36.pyc已经暗示了这个项目是在 Python 3.6 时代写的你现在装的新环境大概率是 3.9 甚至 3.11旧 pyc 文件直接删掉最省事。4.2 现象loss 曲线几乎水平不动训练梯度消失这种问题大多出在不做归一化或者学习率设置过小。价格原始数值是 3000 多经过 tanh 激活函数后落在饱和区域梯度几乎为 0。解决方法是把输入数据用MinMaxScaler压到[0, 1]区间同时检查学习率不低于1e-4。如果归一化做了 loss 还是不动把num_layers从 2 降到 1 再试层数多时梯度回传路径变长梯度更容易在链式传播里消失。4.3 现象验证集 loss 很低但预测曲线严重滞后整体右移这是时间序列预测最经典的陷阱。原因是窗口长度太长模型其实没学会“趋势判断”而是学会了“复制前一天的数值”。我自己的排查习惯是把窗口长度减半看滞后是否缓解如果减半后滞后明显缩小说明当前seq_len超过了数据的有效记忆长度。另外要检查数据集切分有没有按时间顺序如果你用了train_test_split函数并且没有传shuffleFalse数据被随机打乱模型就等于提前看过了测试集的价格形态训练评估整体虚高。严格按时间顺序切分后曲线才“真实”。4.4 现象loss 变成nan训练中断通常原因是学习率过大导致梯度爆炸或者数据里有NaN值没有清理干净。排查顺序是先df.isnull().sum()检查数据再在 optimizer.step 之前加nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0)最后的兜底手段是学习率降到1e-4。LSTM 在长序列上的 BPTT 梯度累计量很大加上我们只用了单序列数据梯度裁剪基本是标配而不是可选项。4.5 现象预测结果看起来像一条平滑的线完全跟不上实际波动这其实是 LSTM 在低信噪比金融数据上的“正常表现”不是代码坏了。价格趋势预测本质上是回归问题回归输出的期望值天然向均值回归。要改善这个观感可以把 MSE 损失换成HuberLoss它对离群点更鲁棒或者干脆换预测目标从“预测具体价格”改成“预测 N 天后价格相对当前值的涨跌幅标签”这样就从回归变成了二分类问题评价指标换成准确率和 F1。对毕业设计来说在答辩里主动说出“回归模型输出天然平滑所以我同时做了方向准确率统计”反而比只展示一条拟合很好的曲线更有深度。5. 换数据、换参数、验效果的进阶玩法从“跑通”到“讲得清”如果你只是把代码跑出来答辩时只能说我运行成功了。想拿高分至少要会做三件事换数据、改参数、做评估对比。换数据是最快的“伪创新”。讲上证指数的人太多了你可以去下载一只个股的日线数据比如贵州茅台或者招商银行把 CSV 替换成新标的注意列名和字段顺序要和原文件保持一致。新数据拿来后重新执行dataset.py之前的预处理步骤观察不同股票的数据特征怎么影响模型表现。茅台这类高价股的波动率低预测曲线可能比指数更平滑银行股偶尔出现除权缺口归一化后窗口切片时会遇到脉冲点这些差异都是你可以在论文里讨论的话题。改参数要成组改不要只改一个数就下结论。你可以固定seq_len20对比hidden_size32/64/128三组结果的验证集 loss再固定hidden_size64对比seq_len10/20/40。把结果画在同一张图上会发现窗口增加时模型更平滑但滞后更严重隐藏层越大收敛越慢但未必更准。这些结论讲出来比“我调参后准确率提高了”这种空话有说服力得多。验证指标上除了看测试集 loss我建议额外算两个数字方向准确率预测值和真实值相对前一天的涨跌方向是否一致和最大回撤对比。方向准确率能直接说明模型“趋势判断”的价值import numpy as np real test_pred.flatten() true test_y.flatten() direction (np.diff(real) 0) (np.diff(true) 0) acc np.mean(direction) print(f方向准确率: {acc:.2%})这段代码先对预测值和真实值分别做差分再比较差分符号是否一致。注意test_pred要先反归一化回原始价格再算差分在归一化后的[0,1]区间上算方向虽然在数学上等价但答辩时用真实价格展示更容易让老师理解。最后提一句我踩过的坑有次我换数据后忘了重新 fit scaler直接把旧的stock.pkl里的 scaler 拿来 transform 新数据导致预测结果整体偏移了一个常数图上看已经猜不出价格区间了。从那以后我每次都强制走一遍“载入数据 → 重新归一化 → 切窗口 → 重训模型”全流程不在旧模型上偷懒。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/3 2:50:03

HTTP协议核心解析:请求方法、状态码与实战排查

1. HTTP协议的本质:先搞懂它到底在做什么1.1 请求-响应模型:一次交互的完整轮廓HTTP(HyperText Transfer Protocol,超文本传输协议)这个名字看起来学术,但本质上就是客户端和服务器之间“对话”的规矩。你打…

2026/10/3 2:50:03

校园消费行为分析:构建可解释的学生经济画像系统

简介:本资源是一套完整的校园消费行为分析与学生经济评估实战项目,面向Python数据分析初学者及高校数据科学课程实践者,聚焦智慧校园一卡通数据的清洗、建模与可视化全流程。压缩包共24个文件,含6个核心Python模块(dat…

2026/10/3 2:45:03

OFDM信道估计MATLAB实现:从导频插值到均衡全流程解析

简介:面向无线通信与OFDM系统学习者的信道估计实践资源,压缩包共1个MATLAB源文件,约7KB。程序聚焦OFDM接收端的信道估计与均衡流程,覆盖导频插入、去除循环前缀、比较收发导频推断信道频率响应,以及基于LS或相邻导频相…

2026/10/3 3:45:06

paperclip 实战:用 React 模式构建轻量级 AI Agent 框架

1. 从“paperclip”这个名字说起:它到底想解决什么问题第一次看到paperclip这个项目名,我脑子里蹦出来的画面是那个经典的办公小物件——回形针。它不起眼,但几乎每个人的桌上都有一枚,用来把散落的纸张别在一起。放到软件语境里&…

2026/10/3 3:45:06

SQL表设计、管理、性能优化与特殊场景实战全解

SQL表相关的活儿,说难不难,说简单也真不简单。我这些年看了太多项目,表结构设计得乱七八糟,慢查询遍地都是,一个简单的去重需求都能写出四五种错误版本。这篇文章我不打算写成一本SQL大全,那没意思&#xf…

2026/10/3 3:45:06

openrig 配置编排:用 YAML 统一接入 Claude Code 与 Codex

1. openrig 到底是个什么东西第一次看到 openrig 这个名字,我下意识以为是某个硬件机架项目,毕竟 rig 在英文里就是“装配、机架”的意思。但翻了一圈社区讨论和热词关联之后才反应过来,这其实是一个围绕 AI 编程助手做统一接入与编排的开源工…

2026/10/3 3:45:06

Open-Shell 完全指南:让 Windows 11 开始菜单回归经典与高效

Windows 11 的原生开始菜单让我这个从 Windows 7 时代过来的人憋屈了很久——没有磁贴分类、没有一键展开所有程序、右键菜单还得再多点一层。后来接触到 Open-Shell(很多人也直接拼成 OpenShell),这套开源工具才算把 Windows 的桌面体验拉回…

2026/10/3 3:45:06

从零手搓AI工程:PyTorch模型训练与推理优化实战

1. 从零手搓AI工程:为什么我不建议你直接调包很多人一听到“AI工程”这四个字,第一反应就是打开某个云平台,拖几个组件,调几个API,然后跑通一个Demo,就觉得自己已经掌握了。我刚开始也是这么想的&#xff0…

2026/10/3 3:40:05

Agent记忆系统实战:从三层记忆架构到Docker部署与MCP集成

1. 从“hindsight”这个词说起:为什么记忆是Agent落地的最后一公里“hindsight”这个词本身很有意思,字面意思是“事后的洞察力”,也就是我们常说的“后见之明”。把这个词用在一个Agent项目上,指向性其实非常明确:它要…

2026/10/2 8:16:46

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/2 18:20:53

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/3 0:04:31

国内大学生必备的AI写作辅助软件是哪款?

国内高校学生在论文写作过程中,越来越依赖AI辅助工具提升效率,主流方案以本土化全流程工具为核心,结合通用大模型与专业插件,覆盖选题构思、框架搭建、初稿撰写、查重降重、格式调整等关键环节,本文将深入解析当前主流…

2026/10/3 0:04:31

Codex接入Jev模型完整指南:配置方法、本地部署与踩坑排查

最近不少人在讨论 Codex 搭配 Jev 这套玩法,我一开始没太当回事,直到自己把 Jev 接进 Codex跑了几轮编码任务之后,才明白那些说“直接起飞”的人是怎么想的。Codex 作为工具本身已经够能打了,但模型固定、上下文策略固定&#xff…

2026/10/3 0:04:31

GitHub 热门: NVIDIA/Model-Optimizer

👋 Hi,我擅长 AI 大模型应用落地、意识解码与 AI 开发工具链 。 💡 创业路上,用技术换时间,一起把 AI 变成生产力 🚀 >GitHub 热门: NVIDIA/Model-Optimizer 凌晨两点,你刚把跑通了的 Qwen3.…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑