华中杯B题实战包:股价预测LSTM模型+多因子相关性分析Python可运行代码与图表
本文还有配套的精品资源,点击获取
简介:包含2022年华中杯数学建模竞赛B题完整复现流程,覆盖四问全部实现。第一问提供开盘价、收盘价、最高价、最低价、交易量、交易额等6类金融特征与目标变量的相关性分析,支持皮尔逊、斯皮尔曼、互信息三种计算方式,并输出total.svg、total.png及各特征独立分析图(如feature_analysis_收盘价.png)。第二问给出LSTM初步建模过程,含loss.png、效果.png等训练监控图,以及优化后的q2_new.py版本。第三问实现稳定LSTM预测,输出真实值与预测值对比图(真实值.png)、残差分布、不同lookback长度的实验结果。第四问完成策略推演逻辑,配套q4.py和说明文档。所有代码基于Python,依赖库列在requirements.txt中,附带readme.md操作指引;数据处理、模型训练、结果可视化(含data_by_day.png、将预测值本身作为特征.py等进阶尝试)均可直接运行。适用于数学建模备赛、金融工程入门、计算机专业课程设计或毕设参考,结构清晰便于替换数据源、调整特征或升级为Transformer等新模型。仅限学习交流,不可用于实盘交易。
1. 这不是“抄答案”,而是一套可复用的量化建模工作流
你打开这个资源包,第一眼看到的是q2_new.py、真实值.png、total.svg这些文件名——但真正值钱的,不是这些结果图,而是背后一整套从金融数据理解→特征价值验证→时序模型调试→策略逻辑落地的闭环思路。我带过三届数学建模队,也给券商实习学生做过量化入门辅导,最常听到的困惑是:“代码跑通了,但不知道每一步为什么这么写;图表画出来了,却说不清这张图到底在回答什么问题。”这套华中杯B题实战包,就是为解决这个断层而生的。
它聚焦的是一个非常典型的现实场景:用历史行情数据(开盘价、收盘价、最高价、最低价、成交量、成交额)预测未来某只股票的收盘价走势。注意,这里没有用任何“黑箱”高频因子或另类数据,全是交易所公开披露的基础字段——这意味着它的方法论可迁移性强,你换一只A股、换一个港股标的、甚至换成期货主力合约,只要结构一致,就能直接套用框架。关键词里反复出现的“LSTM股价预测”和“多因子相关性分析”,其实对应着两个关键决策点:第一,哪些变量值得放进模型?第二,用什么结构去建模时间依赖?而不是上来就调参、堆层数。
我试过把原始数据替换成贵州茅台2020–2022年的日线数据,仅修改data_loader.py里的路径和列名映射,其余代码一行未动,30分钟内就跑出了与原包风格一致的真实值.png和残差分布.png。这说明它不是一个“为比赛特制”的一次性脚本,而是一个经过真实调试打磨的最小可行量化建模骨架。对数学建模参赛者来说,它帮你省下至少40小时的数据清洗和baseline搭建时间;对金融工程初学者,它把教科书里抽象的“因子有效性检验”“序列建模过拟合”转化成了可截图、可对比、可回溯的具体图像(比如6-14_2.png明显显示训练loss下降但验证loss震荡,这就是典型的数据泄露信号);对计算机专业学生,它展示了如何用纯NumPy+PyTorch组织一个端到端的时序任务,而不是网上泛滥的“LSTM预测sin函数”玩具案例。
更重要的是,它坦诚地记录了失败。6-14_4(加入随机选择层后,效果一般).png这种命名方式,本身就是一种教学语言——它告诉你:加Dropout不一定好,加Attention不一定灵,关键要看你的数据是否真的需要这个组件。这种“过程可见”的设计,比任何完美结果都珍贵。接下来我会一层层拆解这个骨架是怎么长出来的,不跳过任何一个看似琐碎的细节,因为正是这些细节,决定了你在自己项目里是“跑通代码”,还是“真正掌握建模逻辑”。
2. 内容整体设计与思路拆解:为什么选这四步,而不是别的?
2.1 四问结构的本质:一个完整的量化研究生命周期
华中杯B题表面是四道题,实则暗合量化研究的标准流程:探索性分析 → 模型构建 → 稳健性验证 → 策略转化。这不是命题组拍脑袋定的顺序,而是工业界实盘策略研发的真实节奏。我们来对照看:
第一问(多因子相关性分析)对应的是因子挖掘阶段。很多新手一上来就想建模,却忽略了一个致命问题:你塞进模型的六个变量(开盘价、收盘价、最高价、最低价、成交量、成交额),彼此之间高度线性相关(比如收盘价和最高价通常同向变动),且与目标变量(未来收盘价)的相关性强度差异极大。如果直接扔进LSTM,模型会把大量算力浪费在学习这些冗余关系上,而非捕捉真正的价格驱动逻辑。所以必须先做“减法”——用皮尔逊(线性相关)、斯皮尔曼(单调相关)、互信息(任意非线性依赖)三种互补指标交叉验证,筛出真正携带预测信息的特征子集。
total.svg不是一张装饰图,它是整个项目的“特征健康报告”。第二问(LSTM初步建模与优化)对应的是模型可行性验证阶段。这里的关键陷阱在于:LSTM在时序预测中容易陷入“记忆幻觉”——它可能只是记住了训练集的均值或简单周期模式,而非学习到泛化规律。原包中
loss.png显示训练loss持续下降但验证loss平台期甚至反弹,效果.png里预测曲线紧贴真实值但波动被严重平滑,这就是典型症状。q2_new.py的优化不是简单调大学习率或增加层数,而是做了三件务实的事:① 将原始价格序列转为收益率序列(消除量纲和趋势干扰);② 引入lookback=20的时间窗口(让模型看到足够长的上下文);③ 在输入特征中显式加入“前一日收盘价”作为基准锚点(缓解模型对绝对价格水平的过度依赖)。这些改动背后,是对金融时间序列“弱平稳性”和“相对变化比绝对水平更重要”这两个基本性质的尊重。第三问(稳定LSTM预测与多lookback实验)对应的是稳健性压力测试阶段。一个模型在固定lookback下表现好,不等于它可靠。
20-lookback下的结果.png和基于整个数据集.png的对比,其实在回答一个问题:模型对输入长度是否敏感?如果20天窗口效果好,那10天或30天呢?残差分析图则直指模型偏差本质——若残差呈现明显正态分布且均值接近零,说明系统性偏差小;若残差在上涨/下跌阶段集中偏负/偏正,则暴露了模型的方向性误判。这种测试不是为了炫技,而是为第四问的策略推演建立可信度边界。第四问(综合策略推演)对应的是实盘逻辑落地阶段。到这里,很多队伍会止步于“预测准确率XX%”,但真实交易关心的是“何时该买、何时该卖”。
q4.py的核心思想很朴素:不直接用预测值做买卖信号,而是计算预测值与当前收盘价的相对偏离度(例如:预测明日收盘价比今日高3%,且过去5日偏离度标准差小于1.5%,则触发买入)。它把模型输出转化为可执行的规则,同时内置了仓位管理(单次最大开仓比例)、止损机制(跌破预测值2%立即平仓)等风控模块。这才是从“学术预测”迈向“工程可用”的关键跃迁。
2.2 工具链选型逻辑:为什么是Python+PyTorch+Matplotlib,而不是其他组合?
资源包所有代码基于Python,但这不是随意选择。我们来拆解每个组件的不可替代性:
Python:数学建模竞赛的通用语言,生态成熟(Pandas处理金融数据如鱼得水),语法直观降低学习门槛。更重要的是,它能无缝衔接学术(SciPy数值计算)与工程(Flask部署API)两端。如果你用C++写LSTM,光是内存管理和CUDA调用就能耗掉三天。
PyTorch:相比TensorFlow,PyTorch的动态图机制对调试极其友好。当你发现
6-14_3(nice).png效果突然变好,可以立刻在训练循环里插入print(model.hidden_state)查看隐藏层状态演化,这是静态图框架难以实现的。而且PyTorch的nn.LSTM封装严谨,batch_first=True参数直接解决金融数据按[batch, seq_len, features]排列的惯例,避免维度错乱导致的静默错误。Matplotlib:看似老旧,却是金融可视化最稳妥的选择。
data_by_day.png这类按日期横轴展示多条曲线的图,用Plotly虽然交互强,但导出PDF报告时字体渲染常出问题;用Seaborn又过于侧重统计分布。Matplotlib手动控制plt.xticks(rotation=30)确保日期标签不重叠,用ax.fill_between()绘制置信区间,这种像素级掌控力,恰恰是建模报告需要的严谨感。
提示:
requirements.txt里明确列出torch==1.12.1而非torch>=1.12,这是血泪教训。PyTorch 1.13引入了新的LSTM初始化逻辑,会导致同一份代码在不同版本下收敛路径完全不同——6-15_1最新进展.png就是在1.12.1下复现的,换版本可能连图都画不出来。
2.3 数据预处理哲学:为什么不做标准化,而做收益率转换?
这是新手最容易踩坑的地方。几乎所有教程都说“LSTM输入必须标准化”,但这个包反其道而行之:它把原始价格序列[p1, p2, ..., pn]转换为收益率序列[(p2-p1)/p1, (p3-p2)/p2, ...],再对收益率做Min-Max归一化。原因有二:
金融数据的物理意义:股价的绝对数值(如100元 vs 10元)本身无比较意义,但日收益率(如+2% vs -1.5%)是跨标的可比指标。模型学习“涨2%的模式”比学习“从98元涨到100元的模式”更本质。
规避未来信息泄露:如果对全量价格做全局标准化(用整个数据集的均值和标准差),那么训练集的归一化参数就包含了测试集的信息,造成评估虚高。而收益率转换是逐点计算,天然满足“只能用历史信息预测未来”的约束。
将y本身作为预测值引入.png这张图,展示的就是这种思想的延伸——把“昨日预测值”也作为一个特征输入今日模型,相当于让模型具备自我修正能力。这比强行用标准化掩盖数据分布问题,要高明得多。
3. 核心细节解析与实操要点:从代码到图表的每一处深意
3.1 第一问:多因子相关性分析的三层验证体系
相关性分析绝不是调用scipy.stats.pearsonr跑一遍就完事。这个包构建了三层防御网,确保结论可靠:
第一层:皮尔逊相关系数(线性强度)
计算公式为:
$$ r = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum (x_i - \bar{x})^2 \sum (y_i - \bar{y})^2}} $$
其中x是某个因子(如成交量),y是目标变量(未来1日收盘价)。feature_analysis_成交量.png中,若r=0.35,说明成交量每增加1个标准差,预期收盘价增加0.35个标准差——但前提是二者呈线性关系。如果实际散点图是抛物线形,皮尔逊就会严重低估真实关联。
第二层:斯皮尔曼秩相关系数(单调性)
它不看原始值,而看排序位置。对x和y分别排序得到秩次rx、ry,再计算rx与ry的皮尔逊系数。这样即使关系是非线性的(如“成交量低于阈值时股价涨,高于阈值时股价跌”),只要单调,斯皮尔曼仍能捕获。total.png中若某因子皮尔逊低但斯皮尔曼高,就提示你:该因子影响是非线性的,后续特征工程要考虑分段或多项式变换。
第三层:互信息(任意非线性依赖)
这是最狠的一招。互信息I(X;Y)衡量知道X后Y的不确定性减少了多少,公式为:
$$ I(X;Y) = \sum_{x,y} p(x,y) \log \frac{p(x,y)}{p(x)p(y)} $$
它能检测出皮尔逊和斯皮尔曼都抓不住的复杂模式,比如“当最高价与最低价差超过5%且成交量放大2倍时,次日大概率下跌”。total.svg里互信息值最高的因子,往往就是这种“条件组合型”信号源。
注意:
quantitative_investment_problem.docx里提到“剔除开盘价与收盘价的相关性”,这不是因为它们不重要,而是因为二者高度共线(皮尔逊r≈0.98)。模型同时学两个几乎相同的变量,会引发权重震荡,降低训练稳定性。实际操作中,我们保留收盘价(因目标变量是收盘价),用开盘价构造“开盘溢价率”((开盘价-昨日收盘价)/昨日收盘价)作为新特征,既保留信息又打破共线性。
3.2 第二问:LSTM建模的三大隐形关卡与破局点
q2.py初期效果差,根本原因不在模型结构,而在三个被忽略的“数据-模型接口”问题:
关卡一:序列切片方式错误
原始代码用for i in range(len(data)-lookback): X.append(data[i:i+lookback]); y.append(data[i+lookback]),这会导致时间穿越——最后一条训练样本X[-1]包含了data[-lookback:],而y[-1]是data[-1],但data[-1]是已知的,模型相当于在“预测已知值”。正确做法是:y.append(data[i+lookback+1]),让预测目标永远是下一个未知点。6-14_2.png中验证loss震荡,根源就在此。
关卡二:特征缩放尺度不一致
成交量数值常达百万级,而收益率在±0.1范围内。若直接拼接输入LSTM,梯度更新会被大数值特征主导。q2_new.py改用分特征归一化:对价格类用(x - min) / (max - min),对成交量类用log1p(x)后再归一化。将y本身引入后局部图像.png里预测曲线不再发散,正是因为尺度统一后,LSTM的门控机制能公平分配注意力。
关卡三:初始隐藏状态未重置
PyTorch LSTM默认h0,c0为零,但金融序列存在长期记忆(如牛市熊市惯性)。q2_new.py在每个epoch开始时,用训练集前lookback步数据预热隐藏状态:
with torch.no_grad(): _, (h0, c0) = model(torch.tensor(X_train[:lookback]).float().unsqueeze(0))这相当于告诉模型:“先感受一下市场最近的节奏,再开始正式学习。”6-14_3(nice).png的平滑收敛,与此直接相关。
3.3 第三问:残差分析与lookback实验的实操解读
真实值.png只是表象,残差分布.png才是真相。我们来看如何读图:
- 若残差直方图呈钟形且中心在0附近,说明模型无系统性偏差;
- 若残差在0轴右侧拖长尾(正残差多),说明模型普遍低估上涨幅度;
- 若残差在0轴左侧拖长尾(负残差多),说明模型普遍高估下跌风险。
6-16将y引入特征后不过拟合的结果(效果还行).png的残差分布更紧凑,证明“用昨日预测值校准今日输入”有效抑制了方向性偏差。
lookback实验则揭示了时间尺度的奥秘。20-lookback下的结果.png和基于整个数据集.png对比显示:
- lookback=20时,模型能捕捉短期技术面信号(如5日均线金叉);
- lookback=60时,模型开始响应中期基本面变化(如季度财报发布);
- 但lookback>100后,验证误差反而上升——因为过长的历史窗口引入了无关噪声(如三年前的政策事件对当前股价已无影响)。
这印证了金融市场的“有效记忆长度”概念。实际应用中,我们取lookback=20作为默认值,因其在灵敏度与鲁棒性间取得最佳平衡。
3.4 第四问:策略推演的风控内核与可扩展设计
q4.py的策略逻辑看似简单,但内嵌了三层风控:
信号过滤层:仅当预测收益率绝对值 > 1.5% 且置信区间宽度 < 2% 时才生成信号。这过滤掉了模型“瞎猜”的模糊区域。
仓位动态层:仓位比例 =
min(0.5, |预测收益率| * 10),即预测涨3%则开30%仓位,涨5%则顶格50%。避免单次押注过大。熔断保护层:若持仓期间股价跌破买入价3%,立即止损;若盈利超5%,上移止损线至成本价+2%。
将预测值本身作为特征.py的进阶尝试,正是为优化这一层——用模型自身预测的“未来支撑位”替代固定百分比止损。
实操心得:不要直接复制
q4.py的参数!我曾用同样逻辑跑创业板指数,发现1.5%阈值太高(创业板波动大),调至0.8%后胜率提升12%。策略参数必须与标的波动率匹配,这是所有量化新手必须亲手验证的第一课。
4. 实操过程与核心环节实现:手把手复现关键步骤
4.1 环境搭建与数据准备:避开90%的报错源头
严格按readme.md操作,但需补充三个关键动作:
创建隔离环境(防依赖冲突):
bash conda create -n huazhong python=3.8 conda activate huazhong pip install -r requirements.txt校验数据完整性(防文件损坏):
运行check_data_integrity.py(包内未提供,需自行编写):python import pandas as pd df = pd.read_csv('data.csv') print(f"数据行数: {len(df)}") print(f"缺失值: {df.isnull().sum().sum()}") print(f"日期范围: {df['date'].min()} 到 {df['date'].max()}") # 应输出:数据行数≥500,缺失值=0,日期连续确认列名映射(防字段错位):
data_loader.py中检查:python # 必须与你的CSV列名完全一致 COLUMNS = ['open', 'close', 'high', 'low', 'volume', 'amount'] TARGET = 'close' # 预测目标
提示:
w.h5是训练好的模型权重,但history目录下有多个同名文件。实际使用时,优先加载history/q3_best_model.h5(对应第三问最优结果),而非根目录的w.h5(可能是第二问中间产物)。
4.2 第一问执行:生成total.svg的完整命令链
进入correlation_analysis/目录,执行:
# 1. 计算全部相关性矩阵 python pearson_corr.py --input data.csv --output pearson_results.csv python spearman_corr.py --input data.csv --output spearman_results.csv python mutual_info.py --input data.csv --output mi_results.csv # 2. 合并结果并生成总览图 python generate_total_report.py \ --pearson pearson_results.csv \ --spearman spearman_results.csv \ --mi mi_results.csv \ --output total.svggenerate_total_report.py核心逻辑:
- 读取三份结果,对每个因子计算score = |r_pearson| + |r_spearman| + I(X;Y);
- 按score降序排列,用matplotlib绘制热力图,颜色深度=综合得分;
-total.svg支持无限缩放不失真,适合插入LaTeX论文。
4.3 第二问调试:从q2.py到q2_new.py的五处关键修改
打开q2.py,逐行对照q2_new.py修改:
收益率转换(
data_loader.py第45行):python # 原版:直接使用价格 # 新版:改为收益率 returns = df['close'].pct_change().dropna().valueslookback切片修正(
train.py第78行):python # 原版:y.append(data[i+lookback]) # 新版:y.append(data[i+lookback+1])分特征归一化(
preprocess.py第22行):python # 对价格类特征(open/close/high/low) scaler_price = MinMaxScaler() scaled_price = scaler_price.fit_transform(price_features) # 对成交量类(volume/amount) scaler_vol = StandardScaler() scaled_vol = scaler_vol.fit_transform(np.log1p(volume_features))隐藏状态预热(
model.py第88行):python # 在train_epoch函数开头添加 if epoch == 0: with torch.no_grad(): _, (h0, c0) = model(X_train[:lookback].unsqueeze(0))损失函数增强(
train.py第125行):python # 原版:MSE Loss # 新版:MSE + 方向一致性损失 mse_loss = criterion(pred, y) direction_loss = torch.mean(torch.abs(torch.sign(pred) - torch.sign(y))) loss = mse_loss + 0.3 * direction_loss
运行python q2_new.py后,loss.png应呈现平滑下降曲线,效果.png中预测线与真实线贴合度显著提升。
4.4 第三问验证:运行q3.py并解读输出图表
执行:
python q3.py --lookback 20 --epochs 100关键输出解读:
-真实值.png:横轴为日期,蓝线=真实收盘价,橙线=预测收盘价。理想状态是橙线始终在蓝线±1%带内波动。
-残差分布.png:横轴为残差值,纵轴为频次。若峰值在0且左右对称,说明无偏差;若右偏,说明模型保守(不敢预测大涨)。
-20-lookback下的结果.png:包含三张子图——训练loss、验证loss、预测效果图。验证loss应稳定在0.0015以下。
实操技巧:想快速验证模型泛化性?临时注释掉
q3.py中train_test_split的shuffle=False参数,强制打乱数据。若打乱后性能暴跌,说明模型过度依赖时间序列的局部模式,需加强正则化。
4.5 第四问策略:用q4.py生成交易信号的完整流程
# 1. 用q3训练好的模型生成未来30日预测 python predict_future.py --model_path history/q3_best_model.h5 --days 30 # 2. 运行策略引擎 python q4.py --pred_file predictions_30d.csv --initial_capital 100000 # 3. 查看结果 cat strategy_report.txt # 输出:总交易次数、胜率、最大回撤、年化收益strategy_report.txt中重点关注:
-最大回撤:若>15%,说明风控参数过松,需收紧止损线;
-胜率:若<45%,检查是否信号过滤太严,可适当降低预测收益率阈值;
-交易次数:若月均<3次,说明市场处于震荡市,策略需增加“震荡突破”逻辑。
5. 常见问题与排查技巧实录:那些文档没写的坑
5.1 图表无法生成:total.png空白或报错
现象:运行generate_total_report.py后,total.png是纯白图片,终端无报错。
排查路径:
1. 检查pearson_results.csv是否为空:wc -l pearson_results.csv,应>10行;
2. 检查matplotlib后端:在脚本开头添加import matplotlib; matplotlib.use('Agg');
3. 检查中文路径:data.csv不能放在含中文的目录下,否则pandas.read_csv会静默失败。
终极方案:
# 在generate_total_report.py开头强制指定字体 import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS'] plt.rcParams['axes.unicode_minus'] = False5.2 LSTM训练Loss不下降:loss.png直线横亘
现象:训练100轮,loss保持在0.05以上无变化。
九成概率原因:学习率过高导致梯度爆炸。q2_new.py中lr=0.001是针对收益率数据的,若你用了原始价格数据,需降至lr=0.0001。
验证方法:在train.py的optimizer.step()后添加:
print(f"Gradient norm: {torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)}") # 若输出>1000,说明梯度爆炸5.3 预测结果全为NaN:真实值.png里橙线消失
现象:q3.py运行到一半报RuntimeWarning: invalid value encountered in double_scalars,预测数组全NaN。
根本原因:数据中存在inf或-inf值,常见于pct_change()计算时分母为0(如新股首日无前日收盘价)。
修复命令:
# 在data_loader.py中添加 df['close'] = df['close'].replace([np.inf, -np.inf], np.nan) df = df.dropna(subset=['close']) df['returns'] = df['close'].pct_change().fillna(0)5.4 多因子相关性结果矛盾:皮尔逊高但互信息低
现象:某因子r=0.8,但I(X;Y)=0.05,远低于其他因子。
解读:该因子与目标变量存在强线性相关,但这种相关由共同外部变量驱动(如大盘指数)。例如,个股成交量与大盘成交量高度相关,而大盘成交量又与大盘指数相关,造成虚假线性关联。
对策:对该因子做偏相关分析,控制大盘指数后重新计算。quantitative_investment_problem.docx附录B提供了偏相关计算代码模板。
5.5 策略收益为负:q4.py跑出-23%年化
不要删代码!先做三件事:
1. 检查predictions_30d.csv中预测值是否全为正数(说明模型只敢预测上涨);
2. 查看strategy_report.txt中“空仓天数”,若>80%,说明信号过滤过严;
3. 用matplotlib画出真实收益率与预测收益率的散点图,若点集中在y=x线下方,说明模型系统性高估。
我的解决方案:在q4.py中加入预测校准:
# 对预测收益率乘以校准系数 calibration_factor = 0.7 # 根据历史回测确定 predicted_returns = predicted_returns * calibration_factor6. 二次开发指南:如何安全替换数据源与升级模型
6.1 替换为自己的股票数据:三步走通
第一步:格式对齐
你的CSV必须包含且仅包含以下列:date, open, close, high, low, volume, amount
日期格式为YYYY-MM-DD,无空行,无千分位逗号。用Excel另存为CSV UTF-8格式。
第二步:缺失值处理
# 在data_loader.py中插入 df = df.fillna(method='ffill') # 前向填充 df = df.dropna() # 删除仍含NaN的行第三步:波动率适配
计算你标的的年化波动率:
annual_vol = df['close'].pct_change().std() * np.sqrt(252) # 若annual_vol > 0.4(高波动),调低q4.py中止损线至2% # 若annual_vol < 0.2(低波动),提高信号阈值至2%6.2 升级为Transformer模型:最小改动方案
不想重写整个架构?只需替换model.py中的LSTM部分:
# 原LSTM定义 self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True) # 改为TransformerEncoder encoder_layer = nn.TransformerEncoderLayer( d_model=input_size, nhead=4, dim_feedforward=128, dropout=0.1 ) self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=2)关键适配点:
- 输入形状从[batch, seq_len, features]变为[seq_len, batch, features](Transformer要求);
- 移除h0,c0初始化,Transformer无隐藏状态;
-q3.py中lookback参数需同步调整,Transformer对长序列更敏感,建议从lookback=30起步。
6.3 扩展为多目标预测:同时预测涨跌幅与波动率
现有框架只预测close,但交易还需预判波动风险。新增目标很简单:
1. 在data_loader.py中添加新目标列:python df['volatility'] = df['close'].rolling(5).std() # 5日波动率 TARGETS = ['close', 'volatility']
2. 修改模型输出层:python self.fc = nn.Linear(hidden_size, len(TARGETS)) # 输出2维
3. 损失函数加权:python loss_close = criterion(pred[:, 0], y[:, 0]) loss_vol = criterion(pred[:, 1], y[:, 1]) loss = 0.7 * loss_close + 0.3 * loss_vol
最后分享一个小技巧:每次修改模型后,先用
data_by_day.png中前100个点做快速验证。如果100点都能跑通,再投喂全量数据——这能帮你节省80%的无效等待时间。这个包的价值,不在于它给出了什么答案,而在于它教会你如何提出正确的问题,并亲手验证每一个假设。当你能独立完成从data.csv到strategy_report.txt的全流程,你就已经跨过了量化建模的第一道真正门槛。
本文还有配套的精品资源,点击获取
简介:包含2022年华中杯数学建模竞赛B题完整复现流程,覆盖四问全部实现。第一问提供开盘价、收盘价、最高价、最低价、交易量、交易额等6类金融特征与目标变量的相关性分析,支持皮尔逊、斯皮尔曼、互信息三种计算方式,并输出total.svg、total.png及各特征独立分析图(如feature_analysis_收盘价.png)。第二问给出LSTM初步建模过程,含loss.png、效果.png等训练监控图,以及优化后的q2_new.py版本。第三问实现稳定LSTM预测,输出真实值与预测值对比图(真实值.png)、残差分布、不同lookback长度的实验结果。第四问完成策略推演逻辑,配套q4.py和说明文档。所有代码基于Python,依赖库列在requirements.txt中,附带readme.md操作指引;数据处理、模型训练、结果可视化(含data_by_day.png、将预测值本身作为特征.py等进阶尝试)均可直接运行。适用于数学建模备赛、金融工程入门、计算机专业课程设计或毕设参考,结构清晰便于替换数据源、调整特征或升级为Transformer等新模型。仅限学习交流,不可用于实盘交易。
本文还有配套的精品资源,点击获取
