ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Python股票量化系统全解析:数据采集到深度学习选股实战

Python股票量化系统全解析:数据采集到深度学习选股实战 简介这是一套面向计算机相关专业学生与初阶从业者的股票量化分析实战项目适用于毕业设计、课程设计及算法实践场景覆盖数据采集、存储、统计分析、可视化呈现与深度学习建模全流程。资源包共244个文件包含71个核心Python源码实现Tushare数据抓取、技术指标计算、LSTM股价预测等、80个编译后pyc文件、38张分析结果PNG图表、20个配置与缓存JSON文件以及HTML/CSS/JS前端界面组件整体压缩包仅3.52MB轻量易部署。已有375人下载学习代码经实测可直接运行无报错依赖问题。读者可完整获得从原始行情接入到模型训练再到交互式看板展示的端到端实现逻辑尤其适合缺乏金融工程经验但具备基础Python能力的学习者快速构建可演示、可扩展的量化分析系统原型。 最近把自己在跑的股票量化系统整个打包成了压缩包文件名就叫“基于python的股票量化系统采集保存数据分析数据可视化深度学习.zip”。不少朋友下载之后过来问这套东西到底该怎么跑、每个目录是干什么的、里面的深度学习模块是不是真能拿来选股。与其一个个回复不如直接把整套系统的设计思路、模块划分、关键代码和踩过的坑摊开写成一篇文章。这套系统的核心是把一条完整的量化流水线串起来用Python采集行情并保存到本地数据库在数据基础上做技术指标分析和策略回测用可视化看K线、资金曲线和回撤最后通过深度学习模型生成一路独立的预测信号。它适合三类人刚入门量化、想在自己电脑上搭一套完整数据底座的Python开发者已经有了交易经验、但还在用Excel手工分析行情的人以及想了解深度学习在股票数据上到底能做什么、不能做什么的技术爱好者。1. 整套系统拆开来看六个模块的分工与协作1.1 从“看盘工具”到“量化流水线”的模块化思路很多人一开始做量化代码都是散着的。今天写个脚本拉数据存CSV明天在Jupyter里算指标后天又写个独立的回测脚本。看似自由但数据格式不统一、代码逻辑重叠、回测和实盘根本对不上。我打包的这套系统核心就是对这种混乱做一次重构。整个项目被划分成六个模块每个目录只做自己的一件事互相之间通过统一的数据库和配置文件通信而不是互相import来import去stock_quant_system/ ├── 01_data_collector/ # 行情采集日线、分钟线、股票列表、指数 ├── 02_data_storage/ # 数据存储建库、建表、增量更新、数据校验 ├── 03_analysis/ # 分析模块技术指标、信号合成、因子计算 ├── 04_visualization/ # 可视化K线、资金曲线、回撤面板 ├── 05_deep_learning/ # 深度学习特征工程、LSTM训练、预测 ├── 06_backtest/ # 回测引擎向量化回测与绩效评价 ├── config/ # 全局配置文件 ├── scripts/ # 一键执行脚本 └── requirements.txt这种划分遵循一个非常关键的原则单向数据流。采集只负责把数据写进库分析只从库里读数据可视化只消费分析结果深度学习只依赖特征宽表。谁都不直接改上游的数据更不会出现“为了算个指标顺便把采集代码也跑一遍”的情况。1.2 为什么技术栈这样选Python、SQLite和PyTorch的组合逻辑这套系统技术选型上有三个核心决策语言选Python、数据库选SQLite、深度学习框架选PyTorch。不是说它们在所有场景下都是最优解而是对于本地个人量化项目它们组合起来的性价比最高。Python不必多说pandas和numpy已经把时间序列操作简化到了极致相比C或者Java写策略逻辑的迭代速度完全不是一个量级。数据库这块很多人一上来就装MySQL、PostgreSQL其实对个人本地研究来说SQLite完全够用。它不需要独立服务进程文件即库备份就是把文件拷走配合WAL模式并发读也够稳。等后续数据量真的大到SQLite扛不住了再把存储层替换掉SQLAlchemy这类ORM会帮我们屏蔽大部分迁移成本。深度学习框架我选了PyTorch而不是TensorFlow理由很简单动态计算图在调试特征工程和模型输入时友好得多。量化场景的数据处理经常要在训练代码里临时打印中间张量、检查某个维度对不对PyTorch这种命令式的写法更直观。如果你更习惯Keras那种高层封装模块代码也不难改。1.3 压缩包里每个目录的实际职责把模块展开看更清楚。01_data_collector里不是简单调一下接口就完事而是做了统一的数据源封装层。因为行情源经常改接口或者调整权限我在这里用了一个类把akshare、tushare等数据源的差异挡住上层代码永远只调用同一个get_daily(symbol, start_date, end_date)方法。03_analysis是策略研究的主战场里面包含了常见技术指标的计算工具、信号合成函数和一个很轻量的回测器。05_deep_learning则是独立于传统技术分析的另一路信号源它从数据库里读取历史行情构造特征宽表然后训练序列模型输出未来N日的上涨概率。整个系统跑通之后最后会产生一个综合信号真正用于决策的是传统指标信号和深度学习信号的结合而不是单靠某一项。2. 行情数据采集与落库最不起眼却最容易翻车的一环2.1 数据源选取与统一封装层的必要性国内做量化研究数据源基本绕不开akshare、tushare、baostock这几个。akshare免费、接口丰富但偶尔会变tushare数据质量规矩但部分接口有积分门槛baostock免费且稳定但数据范围稍窄。我在系统里做了适配默认推荐akshare因为对新手最友好注册就能用。但我没有直接在业务代码里到处调用akshare而是在02_data_storage外面单独做了一层接口封装。为什么要多此一举因为我吃过接口改版的亏。一度所有采集脚本都直接调某个接口的字段名结果上游一改所有程序跟着崩排查都要半天。加了封装层之后上游变了只改一个文件。# data_source.py 核心思路 import akshare as ak import pandas as pd class AKSDataSource: def get_stock_list(self): df ak.stock_info_a_code_name() return df.rename(columns{code: symbol, name: stock_name}) def get_daily(self, symbol, start_date, end_date, adjustqfq): df ak.stock_zh_a_hist( symbolsymbol, perioddaily, start_datestart_date, end_dateend_date, adjustadjust, ) return df.rename( columns{ 日期: trade_date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume, } ) def get_index_daily(self, symbol, start_date, end_date): df ak.index_zh_a_hist( symbolsymbol, perioddaily, start_datestart_date, end_dateend_date ) return df.rename(columns{日期: trade_date, 收盘: close})这里有个细节采集接口返回的字段普遍是中文列名而数据库存储、后续计算最好统一用英文字段。我在封装层一次性完成列名映射下游所有模块都不用再猜“这列到底叫日期还是trade_date”。2.2 全量历史数据补齐与增量更新历史数据首次采集是全量之后每天只需要增量更新否则每天都拉几千只股票的几年K线既慢又容易被限流。那系统怎么判断该从哪天开始拉思路不复杂每张行情表都维护一个max(trade_date)增量更新时把起始日期设为“最后一个交易日”即可。但有一个坑股票可能停牌最后一条记录不等于它就是最新交易日所以更稳妥的做法是优先从交易日历表里取最近一个未入库的日期。我在系统里放了一张trade_calendar表记录每个交易所的交易日与非交易日。增量更新流程是这样def incremental_update(symbol): latest_date get_latest_trade_date(symbol) next_date get_next_trade_date(latest_date) if next_date is None: return False start next_date.strftime(%Y%m%d) end datetime.now().strftime(%Y%m%d) df source.get_daily(symbol, start, end) save_to_db(symbol, df) return True如果next_date取不到说明很可能数据已经是最新或者临时停牌这时跳出就好不用天天报错。用交易日历驱动增量更新比“用昨天的日期当起点”要稳得多避免因为假期、非交易日产生大量空请求。2.3 复权处理为什么计算必须用后复权、展示可以用前复权股票分红送转后价格会产生跳空如果不做复权处理技术指标的连续性和历史回测的收益计算都会失真。这套系统在采集时默认通过adjust参数取复权数据并区分“后复权”和“前复权”的用途。后复权以历史真实价格为基准价格在时间序列末端被放大。这种数据适合做指标计算和收益测算因为它不受“最新价格”影响历史数据不会因为时间推进而发生变化。前复权以当前价格为基准历史价格被调整。适合展示因为它显示的价格和当前市价差不多在同一量级看图直观。实际使用中我建议底层库默认存后复权数据指标计算和回测都用后复权等到可视化展示K线时再动态切换成前复权。如果只存一套数据我会优先存后复权因为它的历史计算口径稳定不会被分红和除权反复打扰。2.4 数据库表设计与核心索引数据库表结构这步看似简单却直接影响后续所有模块。我在02_data_storage里设计了五张核心表并给常用查询字段建了索引CREATE TABLE stock_basic ( symbol TEXT PRIMARY KEY, stock_name TEXT NOT NULL, list_date TEXT, delist_date TEXT, updated_at TEXT ); CREATE TABLE trade_calendar ( trade_date TEXT PRIMARY KEY, is_open INTEGER NOT NULL ); CREATE TABLE stock_daily ( symbol TEXT NOT NULL, trade_date TEXT NOT NULL, open REAL, high REAL, low REAL, close REAL, volume REAL, amount REAL, PRIMARY KEY (symbol, trade_date) ); CREATE INDEX idx_daily_date ON stock_daily(trade_date); CREATE TABLE stock_minute ( symbol TEXT NOT NULL, trade_date TEXT NOT NULL, minute_time TEXT NOT NULL, open REAL, high REAL, low REAL, close REAL, volume REAL, PRIMARY KEY (symbol, trade_date, minute_time) ); CREATE TABLE factor_values ( symbol TEXT NOT NULL, trade_date TEXT NOT NULL, factor_name TEXT NOT NULL, factor_value REAL, PRIMARY KEY (symbol, trade_date, factor_name) );主键设计成复合主键一是保证数据不重复二是天然把同一股票同一日期的重复插入挡在数据库层面。如果经常做全市场扫描记得在trade_date上再建独立索引否则按日期过滤时全表扫描会很痛苦。3. 数据分析模块把裸K线变成可决策的信号3.1 技术指标计算的向量化思维初学者写技术指标很容易陷入循环算每个点指标一多速度就惨不忍睹。这套系统的03_analysis里统一用pandas的向量化操作把循环降到最低。以布林带为例核心就是滚动窗口的均值和标准差def bollinger_bands(series, window20, num_std2): middle series.rolling(window).mean() std series.rolling(window).std() upper middle num_std * std lower middle - num_std * std return upper, middle, lowerMACD的计算会涉及指数移动平均pandas的ewm方法可以直接搞定def macd(series, fast12, slow26, signal9): ema_fast series.ewm(spanfast, adjustFalse).mean() ema_slow series.ewm(spanslow, adjustFalse).mean() dif ema_fast - ema_slow dea dif.ewm(spansignal, adjustFalse).mean() hist (dif - dea) * 2 return dif, dea, hist向量化之后全市场几千只股票跑常用指标也就是几十秒到几分钟的事这为后续因子分析和深度学习特征构建打好了基础。如果某个指标实在需要用逐行判断比如特殊的信号状态机就尽量用numba这类工具加速不要让纯Python循环成为瓶颈。3.2 一个最简单的信号合成例子均线多头排列指标算完不等于策略。我从分析模块里拿最简单的“均线多头排列”来展示信号是怎么合成的。所谓多头排列就是短期均线在中期均线上方中期均线在长期均线上方通常代表趋势处于强势状态。实现起来很直接def multi_ma_signal(df, short5, mid10, long20): df df.copy() df[ma_short] df[close].rolling(short).mean() df[ma_mid] df[close].rolling(mid).mean() df[ma_long] df[close].rolling(long).mean() df[bull_signal] ( (df[ma_short] df[ma_mid]) (df[ma_mid] df[ma_long]) ).astype(int) df[cross_signal] df[bull_signal].diff().fillna(0) return dfbull_signal是持仓状态1表示满足多头排列0表示不满足。cross_signal则是从0变1的那一刻那才是真正的买入信号点。这里有个容易踩的坑直接对bull_signal取原始1做交易信号会导致每天都重复进场必须用diff()提取状态变化的边界。3.3 回测引擎的轻量实现与绩效评价回测我放了一个轻量级引擎支持向量化回测适合日线级别、数量不多的股票池。这个引擎的逻辑核心是根据信号序列计算持仓状态、逐日收益、累计净值最后输出绩效指标。def run_backtest(price_series, position_series, fee_rate0.0003): returns price_series.pct_change().fillna(0) strategy_returns position_series.shift(1).fillna(0) * returns strategy_returns - (position_series.diff().abs().fillna(0)) * fee_rate nav (1 strategy_returns).cumprod() return nav注意持仓为什么要shift(1)当天收盘算出信号只能次日开盘执行如果当天就用信号交易就是典型的前视偏差回测结果会虚高得离谱。这是所有新手最容易犯的错误。绩效评价部分这套系统至少输出五个指标指标计算逻辑说明累计收益率nav[-1] - 1区间总收益年化收益率(nav[-1]) ** (252 / len(nav)) - 1按年换算最大回撤max(1 - nav / nav.cummax())从峰顶到谷底的最大亏损夏普比率(策略年化收益 - 无风险利率) / 年化波动率每承担一单位风险的超额回报胜率盈利天数 / 总交易天数简单直观最大回撤计算有一个常见的细节nav.cummax()得到历史最高净值序列nav / nav.cummax()就是当前离前期顶点还剩多少比例1减去它再取最大值就是最差情况下从高点回落的幅度。回测成绩好不好先看回撤再看夏普别只看累计收益。3.4 分析结果如何服务下游模块分析模块算出的指标和信号部分会直接进可视化做展示部分会落进factor_values表供深度学习模块使用。我是这样设计的传统技术指标和深度学习特征并不是割裂的很多在深度模型里表现不错的特征本来就来自经典指标的变体比如RSI的滚动均值、布林带的位置百分比、成交量的N日变化率等。所以分析模块在整个系统里其实担任了“特征工厂”的角色。它输出两类东西一类是给人类看的信号比如多头排列、金叉死叉另一类是给模型用的标准化特征表。这样设计的好处是后续加新因子不需要动深度学习代码只需要在分析模块里新增一个计算函数然后注册到特征列表里就行。4. 可视化不只是画图而是发现问题的第一现场4.1 可视化在量化系统里被严重低估的价值我见过不少人做量化完全不做可视化策略跑完直接看一行数字收益。这种做法最大的问题是你根本不知道策略中途发生了什么。收益为正但中间可能经历了一波70%的回撤收益为负但最后一个月其实在暴力回升。这些信息藏在数字背后只有图才能一眼暴露。在我这套系统里可视化承担三个任务第一快速检查行情数据有没有异常比如某天价格跳空明显不合理第二观察策略信号是不是按预期出现在K线上第三评估资金曲线和回撤形态判断策略的稳定性。4.2 K线图与指标叠加的实现方案K线图我默认使用mplfinance单文件就能快速出图非常适合本地研究。想要交互式看K线则建议切到pyecharts或者Plotly后面做Web面板更顺手。一个能反映第一项任务的示例代码长这样import mplfinance as mpf def plot_kline_with_indicators(df, titleK-Line): mpf_style mpf.make_mpf_style( base_mpf_stylecharles, rc{font.sans-serif: [SimHei]}, ) add_plot [ mpf.make_addplot(df[ma_short], color#e63946, width1), mpf.make_addplot(df[ma_mid], color#f4a261, width1), mpf.make_addplot(df[ma_long], color#2a9d8f, width1), ] mpf.plot( df, typecandle, stylempf_style, titletitle, addplotadd_plot, volumeTrue, figratio(16, 9), mav(5, 10, 20), )如果你想在K线图上标注买点卖点通过mpf.make_addplot传入一个由NaN和标记值组成的序列再用typescatter叠加标记点即可。这是看策略信号最直观的方式——K线上出现金叉的那个位置系统是不是真的画了一个买点标记。4.3 资金曲线、回撤曲线的绘制要点资金曲线是策略的体检报告回撤曲线则是体检报告上的异常指标。我习惯把两幅图上下叠放共用横轴时间这样一眼就能看出“某段回撤对应资金曲线的哪一段下跌”。绘制资金曲线时最常用的方式是双对数坐标或者普通对数坐标因为长期来看许多策略的净值有指数特征普通坐标容易被早期高波动态势压制后期的变化。如果策略只跑了一年普通坐标也没问题。回撤曲线的核心代码def drawdown_series(nav): running_max nav.cummax() drawdown nav / running_max - 1 return drawdown在可视化里我会把回撤小于一定阈值的区域填充成浅色低于阈值的区域填充深色让“危险区”一目了然。这是我实际使用时最推荐的一个细节比单纯画一条线有用得多。4.4 从静态图到交互式面板的扩展静态图的优点是快缺点是没办法缩放、查看具体某一天的数值。后期我把可视化扩展成了基于Dash的本地Web面板左侧是股票搜索框右侧是K线图和指标组合底部是策略绩效表格。所有数据从SQLite读取不需要额外的后端服务。实际开发时Pyecharts的Tab组件可以把K线图、资金曲线图、回撤图合并成多页签布局再用Page组件把它们纵向排列做出来就是一个轻量级的“可视化大屏”。这套思路同样适合扩展到其他数据监控场景核心是图表组件化、数据查询统一化、交互状态集中管理。5. 深度学习选股与预测给量化系统装上一个动态大脑5.1 深度学习在量化里的正确定位把深度学习加进股票系统很多人第一反应就是“用LSTM预测明天的股价”。这个想法本身就不太现实。股价的短期变化接近随机游走直接预测具体价格误差大不说还容易把模型学到噪声上。这套系统里深度学习模块的目标非常克制预测未来N日收益率的上涨概率而不是预测价格。预测上涨概率本质上是一个二分类问题模型输出的结果再和传统技术信号做集成。这样做的好处是深度模型不是孤军奋战它只是给决策系统多提供一个维度的视角。我用一个比喻来解释传统技术指标像一个看K线形态的老师傅深度学习像另一个只看数据统计特征的分析师。两人各有偏好、各有盲区但把两人的意见综合起来比单靠其中任何一个都稳。5.2 特征工程深度学习信号的质量源头深度模型吃进去的是特征输出的是概率。特征怎么构造直接决定了模型的上限。我从行情数据里构造了三类特征动量类过去5日、10日、20日的收益率衡量趋势强度。波动率类过去10日和20日的日收益率标准差衡量风险水平。量价关系类成交量相对过去20日均值的放缩比例价格在布林带中的位置百分比。以布林带位置百分比为例它的含义是当前收盘价在布林带区间内的相对位置def bb_position(close, window20, num_std2): mid close.rolling(window).mean() std close.rolling(window).std() upper mid num_std * std lower mid - num_std * std return (close - lower) / (upper - lower)位置接近1代表价格处于区间上沿接近0则处于下沿。这类特征天然带区间约束比裸价格稳定得多。特征构造完必须做标准化因为LSTM这类模型对输入尺度敏感。另外还要注意训练集和测试集的时间切分严禁用未来数据做标准化否则会出现数据穿越。正确做法是只在训练集上计算均值和标准差再用同样的参数去转换测试集。5.3 模型结构选择为什么优先试GRU而不是更复杂的Transformer系统里默认实现了一个两层的GRU模型。相比LSTMGRU参数更少、训练更快在行情数据这种样本量不算特别大的场景下更容易收敛、更不容易过拟合。一个标准的序列模型输入形状是(batch_size, seq_len, num_features)。seq_len我通常设为60也就是用过去60个交易日的特征序列来预测未来5日的上涨概率。这个60不是随便拍的它大约对应一个季度的交易日数能覆盖短期和中期趋势的节奏。import torch import torch.nn as nn class GruPredictor(nn.Module): def __init__(self, num_features, hidden_size64, num_layers2): super().__init__() self.gru nn.GRU( input_sizenum_features, hidden_sizehidden_size, num_layersnum_layers, batch_firstTrue, dropout0.2, ) self.classifier nn.Sequential( nn.Linear(hidden_size, 32), nn.ReLU(), nn.Dropout(0.2), nn.Linear(32, 1), nn.Sigmoid(), ) def forward(self, x): _, h self.gru(x) return self.classifier(h[-1])这里有个容易被忽视的细节GRU输出的h是最后一层的隐藏状态维度是(num_layers, batch_size, hidden_size)所以分类器接的是h[-1]。如果直接接h维度对不上就会报错或者更隐蔽地把多层信息混在一起用错了。5.4 训练过程中的脏坑非平稳、过拟合与标签构造训练深度学习模型做股票预测有三个坑几乎是必踩的。第一个坑是非平稳。股票数据不同于图像和语音它的分布随时间漂移。用2018到2021年数据训练的模型直接拿到2023年预测效果大概率明显下滑。我处理的方法是滚动训练每隔一段时间用最近两三年的数据重新训练模型而不是一次训练永久使用。第二个坑是过拟合。深度网络参数多而股票数据里的有效信号非常稀疏模型很容易记住噪声。除了常规的早停和Dropout最关键的是看验证集和训练集的AUC差距。如果训练集AUC已经0.9以上而验证集只有0.55基本就是过拟合需要降低模型容量或者增强正则化。第三个坑是标签构造。标签的定义会直接影响模型学到的内容。我不用“未来5日收益率是否大于0”这种二分类标签而是加上一个阈值过滤比如“未来5日收益率是否超过同期全市场股票的中位数”。这么做的原因是涨跌概率接近50%的二分类任务模型很难学到显著区分度而相对强弱标签对选股更有指导意义因为股票市场是零和博弈绝对涨跌不如相对排名重要。5.5 从模型输出到实际决策预测结果怎么用模型训练完成后对每只股票输出一个0到1之间的概率值。这个概率值本身不是买卖点而是一个排序信号。我的用法是每天收盘后用模型对股票池内的全部股票打分选出概率值最高的前N只作为备选池再结合传统技术指标的信号比如均线多头排列、MACD金叉等做一次二次过滤最后代入风控规则比如单只股票持仓不超过总资金的一定比例、单日最大回撤达到阈值就强制降仓。深度学习信号和传统信号的关系是互补而不是替代。传统信号擅长捕捉趋势形态深度学习信号擅长从多维特征里学习到非线性关系。两者共同决策时策略的鲁棒性会明显优于单一信号。6. 把这套系统从零跑通的完整流程与问题排查6.1 环境准备最容易卡住的不是Python代码系统默认在Python 3.8到3.11之间测试过。建议用虚拟环境安装依赖避免和系统Python环境互相污染python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install -r requirements.txt如果你在Ubuntu这类Linux发行版上跑并且后续要训练深度学习模型建议先确认NVIDIA显卡驱动和CUDA版本。驱动装好但torch.cuda.is_available()仍然返回False的情况很常见多数是因为PyTorch和CUDA版本不匹配。此时不要急着重装驱动先在Python里执行import torch print(torch.__version__) print(torch.version.cuda) print(torch.cuda.is_available())如果torch.cuda.is_available()为False优先卸载PyTorch然后按官网命令安装对应CUDA版本的包通常问题就能解决。6.2 数据准备先跑通最小闭环再全量拉取我建议第一次跑系统时不要直接全市场拉取先做最小闭环验证。用配置文件里的init_stocks参数只指定两三只股票比如一只银行股、一只消费股、一只科技股先完成“采集→落库→分析→可视化”这条路径确保每个环节都正常。python scripts/init_database.py python scripts/collect_daily.py python scripts/run_analysis.py python scripts/run_visualization.pyinit_database.py负责建库建表collect_daily.py负责采集run_analysis.py计算指标run_visualization.py生成图表。只有首次跑通之后再把股票池扩大到全市场。6.3 深度学习模型训练实验管理训练深度学习模型时我强烈建议使用实验记录功能而不是在命令行里肉眼盯日志。系统里默认集成了一个很轻量的实验管理每次训练都记录下参数、数据版本、模型权重路径、训练AUC、验证AUC方便后续对比。python scripts/train_model.py --seq_len 60 --hidden_size 64 --epochs 30 python scripts/predict.py --model_path checkpoints/gru_20250101.pt训练时有一个常见问题DataLoader的默认线程数过高导致CPU内存爆掉。行情数据虽然不算特别大但特征窗口构造之后数量成倍增长如果内存吃紧记得把num_workers调低甚至设成0。6.4 实际运行中的问题排查表问题现象可能原因解决办法采集数据为空数据源接口变动检查封装层的列名映射和接口参数数据库插入速度很慢没使用批量插入用executemany或pandas.to_sql回测收益异常高信号用了当天数据检查是否对持仓做了shift(1)可视化中文乱码matplotlib缺中文字体指定SimHei或安装中文字体CUDA不可用PyTorch与CUDA版本不匹配按官网命令重装PyTorch模型验证AUC接近0.5特征区分度不足或标签不合理优化特征工程、调整标签阈值模型严重过拟合模型容量太大、样本太少减层数、加Dropout、做早停这张表是我把系统分享出去后收到反馈最多的问题汇总。大部分问题都不是代码逻辑错误而是环境或数据处理细节。6.5 关于这套系统我最后还想多说几句打包这套系统的过程里我最大的体会是量化系统里真正难的不是某一个算法而是把零散的脚本组织成一条可复用、可排查、可成长的数据流水线。采集、存储、分析、可视化、深度学习这五块任何一块单独拎出来都能找到开源方案但把它们串起来之后你会发现很多隐藏的问题——数据口径不一致、时区错乱、复权方式混用、前视偏差悄悄混进回测——这些问题才是拉低策略可信度的真凶。如果后续你打算在这套系统上继续扩展我建议优先做两件事一是引入消息队列把采集任务异步化这样当股票池扩大到几千只时增量更新不会阻塞其他模块二是把目前写的轻量回测引擎换成一个事件驱动的回测框架比如vectorbt或backtrader能支持更复杂的订单类型和资金管理。深度学习这块则可以尝试在特征宽表里加入更多的截面因子让模型从“只看单只股票的时间序列”进化到“同时看全市场横向对比”。那样整套系统的信息量又会翻一番。最后分享一个我自己的使用习惯无论模型给出什么信号我都要求系统强制输出该信号的历史回测绩效摘要。如果模型建议买入某只股票我会先看过去一年里类似概率区间信号出现之后平均收益、最大回撤、持有时长到底是多少。这一条看起来简单实际上帮我过滤掉了大量无效信号也让深度学习模块在整个系统里变得更可解释、更可信。本文还有配套的精品资源点击获取
返回列表