资讯动态

股价预测实战避坑:未来函数、特征工程与回测全解析

发布时间:2026/10/19 14:45:49 来源:尧图企业网站定制
1. 为什么股价预测是看着简单、做着全是坑的领域前阵子有个读者私信我说自己用机器学习预测某只股票第二天的收盘价训练集上R²到了0.97测试集上误差也小得惊人问我是不是可以实盘了。我让他先别急着激动把数据切分方式、是否用到了未来数据、特征里有没有偷看未来的列逐一查一遍结果果然是经典的未来函数泄漏——他把整个数据集归一化之后才切的训练集和测试集归一化的均值和标准差是全体数据的统计量信息早就穿越时间串过去了。这大概是我见过最多、也最隐蔽的坑。股价预测这个方向在机器学习实战圈子里一直有特殊的吸引力。原因很直白数据免费、场景熟悉、结果能直接和真金白银挂钩。相比图像分类、文本情感分析这类项目股票预测有一种业余选手也能上手的错觉——反正K线、成交量、各种技术指标都是现成的拿过来拼成特征矩阵丢进随机森林或者LSTM里跑一下第二天开盘对一对好像就完成了AI炒股的第一步。但从业这么多年我的真实感受是股价预测是低门槛、高迷惑性的典型领域。它看起来什么模型都能用、什么特征都有意义但恰恰因为这样几乎每一步都埋着雷。数据的时间序列属性、标签的定义方式、特征是否包含前视信息、回测时是否考虑了手续费和滑点、模型评估是否可靠——任何一个环节处理不当最终得到的高准确率都只是自欺欺人的数字游戏。这篇内容我想完整地帮你把整条链路拆开从问题定义、数据处理、特征工程、模型选择、回测验证到真实的预期管理。我不会只堆理论而是尽量用实战中会真实遇到的场景来说明。2. 先定义清楚你要预测的到底是什么我见过太多人上来就写一行代码model.fit(X_train, y_train)但问起y到底是怎么构造的就含糊了。很多人认为预测股价就是预测第二天的收盘价是多少钱模型输出一个数值。这当然是一种做法但你要想清楚一个细节直接预测价格数值本质上是在做一个回归任务而回归任务的评估和意义在股票场景里极其容易失真。举个例子某只股票当前价格是50元模型预测明天收盘价50.2元。从误差绝对值来看只有0.4%非常小。但如果你把这只股票换成一只1000元的高价股同样的0.4%误差变成了4元。这种绝对误差在不同价格区间里根本没有可比性。更关键的是价格预测的准确性并不直接等于你能否赚钱——你需要知道的是涨还是跌涨多少而不是精确到几分钱的收盘价。方向对了哪怕预测价格偏保守也能盈利方向错了预测得再精确也是亏损。2.1 价格预测与涨跌方向预测两种任务的本质差异价格回归任务的目标是最小化预测值与真实值的差值常见评估指标是MAE、MSE、RMSE。这类模型的缺点是它对价格水平极其敏感而且天然倾向于预测一个平庸的值——当模型不确定时预测结果会向训练集的均值靠拢。放在股票场景里这意味着模型往往会给出一个不大涨也不大跌的预测这在震荡行情里看着误差很小但在趋势行情里会系统性偏慢。方向预测任务则把问题简化为分类明天是涨1还是跌0或者三分类涨/平/跌。这时评估用准确率、精确率、召回率、F1。好处是目标明确、和交易决策直接挂钩且不会因为绝对价格高低产生偏差。缺点是涨1%和涨8%都算涨模型会放弃对幅度的感知这对于止盈止损、仓位管理其实不够用。所以比较推荐的做法是在实盘或策略研究里用方向分类做信号判断在仓位或止盈计算里辅助一个独立的幅度回归模型。两个模型分开训练、各司其职而不是用一个模型同时扛两件事。2.2 标签构造的细节决定成败方向标签不是简单地明天收盘价比今天收盘价高就是1这里还有几个必须处理的细节比较基准问题明天比今天高这个今天是指今收还是今开如果策略是收盘前买入、第二天收盘卖出那基准应该是次日收盘价对比当日收盘价这是隔夜日内的综合收益。如果策略是开盘买入、收盘卖出那标签应该是当日收盘价对比当日开盘价。不同交易逻辑对应不同标签这个必须和你的策略保持一致。阈值问题直接以0为界会把涨幅0.01%都算成涨这类噪声样本会让模型学得很累。实际中可以设一个阈值比如涨跌幅超过0.3%才标记为1低于-0.3%标记为0中间视为平盘剔除。阈值大小的选择跟品种的波动率有关通常参考该股票近60日的平均波动幅度来定。涨跌停与停牌问题真实行情里存在涨停买不进、跌停卖不出的情况。这些样本直接进入训练集会让模型在极端行情下给出理性的指令但实际交易根本执行不了。数据预处理阶段就要把这些特殊样本标记出来至少先跑通模型再考虑要不要剔除。2.3 评估指标为什么准确率90%也可能没用准确率是大家最关心的指标但它在股价预测里有很大的迷惑性。假设一只股票在训练集覆盖的这段时间里有60%的日子是上涨的。一个无脑预测永远涨的模型准确率直接就是60%。如果你的模型准确率做到63%看起来不错但实际只比永远猜涨强了3个百分点这3个百分点扣掉手续费和滑点之后很可能就是亏损的。所以评估分类模型时我习惯同时看几个东西与多数类基线的对比base rate、F1分数、混淆矩阵、以及预测概率的分布。尤其是概率分布——如果模型给出的预测概率要么接近0.51要么接近0.49说明它本质上对涨跌没有信心你基于这个信号去做交易会频繁被假信号抽脸。好的模型输出的概率应该是两极分化的看涨的时候给0.7以上看跌的时候给0.3以下中间段是它主动承认看不清的部分。3. 特征工程里的未来函数最大的隐性敌人如果说预测目标定义是方向那么特征工程就是这条路上最凶险的暗礁。很多人代码能跑通、loss能下降、测试集分数好看一上实盘就失效八成问题出在特征上——不是特征不够多而是特征里混进了未来信息。所谓未来函数前视偏差简单说就是特征里某个数值在t时刻计算时实际需要用到t1时刻才能知道的数据。这种错误在技术上完全无感模型该收敛收敛、该出结果出结果你甚至会觉得效果特别好——因为模型真的预知了未来。但它一到真实环境就会原形毕露因为实盘时你根本没有那个未来的数值喂给模型。3.1 归一化和标准化必须在时间切分之后做这是最经典、也是最容易犯的错误。很多人在构建数据集时顺手对整个特征矩阵做了StandardScaler让所有特征变成均值为0、方差为1的分布。表面上只是普通的预处理实际上已经把测试集的信息偷渡到了训练集。标准化所用的均值和标准差是包含未来样本统计量的模型在训练时等于间接看到了未来的分布信息测试集成绩自然虚高。正确做法是先将数据按时间顺序切分成训练集、验证集、测试集然后仅在训练集上拟合scaler再用这个scaler分别transform验证集和测试集。sklearn里的Pipeline配合作法先用fit在训练集上做之后transform所有子集。这是整个项目里最不建议偷懒的环节。3.2 滚动指标窗口边界和窗口大小要反复确认技术指标类特征比如移动平均线MA、RSI、MACD、布林带本质上都是对历史窗口做统计计算。这些指标本身不引入未来信息但有一个容易被忽略的点计算时一定要保证窗口内的数据全部是截至当前时刻的历史数据不能包含当前K线还未收盘的实时数据。比如你用日K线数据做特征某一天的RSI如果恰好用了当天收盘后才会更新的数据在实盘当天盘中你是拿不到这个值的。严谨的做法是所有技术指标统一用前一天的完整数据计算。处理这种细节通常需要自己手写特征计算逻辑尽量别直接套用某些现成库里的当前值接口因为它们默认假设整根K线已经收盘。3.3 特征选择与有效性相关性和因果性要拆开看另一个常见误区是特征堆砌。有人会把几十个技术指标全部作为特征丢进模型五颜六色的数据表看着很专业实际上大量特征之间存在高度共线性比如MA5、MA10、MA20天然高度相关。这不仅拖慢训练速度还会让模型变得不稳定——特征矩阵的共线性会让部分模型尤其是线性模型的系数估计方差变大换一段数据结果就漂移。特征选择方面我的做法很朴素先做一遍相关性筛查把相关系数超过0.9的特征聚类成一组每组只保留一个代表性特征然后基于训练集做一次简单的特征重要性筛选随机森林或XGBoost的feature importance只保留重要性排名靠前的特征。这样整个特征量级能从几十个收敛到十几个训练更稳定泛化也更好。4. 模型选型的实战对比别迷信LSTM也别只用最流行的模型选择这个环节几乎每个初学者都会问预测股价用LSTM还是XGBoost我的答案是先从最朴素的模型跑起把基线打到能看的程度再决定要不要上复杂模型。理由是复杂模型的调参空间、过拟合风险、训练成本都更大如果你连简单模型在同样特征下的表现都无法解释复杂模型只会让你更快迷失。4.1 基线模型逻辑回归和线性回归的作用不要小看逻辑回归。在方向预测任务里一个正则化过的逻辑回归加上精挑细选的特征往往能达到和使用复杂模型差不多的效果。它的好处是可解释性极强每个特征的系数直接告诉你哪个指标在模型看来更重要、方向是正还是负。这能帮助你验证特征是否符合直觉——比如RSI超买应该被模型视为下跌信号如果系数方向反了那大概率是特征计算或标签定义出了bug。另一个用途是概率校准。逻辑回归天然给出0到1之间的概率输出这个概率在股票预测中尤其重要因为它可以直接作为仓位大小的依据预测概率0.8意味着模型信心较高可以放大仓位0.55则只适合轻仓试点。树模型虽然也能输出概率但它的概率往往比较粗糙比如在XGBoost里预测概率可能是一串离散值需要额外的校准步骤才能用到实盘信号上。4.2 树模型与集成模型为什么XGBoost通常比想象中好用从实战经验看经过良好特征工程的表格型股价预测任务里XGBoost、LightGBM这类梯度提升树模型综合表现往往优于LSTM。原因在于股价预测的特征大多是结构化表格数据树模型对特征尺度不敏感、能捕捉非线性关系、训练效率高、调参相对直接。以我自己跑过的某只股票为例用同样的特征集做涨跌二分类XGBoost在滚动回测中的F1比LSTM高约2到3个百分点而且训练时间从小时级降到了分钟级。XGBoost还不容易过拟合配合早停early stopping机制基本不太需要担心模型在训练集上死记硬背。LightGBM和XGBoost的取舍上我通常看数据量和特征数。数据量在数万行以内XGBoost比较稳数据量特别大、特征维度高时LightGBM的直方图算法在速度上有明显优势。两者原理上都是梯度提升不用过分纠结。4.3 LSTM与序列模型什么时候值得用LSTM并不是一无是处。它的优势在于可以学习时间步之间的长距离依赖关系理论上比单日特征拼接更能捕捉趋势形态。比如某段连续下跌后放量止跌这种形态模式纯表格特征可能需要你手动构造连续N日跌幅变量而LSTM只要喂足够长的序列窗口理论上可以自己学到。但代价也很明显数据量需求大、训练时间长、超参数多、结果稳定性差。具体到股价预测这个场景日线数据每天只有一根K线即便收集10年也就2500根左右这个体量对LSTM来说非常紧张。用周线数据的话样本量更少几乎没法训练复杂模型。所以我对LSTM的态度很明确先在日线级别用表格模型跑通整体流程如果后续要扩展到分钟级别数据或者要识别更复杂的K线形态模式再引入序列模型不迟。现实中的大部分入门级股票预测项目远没到需要LSTM出场的复杂度。5. 回测里的隐形陷阱前视偏差、过拟合与成本黑洞模型训练完必然要进入回测环节。这一步是很多人最后的心理防线——模型在历史数据上模拟交易的收益曲线漂亮得不像话于是信心爆棚冲进实盘。结果现实几巴掌教做人。这里的原因除了前面说的数据泄漏之外还集中在回测环境的真实性和评估方法这两个方面。5.1 时间序列切分与Walk-Forward验证普通机器学习项目里随机将样本分为训练集和测试集是标准操作但在时间序列数据上这样做是致命的。股价数据在时间上高度自相关随机打乱切分会把前后期数据混在一起模型会看到未来的部分模式测试集成绩不可信。正确做法是严格按照时间顺序切分前70%做训练中间15%做验证用于调参和早停最后15%做测试只在最终评估时用一次。更进一步是Walk-Forward滚动前进验证把时间窗口整体向前滚动例如用第1到第1000天的数据训练预测第1001到1050天然后移动到第51到1050天训练预测第1051到1100天以此类推。这样能模拟模型在真实使用时的迭代过程评估结果更贴近实盘。代价是训练次数翻好几倍但这是值得的。5.2 过拟合识别训练集满分和测试集拉胯的经典症状股价预测模型几乎天然会过拟合——因为纯噪声的数据太多模型总能找到一些看起来有用的随机模式。识别过拟合有几个信号训练集准确率远高于验证集且差距大于5个百分点基本可以肯定在记忆噪声特征重要性集中在某几个特征上换一段数据比如从2020年换到2023年后重要性的排序剧烈变化说明模型学到的模式不稳定预测概率分布长期处于0.5附近模型始终犹豫不决换一个不同市场阶段的数据比如从牛市换到熊市准确率骤降遇到这些信号正则化、减少特征、增加数据量、降低模型复杂度都是常规解法。但如果尝试几轮仍然没有改善就该考虑这个预测目标本身是否可学——这不是模型不够好而是市场和噪声决定了在这个任务上准确率的天花板就在那里。5.3 交易成本与滑点收益曲线里最容易注水的部分很多初学者的回测脚本只算信号收益率今天预测明天涨1%就假设明天赚1%。这完全忽略了交易成本。A股市场买卖双向都有费用印花税、佣金、过户费杂七杂八加起来一次完整交易成本大约在0.1%到0.15%之间。如果策略每天调仓一次一年250个交易日光交易成本就能吃掉30%以上的收益。高频交易策略更是几乎不可能在扣费后盈利。滑点则是另一个成本黑洞你的模型预测某股会涨于是以当前价下单但真实成交价往往比看到的价格差一点尤其在流动差的票上。回测时建议至少按成交价的0.05%到0.1%扣滑点或者用更保守的固定差额法。很多看起来年化50%的策略扣完这些成本后可能年化直接变负数这就是现实和理想之间的差距。6. 从零跑通一个迷你实战流程含避坑注记前面把理论和坑都铺开了这里我再贴一段简化的实战流程帮你把每一步落到代码层面。我用的是公开的开源工具链数据抓取用akshare或yfinance这类库数据处理用pandas模型用scikit-learn和XGBoost。代码不再贴完整版只标注关键环节和注释方便你按图索骥。6.1 数据获取与日线数据清洗获取某只股票近三年的日K数据含open、high、low、close、volume字段。清洗阶段必须处理三件事一是剔除停牌日或把停牌日的涨跌幅置为0并打标记二是确认时间索引无重复、无缺失三是对前后复权价格做处理——送股、配股会导致除权日价格跳空如果不复权技术指标会计算错误如果使用前复权数据要确认整个数据区间内复权因子的一致性避免跨复权基准段的数据拼接后失真。6.2 特征构造与训练集切分顺序特征组我常用这三类基础的价格衍生特征涨跌幅、振幅、成交额变化率、技术指标RSI、MACD、布林带位置、ATR、成交量相关特征量比、换手率、5日量均线比。所有特征统一用截至当前日收盘后可得的数据计算。标签按前面说的2.2节方式定义以阈值法构造涨跌二分类标签。数据切分严格按时间顺序训练集为前70%、验证集15%、测试集15%。StandardScaler只用训练集fit再transform验证集和测试集。如果你用了XGBoost这类树模型可以不标准化但为了后续换成线性模型或神经网络时不踩坑我习惯统一做标准化。6.3 模型训练与验证的代码骨架先上基线逻辑回归然后是XGBoost。XGBoost设置早停轮数比如50轮用验证集评估每个epoch的logloss找到最优迭代次数再回训练集上重训。最后在测试集上算准确率和F1同时打印混淆矩阵。# 伪代码示意训练-验证-测试严格分离 from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from xgboost import XGBClassifier # 假设df已经按时间排序features和labels已构造 split1 int(len(df) * 0.7) split2 int(len(df) * 0.85) train_df df.iloc[:split1] val_df df.iloc[split1:split2] test_df df.iloc[split2:] scaler StandardScaler() X_train scaler.fit_transform(train_df[features]) X_val scaler.transform(val_df[features]) X_test scaler.transform(test_df[features]) y_train train_df[target] y_val val_df[target] y_test test_df[target] # 基线模型 lr LogisticRegression(max_iter1000) lr.fit(X_train, y_train) print(Logistic Regression val acc:, lr.score(X_val, y_val)) # XGBoost early stopping xgb_model XGBClassifier(n_estimators1000, learning_rate0.05) xgb_model.fit(X_train, y_train, eval_set[(X_val, y_val)], early_stopping_rounds50, verboseFalse)回测时每根K线只使用模型在彼时训练集上完成训练的版本对当日作出的预测随后当天按信号执行虚拟交易。整个滚动回测期间反复重新训练模型以此模拟不断用新数据更新模型的真实部署方式。交易模拟里记得扣手续费和滑点。6.4 评估结果该怎么解读跑完上面流程我建议你对最终结果建立正确的预期。方向分类的测试集准确率绝大多数情况下会落在50%到60%这个区间。如果在某只股票上能做到55%以上同时扣掉成本之后回测曲线是斜向上的就已经是相当不错的结果了。如果有人告诉你某模型在测试集上准确率到了80%先不用兴奋大概率是标签泄漏、未来函数或者数据切分出了bug。另外强烈建议看一眼模型在连续下跌行情和连续上涨行情下的表现差异。很多模型在趋势明显的阶段表现良好在震荡阶段则大幅退化。这种不对称性决定了一个模型能否真的用于实盘——震荡市的信号错误是亏损的主要来源。7. 机器学习在股票市场中的合理定位预测不是目的辅助决策才是最后想分享一个我做了这么多项目之后想明白的事。把模型预测准确率从50%提升到55%在学术上是一个值得庆祝的进步但在交易实践中它本身离盈利还差着很长的路。中间的桥梁是交易策略仓位管理、止损纪律、资金分配、组合构建这些环节对最终收益的影响往往不比预测准确率小。我见过一些朋友模型准确率一直提不上去就在特征和模型之间来回折腾却忽略了止损和仓位对最终资金曲线的影响。实际上只要有略高于随机水平的信号预测能力配合科学的仓位管理和严格止损长期也可能做出稳健的策略。反过来预测准确率再高如果满仓进出、从不设止损一次黑天鹅就能让所有收益归零。所以我对机器学习和股价预测的定位是它不是一个点石成金的预测工具而是一个帮助你理解市场结构、量化信号有效性的辅助决策手段。如果你的目标是做出一个能长期稳定运行的程序化交易策略那么模型预测只是其中最前端、甚至未必是最重要的一环。把精力平均分配到数据质量、特征工程、回测真实性和策略风控上整体收益会比你死磕模型准确率大得多。在实操中我还有一个体会值得分享单股票预测的稳定性通常很差因为个股受事件驱动的影响太大业绩公告、产业政策、市场情绪这些信息几乎不可能仅从历史K线和量价数据中预测到。相比之下指数预测或者一篮子股票的组合预测噪声更低、信号更稳定更适合作为机器学习模型的标的。如果你刚入门不妨把目光从具体的某只股票挪开先拿宽基指数练手整体体验会舒服很多。这大概就是我希望你在动手之前先想明白的全部内容。做股价预测的项目别揣着一夜暴富的心态沉下心来把数据、模型、回测和风控这四个环节老实打磨一遍你会收获比准确率更值钱的东西——对数据和市场的一份清醒。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑