简介这份资源提供了一套基于XGBoost算法预测股票未来n日价格的完整源码面向具备一定Python与机器学习基础、希望将集成学习模型落地到量化金融场景的开发者与学习者。它解决的是从行情数据获取、特征工程到模型训练与结果输出的一整套流程搭建问题适合作为课程设计、个人项目或策略研究的起点。压缩包共6个文件包含3个Python脚本、2个文本说明与1个Excel结果表整体约18KB其中脚本分别承担数据抓取、工具函数封装与XGBoost建模预测文本文件给出依赖清单与使用说明Excel则保存了预测结果示例。已有245人学习下载。读者可据此理解如何构造滞后特征与标签、划分训练测试集、调参训练XGBoost并导出预测值同时借助说明文档快速复现运行为后续扩展多因子或对比其他模型提供可参考的代码骨架。1. 一份能跑通的 XGBoost 股价预测源码到底值不值得拆很多人第一次接触量化预测都是从「用机器学习预测股价」这个念头开始的。真到动手卡住的地方往往不是模型本身而是数据怎么对齐、标签怎么构造、预测的是「n 天后」这个 n 到底怎么落地。这份基于 XGBoost 预测 n 日后股价的源码包解决的正是从原始行情到可训练特征、再到模型输出这一整条链路。它包含 GetData.py 取数、sometools.py 特征工程、xgboostmodel.py 建模训练外加 requirements.txt 和一份 20220511result.xlsx 结果样例属于那种「拿来就能跑、跑完能看懂每一步在干什么」的完整工程。适合两类人一是想入门人工智能与深度学习在金融时序上怎么落地的新手二是已经会调 XGBoost 但没搭过完整预测流水线的熟手。下面按数据、特征、模型、避坑、进阶的顺序拆开讲。2. 数据获取与标签构造n 日后收益怎么定义才不翻车2.1 GetData.py 的取数逻辑与字段约定拿到源码先别急着跑模型第一步永远是看数据从哪来、长什么样。GetData.py 承担的是行情拉取和落盘常见做法是通过公开行情接口按股票代码和日期区间取日线字段一般包含开盘、最高、最低、收盘、成交量、成交额。这里有个容易被忽略的点不同接口返回的列名和顺序不一致如果直接喂给后面的特征脚本列错位是静默发生的模型照样能训练但学到的全是错位关系。我一般会在取数后立刻做一次列名标准化和类型转换把日期转成 datetime 并设为索引价格类字段统一成 float。下面这段是常见的清洗骨架可以直接套import pandas as pd def load_and_clean(path): # 读取原始行情注意编码和分隔符按实际接口调整 df pd.read_csv(path, encodingutf-8) # 统一列名避免后续按列名取值时 KeyError df df.rename(columns{ 日期: date, 开盘: open, 最高: high, 最低: low, 收盘: close, 成交量: volume }) # 日期转标准格式并排序时序模型对顺序极度敏感 df[date] pd.to_datetime(df[date]) df df.sort_values(date).reset_index(dropTrue) # 价格字段强制转数值脏数据置空后前向填充 for col in [open, high, low, close, volume]: df[col] pd.to_numeric(df[col], errorscoerce) df df.ffill().dropna().reset_index(dropTrue) return df逻辑说明排序是为了保证后面 shift 构造标签时方向正确ffill 处理停牌或缺失dropna 清掉开头无法填充的行。参数上errorscoerce 把无法解析的字符串变成 NaN 而不是直接报错这在真实行情里很常见。2.2 标签定义n 日后的收益还是价格这是整份源码最核心也最容易踩坑的地方。预测「n 日后的股价」有两种理解一是直接回归 n 天后的收盘价二是预测 n 日后的涨跌或收益率。直接回归价格的问题在于股价是非平稳序列模型很容易学到「今天的价格接近明天的价格」这种平凡解评估指标看着不错实际没有预测能力。更稳的做法是构造收益率标签用未来第 n 天的收盘价相对当前收盘价的变化def make_label(df, n5): # 未来 n 日后的收盘价 df[future_close] df[close].shift(-n) # 标签一n 日后收益率回归目标 df[label_ret] df[future_close] / df[close] - 1 # 标签二涨跌二分类1 为涨 df[label_up] (df[label_ret] 0).astype(int) # 末尾 n 行没有未来数据必须丢弃否则标签是 NaN 混进训练 df df.dropna(subset[future_close]).reset_index(dropTrue) return df参数 n 就是标题里的「n 日」改成 1 就是预测次日改成 10 就是预测十日后。注意 shift(-n) 是向上取未来方向写反会变成用历史预测历史这是血泪经验里最常见的一种翻车。dropna 那一步不能省否则最后 n 行标签为空训练时会报错或悄悄丢样本。3. sometools.py 特征工程把量价数据变成模型能吃的矩阵3.1 常用技术因子的构造XGBoost 本身不擅长从原始价格里自动提取时序结构特征质量基本决定上限。sometools.py 里通常放的是因子计算函数常见的有均线、动量、波动率、量价背离这几类。均线类用 rolling 窗口动量类用收益率差分波动率用收益率的标准差。下面给一组能直接用的因子import numpy as np def add_features(df): # 多周期均线反映不同时间尺度的趋势 for w in [5, 10, 20]: df[fma_{w}] df[close].rolling(w).mean() # 动量过去 w 日累计收益 for w in [3, 5, 10]: df[fmom_{w}] df[close].pct_change(w) # 波动率过去 w 日收益率标准差 df[vol_10] df[close].pct_change().rolling(10).std() # 量比当日成交量与 5 日均量之比 df[vol_ratio] df[volume] / df[volume].rolling(5).mean() # 价格在近期区间的位置归一化到 0-1 df[pos_20] (df[close] - df[low].rolling(20).min()) / \ (df[high].rolling(20).max() - df[low].rolling(20).min()) return df逻辑说明rolling 窗口产生的前若干行是 NaN这是正常的后面统一 dropna 即可。pos_20 这类位置因子对树模型比较友好因为它把绝对价格转成了相对位置缓解了非平稳问题。参数上窗口别设太大日线数据里超过 60 的窗口在样本量有限时容易过拟合。3.2 特征与标签的对齐、训练集切分特征算完要把特征列和标签列拼成训练矩阵。这里的关键是时间顺序切分绝不能随机打乱。金融时序一旦随机切分未来信息会泄漏到训练集评估结果虚高上线就废。常见做法是按时间前 80% 训练、后 20% 测试def split_time_series(df, feature_cols, label_col, ratio0.8): df df.dropna(subsetfeature_cols [label_col]).reset_index(dropTrue) split int(len(df) * ratio) X_train df.loc[:split-1, feature_cols] y_train df.loc[:split-1, label_col] X_test df.loc[split:, feature_cols] y_test df.loc[split:, label_col] return X_train, y_train, X_test, y_test参数 ratio 控制切分点0.8 是常见起点。注意 dropna 要在切分前做保证特征和标签行数一致。feature_cols 就是上一步生成的所有因子列名label_col 用 label_ret 或 label_up。这一步做完数据侧就干净了可以进模型。4. xgboostmodel.py 建模参数怎么设、结果怎么看4.1 训练与预测的主流程xgboostmodel.py 是整份源码的执行入口负责读特征、调 XGBoost、输出预测。XGBoost 在表格类特征上表现稳定训练快、对缺失值友好、不容易被量纲影响这也是它比深度学习更适合这份小样本量价数据的原因。核心训练代码大致如下import xgboost as xgb from sklearn.metrics import mean_squared_error, accuracy_score def train_model(X_train, y_train, X_test, y_test, taskreg): if task reg: model xgb.XGBRegressor( n_estimators300, # 树的数量越大越容易过拟合 max_depth4, # 单棵树深度金融数据建议压浅 learning_rate0.05, # 学习率小一点更稳 subsample0.8, # 行采样抗过拟合 colsample_bytree0.8, # 列采样 reg_lambda1.0 # L2 正则 ) model.fit(X_train, y_train) pred model.predict(X_test) print(RMSE:, mean_squared_error(y_test, pred, squaredFalse)) else: model xgb.XGBClassifier( n_estimators300, max_depth4, learning_rate0.05, subsample0.8, colsample_bytree0.8, reg_lambda1.0, eval_metriclogloss ) model.fit(X_train, y_train) pred model.predict(X_test) print(ACC:, accuracy_score(y_test, pred)) return model, pred逻辑说明max_depth 压到 4 左右是金融数据的常见选择树太深会记住噪声。learning_rate 配 n_estimators 是一对学习率小就多给点树。subsample 和 colsample_bytree 是两道抗过拟合的闸。reg_lambda 控制叶子权重防止个别样本主导。参数没有万能值建议先用这套默认跑通再按验证集表现微调。4.2 结果文件 20220511result.xlsx 怎么读源码包里带了 20220511result.xlsx这是某次运行的输出样例通常包含日期、真实值、预测值、误差几列。看结果别只盯一个 RMSE 或准确率要分三段看训练段拟合是否过好、测试段是否明显掉点、预测值和真实值的走势是否同向。如果训练段误差极低而测试段误差飙升基本就是过拟合回去调 max_depth 和正则。如果测试段准确率在 50% 上下晃说明特征里没有可用信号得回到因子构造那一步而不是继续调参。提示收益率回归的 RMSE 数值本身很小因为收益率量级就小别拿它和价格回归的 RMSE 比没有可比性。5. 避坑与排查这份源码最容易翻车的五个地方5.1 未来函数泄漏现象测试集指标好得离谱实盘完全对不上。原因特征里混入了未来信息比如用了 shift(-1) 的收盘价当特征或者 rolling 时用了 centerTrue。解决所有特征只能用当前及历史数据构造完特征后逐列检查是否引用了未来行center 参数一律保持默认 False。5.2 标签与特征错位现象模型能训练但预测方向系统性反了。原因shift 方向写反或者 dropna 之后特征和标签没有同步对齐。解决构造标签后立刻打印前几行人工核对 future_close 确实是当前行之后第 n 天的值切分前统一 dropna。5.3 随机切分导致信息泄漏现象交叉验证分数很高时间外推一塌糊涂。原因用了 train_test_split 默认的随机打乱。解决时序数据必须按时间切分训练集在前、测试集在后绝不 shuffle。5.4 停牌与缺失值处理不当现象某些股票训练报错或结果异常。原因停牌日无成交价格字段为空ffill 用错方向或没做。解决先 ffill 再 dropna确认填充方向是向前填充不要用 bfill 引入未来值。5.5 参数过拟合单只股票现象换一只股票指标就崩。原因参数是针对某只票调出来的泛化差。解决在多只股票上跑同一套参数取平均表现别为单只票的最优指标去调参。6. 进阶用法把单点预测改成滚动回测跑通单次训练只是起点真正判断这套源码有没有用得做滚动回测。做法是固定训练窗口每次向前滚动一天用历史窗口训练、预测下一天累积所有预测再统一算指标。这样得到的才是接近实盘的评估。下面是一个最小滚动框架def walk_forward(df, feature_cols, label_col, train_window250): preds, trues [], [] for i in range(train_window, len(df)): train df.iloc[i-train_window:i] test df.iloc[i:i1] model xgb.XGBRegressor( n_estimators200, max_depth4, learning_rate0.05, subsample0.8 ) model.fit(train[feature_cols], train[label_col]) preds.append(model.predict(test[feature_cols])[0]) trues.append(test[label_col].values[0]) return preds, trues参数 train_window 是训练窗口长度250 约等于一年交易日。窗口太短模型不稳太长则对市场变化反应迟钝。跑完把 preds 和 trues 对齐算 IC 或方向准确率比单次切分可信得多。我一般还会把预测值按大小分五组看最高组和最低组的未来收益差这个多空 spread 才是策略里真正能用的信号。从那以后我每次拿到这类预测源码都强制先跑一遍滚动回测再谈效果单次切分的漂亮数字一律不信。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?