尧图精选

基于深度学习的股票量化交易:从数据清洗到策略回测实战

🕒 发布时间:2026/8/31 15:26:34 📁 来源:尧图网络
简介本资源是一套面向高校人工智能与金融科技方向本科生的毕业设计/课程设计实践项目聚焦深度学习在股票量化交易中的落地应用解决股价趋势预测与自动化策略生成问题。压缩包共49个文件含42个Python源码覆盖数据加载、模型构建、策略回测、实时监控等核心模块、2个Jupyter Notebook含Darts框架深度学习时序建模示例、1份README说明文档、1个pytest配置文件及配套测试脚本、.gitignore与环境配置文件等整体仅2.93MB轻量易部署。已有91人学习下载。读者可直接获得结构清晰的工程化项目骨架包含modelsTFT、TSMixer、DLinear等前沿时序模型实现、utils通用工具函数、strategy交易逻辑与止盈止损模块、monitor实时性能监控脚本等标准化目录以及完整单元测试体系tests下7个测试用例显著降低从理论到代码实现的学习门槛。 我刚开始接触这个领域的时候也跟很多人一样觉得“深度学习炒股”就是玄学加赌博直到自己把一个完整的项目跑通、复盘、再迭代才慢慢摸清楚这里面的门道。今天要聊的这个项目标题就是“基于深度学习的股票量化交易”它不是一个单一的模型脚本而是一整套从数据清洗、特征工程、模型训练到策略回测的闭环流程。这篇文章我会把它拆开揉碎把里面最核心的思路、最容易踩的坑、以及真正能落地的实操细节全部讲清楚。不管你是刚入门深度学习还是已经有量化经验但想引入神经网络这篇内容应该都能给你一些实在的参考。1. 整体设计与思路拆解1.1 为什么是“深度学习 股票量化”传统的量化交易核心逻辑是人肉找规律。比如经典的均线策略、动量因子、价值因子本质上是人根据历史经验总结规律然后用代码去执行。这种做法的问题在于市场规律会变而且因子之间往往有复杂的非线性关系人眼很难看全。深度学习的价值恰恰在这里。神经网络不依赖人工指定特征组合它可以自己从原始数据中学习到高维的、隐藏的模式。比如CNN可以提取局部趋势形态LSTM可以捕捉时间序列上的长期依赖这些是传统线性模型很难做到的。所以这个项目选择深度学习不是因为它听起来高端而是因为股票数据天然具备时序性、非线性和高噪声的特性适合用深度网络去拟合。但也要泼一盆冷水深度学习模型在股票上的应用本质上是在预测一个极低信噪比的信号。大多数时候模型学到的是噪声而不是规律。所以整个项目设计的重心其实不应该放在“模型有多深、多花哨”而应该放在“数据怎么处理、特征怎么构造、回测怎么设计才能不被过拟合骗过去”。这一点我会在后面的章节反复强调。1.2 网络结构选型CNN、LSTM与Transformer的取舍这个项目在模型选型上我建议的思路是先用CNN提取局部特征再用LSTM捕捉时序依赖最后接全连接层输出预测值或分类概率。这种组合在股票短周期预测上是一个比较稳妥的基线方案。为什么不用纯LSTM因为纯LSTM在输入维度较高时训练速度慢而且对局部形态的提取能力偏弱。CNN则擅长在固定窗口内捕捉K线形态比如连续几根阳线、放量突破等模式。把两者串起来可以让模型先“看形状”再“记顺序”逻辑上是说得通的。至于Transformer很多新入场的朋友一上来就想用Attention。但请记住Attention在处理长序列时优势明显但在股票这种噪声极大的短序列场景它的优势并不显著反而容易过拟合。而且Transformer的训练需要更多数据、更多调参经验对初学者并不友好。我个人的建议是把Transformer作为进阶版本去尝试先把手头的CNNLSTM跑通、跑稳。1.3 为什么强调“回测先行”很多人看到“深度学习量化”就急着调参、训模型恨不得一天跑出十组结果。但我看这个项目的第一反应是回测框架搭好了没有数据切分对不对评价指标怎么定回测先行意思是在动手训练模型之前先把一套完整的评估机制建好。包括训练集、验证集、测试集的时间窗口划分手续费和滑点的模拟以及评价指标的选择。没有这套东西你训练出来的模型再“好看”也没法判断它到底能不能用。一个很典型的翻车案例是有人把训练集和测试集从同一时间段里随机切分结果模型在测试集上表现极好因为测试样本和训练样本来自同一个市场状态信息泄漏严重。这个问题在传统机器学习里就被反复提醒过到了深度学习时代反而因为模型更复杂、更容易“背题”变得更加致命。2. 核心细节解析与实操要点2.1 数据源的选取与预处理这个项目的第一步是获取干净的日线或分钟线数据。常见的开源数据源有Tushare、AkShare、baostock各有优劣。Tushare的数据质量高但部分接口需要积分AkShare免费但接口偶尔会变baostock稳定但覆盖范围有限。我的建议是本地缓存一份历史数据到CSV或数据库不要每次训练都去拉接口既慢又不稳定。拿到原始数据后第一步不是直接喂给模型而是做基础清洗。主要处理这几类问题停牌导致的缺失值、极端涨跌导致的异常值、复权因子的计算。尤其是复权如果你直接用不复权的价格训练模型分红送股会产生断崖式下跌或上涨的假信号模型会学到完全错误的“规律”。这里推荐用前复权数据它更贴近实际可交易的视角。清洗完之后数据要按时间顺序排列不要打乱顺序做随机抽样。这是时间序列数据与普通表格数据最大的不同样本之间有先后依赖一旦打乱时序信息就彻底毁了。2.2 特征工程别急着上模型先想想“用什么特征”深度学习虽然能自动提取特征但输入的基础特征仍然决定了模型能学到什么。这个项目里我常用的特征组有三类基础行情特征开盘价、收盘价、最高价、最低价、成交量、成交额。技术指标特征MA5、MA20、RSI、MACD、布林带位置等。这些可以直接用TA-Lib库计算非常方便。衍生特征涨跌幅、量比、振幅、换手率等。把这些特征堆叠成一个多维时间序列矩阵形状类似于(样本数, 时间窗口长度, 特征数)就是三维张量这正好是LSTM和CNN的输入格式。有一个细节必须注意不同特征的量纲差异很大比如价格可能是一百多成交量可能是几千万。如果不做归一化模型训练会非常不稳定甚至梯度爆炸。这里推荐做Z-score标准化也就是对每个特征减去均值除以标准差。而且要注意标准化的均值和标准差必须只用训练集计算测试集和验证集沿用训练集的标准差做变换绝不能混入未来信息。2.3 标签构造预测什么比怎么预测更重要模型要预测什么决定了整个项目的目标是否合理。常见的做法有两种一是回归任务预测未来N天的收益率。优点是输出连续方便排序缺点是噪声大优化目标与交易收益不完全一致。二是分类任务预测未来N天是涨还是跌或者预测三分类涨/跌/平。这种方式更符合交易决策也更容易评估准确率。我个人的经验是用分类任务而且不要预测“明天涨还是跌”而是预测“未来5个交易日累计涨幅是否超过阈值”。这样做的好处是天然做了一次平滑降低了单日噪声的干扰。阈值一般取3%到5%具体看股票的波动率水平。标签构造完成后通常会面临类别不平衡的问题——涨跌样本可能大致均衡但“平”的样本往往太多。处理办法可以是调整阈值或者用加权损失函数让少数类样本的loss贡献更大。3. 实操过程与核心环节实现3.1 模型结构设计一个可跑的基线我直接给出一个在多个项目里验证过比较稳定的结构PyTorch风格描述方便你对着搭import torch import torch.nn as nn class StockNet(nn.Module): def __init__(self, n_features, seq_len60, num_classes3): super().__init__() self.cnn nn.Sequential( nn.Conv1d(n_features, 32, kernel_size3, padding1), nn.ReLU(), nn.MaxPool1d(kernel_size2), nn.Conv1d(32, 64, kernel_size3, padding1), nn.ReLU(), nn.MaxPool1d(kernel_size2) ) self.lstm nn.LSTM(input_size64, hidden_size128, num_layers2, batch_firstTrue, dropout0.3) self.fc nn.Sequential( nn.Linear(128, 64), nn.ReLU(), nn.Dropout(0.3), nn.Linear(64, num_classes) ) def forward(self, x): # x: (batch, seq_len, n_features) x x.permute(0, 2, 1) # 转换为Conv1d需要的格式 x self.cnn(x) x x.permute(0, 2, 1) # 转回 (batch, new_seq_len, channel) out, _ self.lstm(x) out out[:, -1, :] # 取最后一个时间步 out self.fc(out) return out这里设计的关键点是卷积操作采用“窄卷积加池化”的方式让模型逐步压缩时间维度最后把完整窗口的信息浓缩到LSTM的最后一个时间步。kernel_size3表示每个卷积核只看前后相邻的3个K线这是提取局部形态比较自然的窗口大小。池化层则减少计算量同时增加建模的平移不变性。窗口长度seq_len60表示用过去60个交易日的特征去预测未来。60个交易日大约相当于一个季度的交易天数这个窗口长度能覆盖一个短中期趋势的完整形态又不至于因为太长而引入太多噪声。这是我试过多个窗口之后比较折中的一个值建议不要盲目调整。3.2 训练策略与关键超参数训练过程中优化器我选AdamW学习率初始为1e-3用余弦退火调度进行衰减。批次大小在GPU显存允许的情况下尽量取大一般128到256之间即可。损失函数用交叉熵因为预测任务是三分类。为了防止过拟合这里有几个关键手段Early Stopping监控验证集的loss连续10个epoch不下降就停止训练。Dropout在LSTM层和全连接层都加了0.3的dropout作用是随机丢弃部分神经元强迫模型学习更鲁棒的特征。权重衰减AdamW自带的L2正则化防止某些特征的权重异常放大。梯度裁剪LSTM训练时容易梯度爆炸用nn.utils.clip_grad_norm_把梯度范数限制在1.0以内。还有一个非常容易忽略的点训练集和验证集的划分要按照时间顺序而不是随机打乱。我的做法是前70%时间的数据做训练接下来15%做验证最后15%做测试。这样能最大程度模拟“用历史预测未来”的真实场景。3.3 训练过程的现场记录说一下我按照这个流程跑出来的实际感受。大概在40个epoch左右训练集的准确率能到55%左右验证集在48%到52%之间波动。别觉得这个数字低股票三分类的话随机猜是33%能做到50%已经算有明显信号了。关键不在于准确率有多高而在于预测结果与真实涨跌之间是否有稳定的相关性。训练过程中比较重要的信号是loss曲线的走势。如果训练loss持续下降但验证loss不降反升说明模型开始过拟合这时候早停机制会介入。如果训练和验证loss都下不去那就要检查数据预处理和标签构造是否有问题而不是继续调参。最忌讳的是看着训练集loss好看就高兴那只是模型在“背题”。另外一个实操细节是每训练完一个epoch都保存一次模型权重。但不要每个都留只保留验证集上表现最好的那个。这样即使后面的迭代跑崩了也有一个可用的最佳状态。我用这个方式避免过很多次“训练到半夜结果最后一步崩了”的尴尬。4. 回测与策略落地4.1 回测平台选型自研还是用现成框架模型训练出来之后面临的第一个问题是怎么验证它在策略层面能不能赚钱这就需要回测。可选方案无非三类自研回测引擎、第三方回测平台、开源回测框架。自研引擎的好处是逻辑透明、可控性强坏处是容易漏掉细节。比如你没有正确处理停牌、除权除息、涨跌停限制回测结果就会偏向乐观看起来很猛实盘一跑就崩。第三方平台比如聚宽、米筐优点是内置了大量数据、风控模块和券商交易接口适合没时间折腾的人。缺点是策略逻辑会受平台限制而且数据、API版本升级频繁依赖性强。开源框架里我比较推荐qbot它集成了数据源、回测引擎和实盘交易接口而且对AI策略的适配做得比传统回测框架好。如果你坚持用通用框架backtrader也是经典选择社区成熟、文档齐全但对神经网络模型的支持比较原始需要自己写策略逻辑。我的建议是如果只是想验证策略逻辑先在开源框架里跑通全流程如果后面要认真做实盘演练再考虑自研或迁移到专业平台。不要一开始就想着造轮子。4.2 交易信号生成与持仓管理模型输出的三分类概率不能直接当成买入卖出信号。需要做一层“信号平滑”处理。常见做法是当模型连续3个交易日预测“涨”的概率超过60%时才发出买入信号当预测“跌”的概率超过60%时才发出卖出信号。这样可以过滤掉模型频繁切换方向产生的交易噪声。持仓管理上我建议引入仓位控制而不是简单的“满仓干”或“空仓躲”。最简单的方案是以预测概率作为置信度按置信度分配仓位权重。比如看涨概率55%那就20%仓位看涨概率70%那就50%仓位以此类推。这个逻辑很像凯利公式的简化版核心是避免在模型不太确定的时候赌上全部本金。止损是绝对不能省略的环节。无论模型多自信单笔交易的最大亏损不要超过总资金的3%到5%。我在回测里见过太多模型在连续上涨后又连续阴跌的案例如果没有硬性止损线资金曲线的最大回撤会非常夸张直接影响长期复利。4.3 手续费、滑点与涨跌停的现实影响新手做回测最容易忽略的就是交易成本。A股目前的常规费率结构是佣金双边0.025%左右有最低5元的门槛、印花税单边0.05%、滑点按不同流动性从0.01%到0.3%不等。来回一次交易的总摩擦成本保守估计应该在0.15%左右。这是什么概念假设你的策略平均持仓5天年化换手100次摩擦成本就是15%。如果策略本身的年化超额收益只有10%那扣掉成本之后反而是亏的。所以回测引擎里能不能准确模拟费用直接决定了策略回测结果是否可信。我在这个项目里把单边手续费率调成0.1%到0.3%分别跑了两组对比结果差异非常显著——后者几乎把策略利润全部吃光。涨跌停和停牌的处理也很关键。模型可能在涨停板上发出买入信号但实际交易中你可能根本买不进。回测如果不管这个限制就会产生大量“幽灵成交”让收益虚高。正确的做法是开盘价直接涨停的股票不纳入买入候选开盘价直接跌停的股票不纳入卖出候选停牌期间的交易一律视为无效。5. 常见问题与排查技巧实录5.1 模型过拟合回测猛如虎实盘菜如鸡这是深度学习中做量化时最普遍的困境。很多人把回测里漂亮的收益曲线当成了模型能力的证明结果一上实盘就露馅。问题根源在于模型记住了历史数据里的噪声而不是真正的市场规律。排查方法很简单把测试集时间窗口拉长去看几个不同市场状态下的表现。比如分别看牛市段、熊市段、震荡市段的收益和回撤。如果模型只在某一类行情里赚钱那说明它学到的可能是阶段性的市场风格而不是普适规律。解决办法有几个方向一是降低模型复杂度从三层LSTM降成两层甚至一层二是增加Dropout和权重衰减强度三是增加训练数据量把更长时间的历史数据纳入训练四是使用集成学习比如训练多个不同随机种子的模型然后投票这能有效降低单模型的方差。5.2 特征工程中的未来函数陷阱未来函数是量化回测里最隐蔽的坑。简单说就是你在计算某个特征时无意中使用了未来时刻才产生的数据。比如用当天的收盘价计算某个特征然后又把当天的收盘价当成预测目标这就有信息泄漏。一个特别容易踩的坑是对整个数据集先做标准化再划分训练集和测试集。这个操作看起来没毛病但实际上测试集的均值、方差已经参与了标准化计算测试集的信息泄漏到了训练过程中。正确的做法是前面提到的只用训练集计算统计量验证集和测试集都用训练集的统计量来变换。类似的坑还有用未来K线的数据填充当前K线的技术指标比如MA移动平均线计算时误用了未来数值。这些问题在代码review时很难发现需要靠严格的回测框架来规避。5.3 环境配置搭建深度学习环境时最让人崩溃的事说实话很多时候困扰一个深度学习项目的不是模型而是环境。Ubuntu下安装NVIDIA驱动、CUDA、PyTorch版本不匹配的问题能把人折磨到怀疑人生。我在这个项目上踩过最大的坑就是驱动装完以后不生效nvidia-smi命令死活没反应。最后发现是驱动版本和CUDA版本不匹配导致的。这里给一个相对稳的组合Ubuntu 20.04或22.04 NVIDIA驱动535或545分支 CUDA 12.2 PyTorch 2.x。装完驱动后先重启然后执行nvidia-smi确认显卡被识别再装CUDA和cuDNN最后用pip install torch装PyTorch。每一步都验证一下不要一口气全装完再排查。如果你没有本地GPU或者不想折腾驱动也可以直接用AutoDL这类云平台。它们是预装好环境的直接选PyTorch镜像就可以开工。本地环境更适合反复调试和长周期训练云平台则适合资源紧张的时候快速上手。两者结合效率会高很多。5.4 常见问题速查表问题可能原因解决思路训练loss下降到0.3以下但验证集loss升高过拟合增大Dropout、降低LSTM层数、加入早停验证集准确率长期低于40%特征噪声过大或标签不合理调整预测阈值、增加特征、更换时间窗口回测年化收益很高但最大回撤超过30%缺少止损或仓位控制引入硬止损线和分档仓位策略模型在测试集正常但实盘持续亏损市场风格切换或过拟合缩小预测周期、集成模型、更新训练频率nvidia-smi无输出驱动没有正确安装或内核模块冲突重装匹配版本的驱动并重启torch.cuda.is_available()返回FalseCUDA版本与PyTorch版本不匹配重新安装匹配版本的PyTorch写在最后做深度学习量化最关键的心态是别追求完美模型要追求稳定可解释的策略。我给这个项目设计全流程的过程中最深的体会是“慢就是快”。数据清洗做得越细致特征构造考虑得越周全后面的训练和回测就越顺。反而是那些急着把模型跑起来、急着看收益曲线的操作最后往往折在过拟合或者回测失真上。另外再分享一个小的实操技巧模型训练完成后不要只留一个最佳权重把每轮训练过程中表现最好的3到5个模型都保存下来回测时做集成。这样能明显降低单模型的随机性资金曲线会平滑很多。这个细节不算复杂但收益率和体验的提升是实实在在的。如果后续有条件这个项目还可以往两个方向扩展一是引入更丰富的数据源比如新闻情绪、龙虎榜资金流二是尝试用深度强化学习直接在交易策略层面做优化而不只是做涨跌预测。每一步扩展都会带来新的坑但也正是这些坑才让这个领域的探索一直这么有意思。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →