简介:这是一份面向高校学生与量化投资初学者的深度学习实战项目包,可作为毕业设计、期末大作业或人工智能课程实践参考,帮助读者理解如何将神经网络应用于股票价格预测与交易策略开发。压缩包共46个文件,约216KB,以23个Python源码为核心,辅以xml工程配置、csv策略与行情数据、sqlite与db数据库文件、md说明文档及txt依赖清单,覆盖数据读取、模型构建、策略执行与模拟交易等环节。项目围绕数据预处理、RNN/LSTM等模型搭建、训练调优及历史回测评估展开,代码按分析、深度学习网络、策略、模拟运行等模块分层组织,并配有单元测试与依赖说明,便于读者梳理完整工程结构、理解量化策略从数据到回测的实现链路。目前已有133人学习下载,适合希望打通深度学习与金融量化交叉知识、积累可运行项目经验的读者参考。
1. 从一份 600519 的 CSV 说起:这套深度学习量化策略包到底能跑出什么
很多人第一次接触量化投资,都是从一份贵州茅台的日线 CSV 开始的。你手里这个基于深度学习的量化投资策略.zip,本质上就是一条从原始行情到模拟交易信号的完整链路:data/600519.SH.CSV是原料,process/csv2sqlite.py把 CSV 灌进 SQLite,analysis/stock.py做指标计算,DL/network.py搭深度学习网络,strategy/Strategy.py把预测转成买卖动作,最后simulate_RUN.py跑一遍模拟。它不是一个能直接下单的实盘系统,而是一个结构清晰、可拆可改的毕业设计级工程骨架,适合做期末大作业、课程设计,或者作为你自己策略原型的起点。如果你正卡在“深度学习怎么和量化投资结合”这个点上,这份代码能让你少走一段从零搭架子的路。
2. 拆开压缩包先看什么:目录结构与模块职责
2.1 核心文件清单与调用关系
拿到一个陌生项目,我习惯先看入口文件和依赖,而不是急着跑。这个包里main.py和simulate_RUN.py是两个入口,前者偏策略执行,后者偏模拟回测。requirements.txt决定了你能不能顺利装环境,README.md和Sight.md是作者留下的说明,先扫一遍能省很多猜的时间。
| 路径 | 职责 | 是否核心 |
|---|---|---|
main.py | 策略主执行入口 | 是 |
simulate_RUN.py | 模拟交易运行入口 | 是 |
ML.py | 深度学习模型相关逻辑 | 是 |
DL/network.py | 网络结构定义 | 是 |
DL/GPU.py | GPU 相关配置 | 视环境 |
analysis/stock.py | 股票数据读取与指标 | 是 |
analysis/draw.py | 绘图 | 否 |
process/csv2sqlite.py | CSV 转 SQLite | 是 |
process/SQLFrame.py | SQL 数据帧封装 | 是 |
strategy/Strategy.py | 策略逻辑 | 是 |
strategy/chost.py | 策略辅助模块 | 视情况 |
data/600519.SH.CSV | 原始行情数据 | 是 |
tests/ | 单元测试 | 建议看 |
从调用关系看,典型链路是:csv2sqlite.py把600519.SH.CSV写入data.sqlite或600519.db,stock.py从库里读数据并算特征,network.py定义网络,ML.py负责训练和预测,Strategy.py根据预测生成信号,simulate_RUN.py串起来跑模拟。你改任何一环,都要顺着这条链往下检查。
2.2 环境准备与依赖安装
requirements.txt是这个项目能不能跑起来的第一道门槛。深度学习项目最怕的就是版本冲突,尤其是 TensorFlow 和 PyTorch 对 Python 版本、CUDA 版本都很敏感。我一般会先建独立虚拟环境,再按文件装依赖。
python -m venv venv # Windows 激活 venv\Scripts\activate # Linux / macOS 激活 source venv/bin/activate pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple第一段建虚拟环境,避免污染全局包;第二段激活环境,Windows 和 Linux 命令不同;第三段用国内镜像装依赖,速度会快很多。如果requirements.txt里没有锁死版本号,装完最好pip freeze > requirements_lock.txt存一份,方便复现。
提示:如果安装过程中报某个包找不到对应版本,先看它的版本号是不是写死了。常见做法是把该行改成不指定版本,让 pip 自己选兼容版本,再观察后续是否报错。
2.3 数据从 CSV 到 SQLite 的落库过程
这个项目没有直接用 pandas 读 CSV 就完事,而是多了一步落库,说明作者想让数据查询和复用更方便。process/csv2sqlite.py大概率就是干这件事的。你可以先手动跑一遍,确认数据能正确进库。
import pandas as pd import sqlite3 # 读取 CSV,注意编码和日期列 df = pd.read_csv("data/600519.SH.CSV", encoding="utf-8") # 日期列转成标准格式,方便后续按时间索引 df["date"] = pd.to_datetime(df["date"]) # 写入 SQLite,表名用 stock_600519 conn = sqlite3.connect("data/600519.db") df.to_sql("stock_600519", conn, if_exists="replace", index=False) conn.close() print("rows:", len(df), "cols:", list(df.columns))这段代码做了三件事:读 CSV、转日期、写库。if_exists="replace"表示每次覆盖,适合反复调试;如果你不想丢历史数据,改成"append"。index=False避免把 pandas 索引也写进去。跑完打印行列数,能快速判断数据有没有读歪。
2.4 用 stock.py 做特征与指标计算
analysis/stock.py是数据加工层。量化策略里常见的均线、收益率、波动率,通常都在这一层算。你可以先单独调用它,看看输出长什么样,再决定要不要加自己的因子。
import pandas as pd def add_features(df): # 收盘价简单收益率 df["ret"] = df["close"].pct_change() # 5 日和 20 日均线 df["ma5"] = df["close"].rolling(5).mean() df["ma20"] = df["close"].rolling(20).mean() # 20 日滚动波动率 df["vol20"] = df["ret"].rolling(20).std() # 去掉前面因滚动窗口产生的空值 df = df.dropna().reset_index(drop=True) return df if __name__ == "__main__": raw = pd.read_csv("data/600519.SH.CSV") feat = add_features(raw) print(feat[["date", "close", "ret", "ma5", "ma20", "vol20"]].tail())pct_change()算日收益率,rolling(5).mean()算 5 日均线,rolling(20).std()算 20 日波动率。dropna()会删掉前 19 行,因为均线还没形成。这一步做完,你的特征表就可以喂给网络了。参数上,均线窗口和波动率窗口都可以改,但要注意改完以后样本量会变,训练集划分也要跟着调。
3. 深度学习模型怎么接进策略:网络定义、训练与预测
3.1 DL/network.py 里的网络结构怎么读
DL/network.py是模型定义文件。量化时序数据常见的选择是 LSTM 或一维 CNN,前者擅长捕捉长依赖,后者擅长提取局部形态。你打开文件后,先看它继承的是哪个框架的模块,再看输入输出维度。
import torch import torch.nn as nn class LSTMModel(nn.Module): def __init__(self, input_size=5, hidden_size=64, num_layers=2, output_size=1): super().__init__() # batch_first=True 表示输入形状为 (batch, seq, feature) self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): # out 形状 (batch, seq, hidden) out, _ = self.lstm(x) # 只取最后一个时间步的输出做预测 return self.fc(out[:, -1, :])input_size对应你喂进去的特征数量,比如 close、ret、ma5、ma20、vol20 就是 5。hidden_size是隐藏层维度,越大拟合能力越强但越容易过拟合。num_layers=2表示两层 LSTM。out[:, -1, :]取序列最后一步,表示用过去一段窗口预测下一个点。如果你改成预测多步,output_size要相应调整。
3.2 训练循环与损失函数选择
ML.py大概率包含训练逻辑。量化里做回归常用 MSE,做涨跌分类常用交叉熵。你要先确认标签是什么,再决定损失函数。
import torch import torch.nn as nn from torch.utils.data import DataLoader, TensorDataset def train_model(model, X, y, epochs=50, lr=1e-3, batch_size=32): # 转成 tensor,float32 是深度学习默认精度 X_t = torch.tensor(X, dtype=torch.float32) y_t = torch.tensor(y, dtype=torch.float32).view(-1, 1) loader = DataLoader(TensorDataset(X_t, y_t), batch_size=batch_size, shuffle=True) criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=lr) for epoch in range(epochs): model.train() total_loss = 0.0 for xb, yb in loader: optimizer.zero_grad() pred = model(xb) loss = criterion(pred, yb) loss.backward() optimizer.step() total_loss += loss.item() if (epoch + 1) % 10 == 0: print(f"epoch {epoch+1}, loss {total_loss/len(loader):.6f}") return modelMSELoss适合预测收益率这类连续值。Adam学习率默认 1e-3,比较稳。shuffle=True打乱样本顺序,避免模型记住顺序。每 10 轮打印一次 loss,方便观察有没有发散。如果 loss 一直不降,先检查输入特征有没有归一化,再检查标签有没有对齐。
3.3 训练集、验证集、测试集怎么切
时序数据不能随机打乱切分,否则会用到未来信息,这是量化里最经典的翻车点之一。正确做法是按时间顺序切。
def time_split(X, y, train_ratio=0.7, val_ratio=0.15): n = len(X) train_end = int(n * train_ratio) val_end = int(n * (train_ratio + val_ratio)) return (X[:train_end], y[:train_end], X[train_end:val_end], y[train_end:val_end], X[val_end:], y[val_end:])train_ratio=0.7表示前 70% 做训练,中间 15% 做验证,最后 15% 做测试。这样切出来的测试集在时间上最靠后,更接近真实使用场景。如果你用随机切分,模型可能在训练时见过未来数据,回测结果会虚高,实盘就露馅。
3.4 预测结果怎么转成买卖信号
模型输出的是数值,策略需要的是动作。strategy/Strategy.py负责这一步。常见做法是设定阈值:预测收益大于某个值就买,小于某个值就卖。
def signal_from_pred(pred, buy_th=0.005, sell_th=-0.005): signals = [] for p in pred: if p > buy_th: signals.append(1) # 买入 elif p < sell_th: signals.append(-1) # 卖出 else: signals.append(0) # 持有 return signalsbuy_th和sell_th是阈值,单位是预测收益率。阈值太小吃太多噪声,太大错过机会。你可以先用 0.005 跑一遍,再根据信号数量和回测结果调整。这一步没有标准答案,更多是经验和反复试。
4. 模拟回测怎么跑:simulate_RUN.py 与策略参数
4.1 模拟运行的入口与参数
simulate_RUN.py是回测入口。它一般会读数据、加载模型、生成信号、模拟买卖、输出收益曲线。你第一次跑,建议先把交易成本设为零,确认逻辑通不通,再加成本。
python simulate_RUN.py --data data/600519.db --model DL/model.pth --cash 100000--data指定数据库,--model指定模型权重,--cash是初始资金。如果脚本不支持命令行参数,就打开文件改默认值。跑完看输出目录有没有收益曲线图或交易记录 CSV。
4.2 回测指标怎么看
回测不是只看总收益。我一般会同时看年化收益、最大回撤、夏普比率和交易次数。总收益高但回撤大,实盘很难拿住;交易次数过多,成本会吃掉利润。
| 指标 | 含义 | 关注点 |
|---|---|---|
| 年化收益 | 折算到一年的收益率 | 是否稳定 |
| 最大回撤 | 从高点到低点的最大亏损 | 能否承受 |
| 夏普比率 | 单位风险的超额收益 | 越高越好 |
| 交易次数 | 买卖总次数 | 是否过于频繁 |
| 胜率 | 盈利交易占比 | 结合盈亏比看 |
这些指标如果脚本没直接输出,你可以从交易记录自己算。关键是别只看一个数就下结论。
4.3 策略参数调整的边界
strategy/Strategy.py和strategyDic/default.strategy.csv里通常有策略参数。改参数之前,先想清楚改的是哪一层:是特征窗口、模型超参,还是买卖阈值。每次只改一个,记录结果,否则你分不清是哪个改动起了作用。
# 示例:把均线窗口从 5/20 改成 10/30 df["ma10"] = df["close"].rolling(10).mean() df["ma30"] = df["close"].rolling(30).mean()窗口变大,信号更平滑但更滞后;窗口变小,反应快但噪声多。没有绝对优劣,要结合你的持仓周期。改完记得重新训练模型,因为输入特征变了。
5. 避坑与排查:这份代码最容易翻车的几个地方
5.1 数据时间对齐问题
现象:回测收益异常高,曲线几乎只涨不跌。原因:特征和标签错位,用了未来数据。解决:检查shift方向,确保预测目标在特征之后。常见做法是标签用close.shift(-1),特征用当前及过去数据。
5.2 归一化不一致
现象:训练 loss 正常,预测结果离谱。原因:训练集和测试集用了不同的归一化参数。解决:归一化参数只在训练集上拟合,然后应用到验证集和测试集。不要对全量数据一起归一化。
5.3 模型过拟合
现象:训练集 loss 很低,验证集 loss 很高。原因:模型太复杂或样本太少。解决:减小hidden_size、加 dropout、早停,或者增加数据量。量化数据本身噪声大,过拟合很常见。
5.4 SQLite 路径与权限
现象:跑csv2sqlite.py报找不到文件或无法写入。原因:相对路径基于当前工作目录,不是脚本所在目录。解决:用os.path.dirname(__file__)拼绝对路径,或者确认你在项目根目录执行命令。
5.5 GPU 与 CPU 切换
现象:DL/GPU.py相关代码报 CUDA 不可用。原因:机器没有 GPU 或驱动不匹配。解决:在代码里加device = torch.device("cuda" if torch.cuda.is_available() else "cpu"),把模型和数据都.to(device)。没有 GPU 就用 CPU,小数据量也能跑。
6. 让这套代码真正为你所用:从改一个因子到验证一轮回测
这份代码最大的价值不是它自带的策略,而是它给了你一条可改的链路。你可以从最简单的改动开始:在stock.py里加一个动量因子,重新训练,跑一遍回测,看指标有没有变化。然后换一个网络结构,比如把 LSTM 换成一维 CNN,再跑一遍。每次只改一个变量,记录结果,这样你才能知道什么有效。
# 加一个 10 日动量因子 df["momentum10"] = df["close"] / df["close"].shift(10) - 1 df = df.dropna().reset_index(drop=True)这个因子表示过去 10 个交易日的涨跌幅。加完以后,input_size要从 5 改成 6,训练脚本也要同步改。跑完对比夏普比率和最大回撤,如果变好,说明动量有信息;如果变差,可能是过拟合或者因子冗余。
验证一轮回测是否可信,我一般会做三件事:一是把测试集换成不同时间段,看结果是否稳定;二是把交易成本加上,看利润还剩多少;三是把参数微调一下,看结果是否剧烈变化。如果一改参数结果就天翻地覆,说明策略不稳,实盘要谨慎。
注意:回测好看不等于实盘能赚。这份代码是学习骨架,不是印钞机。用它理解流程、练手改代码,比直接拿去跑实盘更有价值。
从那以后我每次拿到一个新的量化代码包,都会先跑通数据链路,再单独验证模型输出,最后才看回测曲线。顺序反了,很容易被漂亮的收益图带偏。希望这份拆解能帮到你,少踩几个我踩过的坑。
本文还有配套的精品资源,点击获取