news 2026/9/11 1:42:36

HMM-LSTM股票趋势分析:四类模型分层拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HMM-LSTM股票趋势分析:四类模型分层拆解

简介:基于HMM-LSTM的股票市场趋势分析项目提供了四种模型融合实验方案,适合金融量化初学者及有Python基础的算法工程师,用于理解隐马尔可夫模型与长短期记忆网络在行情预测中的实际结合。资源共61个文件,包含28个Python脚本、26个pyc编译文件、4张结果图、1篇参考论文PDF、1个Markdown项目说明及1张示意图片,压缩包仅2.54MB,轻量易部署。整体代码覆盖数据清洗、特征工程、模型训练、预测评估、结果可视化等关键环节,四种模型包括HMM-LSTM、GMM-HMM、XGB-HMM及独立LSTM,便于横向对比不同建模思路。目前已有327人学习下载。读者可借此掌握HMM对市场状态的识别、LSTM对趋势序列的拟合,并通过图表与论文辅助理解算法原理,项目说明提供了清晰的运行指引,适合在此基础上扩展自己的量化策略或完成课程设计。

1. 从HMM到LSTM:这四类模型是怎么把股市趋势“分层拆解”的

做量化的人都清楚一个尴尬的事实:单纯靠均线、MACD这类技术指标做趋势判断,震荡行情里会被来回打脸;单纯靠深度学习模型,又容易被市场噪声带偏。这套基于HMM-LSTM的股票市场趋势分析源码,核心思路是把“市场状态识别”和“时序趋势预测”拆成两个层次来处理:隐马尔可夫模型(HMM)负责从价格、成交量、技术因子中识别隐含的牛熊和震荡状态,LSTM再基于状态信息与原始特征序列预测后续趋势。源码里一共实现了HMM、GMM-HMM、XGB-HMM和LSTM四类模型,并且提供了训练、预测、评估、绘图全流程。

适合两类人:一是正在做量化选股或择时研究、想用状态空间模型做市场阶段划分的工程师;二是想在同一个数据集上对比“传统概率模型 vs 集成学习 vs 深度学习”效果的算法学习者。文章后面会带你逐个拆解源码中的核心文件,包括HMM多因子建模、XGBoost输出概率参与构建HMM观测矩阵、LSTM时序预测,以及最后的模型组合与样本平衡处理。

2. HMM状态建模:多因子观测序列与GMM-HMM的实现细节

2.1 为什么用HMM描述股票市场状态

股票价格走势不是一个平稳随机过程,它会在趋势、反转、震荡之间切换。这种“切换”看不见摸不着,但我们能观察到价格涨跌幅、成交量、波动率等指标。HMM正好匹配这个结构:隐藏状态表示市场当前处于什么阶段,观测序列是我们可以拿到的行情因子,状态转移矩阵描述从牛市到震荡、再到熊市的概率。源码中的HMM_duoyinzi.py就是按这个思路写的多因子HMM。

相较于直接用收益率阈值划分牛熊,HMM的优势在于状态是概率性的,每个时刻都会输出处于各个状态的后验概率,而不是硬切一刀。这个概率序列后续既可以单独做择时信号,也可以作为LSTM或XGBoost的输入特征。源码中HMM_hangqing.py处理行情数据、process_on_raw_data.py做原始数据清洗,都是为了给HMM准备干净的多因子观测序列。

2.2 多因子观测构造与数据对齐

HMM的观测序列要保证所有因子在同一时间轴对齐,并且尽量平稳。源码中form_df_all.py和process_on_raw_data.py完成这步工作。常见因子的构造方式如下表:

因子名称计算方式用途
对数收益率ln(close_t / close_{t-1})消除价格水平影响,满足平稳性
成交量变化率volume_t / volume_{t-1} - 1反映资金活跃度
波动率过去N日收益率标准差区分高波动与低波动状态
振幅(high - low) / close日内多空博弈强度

源码中把这些因子拼接成一个DataFrame,对齐后按日期排序。需要注意:因子数据不能混入未来信息,比如计算波动率只能用截至当天的历史窗口。HMM_duoyinzi.py里对每个因子做z-score标准化,这步很关键,因为不同因子的量纲差异会影响观测概率密度函数的估计结果。

2.3 GMM-HMM:用高斯混合替代单高斯观测分布

标准的HMM如果假设观测概率服从单高斯分布,对股票这种尖峰厚尾的收益率分布拟合效果有限。GMM_HMM.py实现了用高斯混合模型(GMM)作为HMM的观测概率密度函数,即每个隐藏状态下,观测向量由多个高斯成分加权组合而成。这样做的好处是:一个“震荡市”状态内部可能包含窄幅整理和宽幅波动两种子模式,单高斯只能描述一种均值-方差结构,而GMM可以表达更复杂的观测分布。

2.3.1 训练脚本核心逻辑

train_HMM_model.py中会调用GMM_HMM.py完成训练,关键流程如下:

import numpy as np from hmmlearn.hmm import GaussianHMM # 或使用带GMM的扩展版本 from hmmlearn.hmm import GMMHMM # n_components为隐藏状态数,n_mix为每个状态下的高斯成分数 model = GMMHMM(n_components=4, n_mix=3, covariance_type="diag", n_iter=200, random_state=42) # obs为多因子序列,shape: (n_samples, n_features) model.fit(obs) # 解码最优状态序列(Viterbi算法) states = model.predict(obs) # 计算每个时刻的状态后验概率 posterior = model.predict_proba(obs)

n_components=4表示预设4种市场状态,实际可根据AIC或BIC调整;n_mix=3表示每个隐藏状态下用3个高斯成分拟合观测分布,成分越多拟合能力越强但越容易过拟合;covariance_type="diag"假设因子之间条件独立,计算量小且对多维因子更稳健。训练完成后,states就是每个交易日对应的市场状态标签,posterior则给出每一天处于各状态的概率。

注意:HMM的状态序号本身没有语义,0号不一定代表熊市。需要训练完后对照每个状态的均值向量来人工标注状态含义,比如某个状态下收益率均值显著为负、波动率偏高,就对应熊市状态。

2.4 状态转移矩阵与初始状态的可解释性

训练完成后可以从model.transmat_拿到状态转移矩阵,每一行表示从状态i转移到状态j的概率。实际经验中,牛市和熊市的自转移概率通常在0.9以上,说明趋势有惯性;而震荡市向牛熊市的转移概率相对均衡,符合“震荡是趋势的蓄势阶段”这一市场规律。源码中的evaluate_plot.py会把状态序列画在价格图上,你可以直观看到HMM识别的牛熊分界点是否和肉眼判断一致。如果状态切换过于频繁,说明因子噪声太大或状态数偏多,需要减少n_components或对因子做平滑。

3. XGB-HMM特征融合:把XGBoost概率输出变成HMM的观测矩阵

3.1 XGBoost和HMM能怎么结合

HMM的观测概率B矩阵描述的是“在某个隐藏状态下,观测到某个特征值的概率”。传统做法是用高斯分布或GMM去拟合这个概率,但XGBoost在表格数据上有更强的非线性拟合能力。XGB_HMM.py的思路是:先用XGBoost对历史行情样本做分类或回归,输出每个样本属于某种市场状态的概率,然后把这个概率作为HMM观测似然的一部分,或者直接用来重新估计B矩阵。这样HMM的状态转移部分保留时序结构的建模能力,而观测部分则引入XGBoost的特征交互能力。

3.2 源码中的B矩阵重估流程

pred_proba_XGB.py训练XGBoost分类器,输入特征包括滞后N期的收益率、成交量变化、RSI、布林带位置等,标签来自HMM解码出的状态序列(或者人工标注的牛熊标签)。训练完成后,对全部样本做交叉验证预测,得到每个样本属于各状态的概率向量。form_B_matrix_by_XGB.py利用这些概率重新构建HMM的B矩阵:

import numpy as np import xgboost as xgb # 训练XGB分类器,num_class对应状态数 model = xgb.XGBClassifier( n_estimators=300, max_depth=5, learning_rate=0.05, objective="multi:softprob", num_class=4, subsample=0.8, colsample_bytree=0.8, ) model.fit(X_train, y_hmm_states) # 对训练集全量样本输出状态概率 train_proba = model.predict_proba(X_train) # 用概率重新估计B矩阵:每个状态下特征的条件概率 # 这里简化展示:按状态聚合特征均值,结合XGB概率加权 B_matrix = np.zeros((n_states, n_features)) for s in range(n_states): weight = train_proba[:, s].reshape(-1, 1) B_matrix[s] = np.average(X_train_features, axis=0, weights=weight.ravel())

multi:softprob是XGBoost的多分类目标函数,输出每个类别的概率;colsample_bytree=0.8在每棵树构建时随机采样80%的特征,降低过拟合。通过这种方式,HMM的观测概率不再局限于参数化的高斯分布,而是由XGBoost的叶节点输出决定,理论上可以捕获因子之间的高阶交互关系。

3.3 这种融合方式的适用边界

XGB-HMM的优势在特征数量较多(比如20个以上)且因子间存在复杂非线性关系时体现得比较明显;如果只用收益率和成交量两三个因子,反而可能不如GMM-HMM稳定。源码中XGB_HMM.py会把XGBoost的概率输出和HMM的转移概率相乘,得到每个时刻的联合状态概率,这个概率序列既可以直接作为择时信号,也可以拼接到LSTM的输入特征中。

另外一个容易踩坑的地方是:XGBoost训练时使用的标签如果来自HMM解码结果,那么HMM的训练数据必须和XGBoost的训练数据在时间上严格错开,否则会有标签泄漏。源码中random_cut.py的作用就是随机切分训练集和验证集,确保HMM和XGBoost都在各自的区间上训练,避免未来函数进入特征。

4. LSTM序列预测与四模型完整训练流程

4.1 HMM状态已经建模了,为什么还要LSTM

HMM是一阶马尔可夫模型,它假设当前状态只依赖前一个状态,而且观测序列内部的条件独立。这在股票市场里过于简化,因为趋势的形成往往依赖更长周期的上下文信息,比如连续五天的放量上涨和单日放量上涨对未来走势的影响完全不同。LSTM通过门控机制可以学习这种长距离依赖,因此源码中LSTM.py的输入不仅包含原始行情因子,还拼接了HMM输出的状态后验概率。

4.2 random_cut.py:时序数据切分与防泄漏

时序预测最忌讳随机打乱数据后切分训练集和测试集,因为相邻日期的样本高度相关。random_cut.py做了两件事:一是按时间顺序保留连续性,二是在训练集和验证集之间留出间隔窗口。常见的做法是训练集占70%、验证集占15%、测试集占15%,切分点按时间比例而不是随机索引。源码中还提供了sample的滑动窗口构造逻辑,用过去60个交易日的数据预测未来5日的趋势方向。

import numpy as np def create_sequences(features, states, seq_len=60, pred_len=5): X, y = [], [] for i in range(len(features) - seq_len - pred_len): # 输入窗口:原始因子 + HMM状态概率 x_seq = np.hstack([ features[i : i + seq_len], states[i : i + seq_len] ]) # 预测目标:未来pred_len日收益率均值方向 future_ret = features[i + seq_len : i + seq_len + pred_len, 0] y_label = 1 if np.mean(future_ret) > 0 else 0 X.append(x_seq) y.append(y_label) return np.array(X), np.array(y)

seq_len=60对应大约一个季度的交易日数量,覆盖中期趋势周期;pred_len=5是预测未来一周的方向,避免过短的预测周期被噪声主导。hstack操作把HMM状态概率作为额外的特征列拼在原始因子后面,这样LSTM在每个时间步都能感知当前市场状态。

4.3 train_LSTM_model.py的训练配置

源码中LSTM模型用Keras实现,核心参数比较常规但有几处容易影响效果的地方。一个典型的配置是:

from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.optimizers import Adam model = Sequential([ LSTM(units=128, return_sequences=True, input_shape=(60, n_features)), Dropout(0.3), LSTM(units=64, return_sequences=False), Dropout(0.3), Dense(units=32, activation="relu"), Dense(units=1, activation="sigmoid"), ]) model.compile( optimizer=Adam(learning_rate=0.001), loss="binary_crossentropy", metrics=["accuracy"], ) # 设置早停,避免过拟合 from tensorflow.keras.callbacks import EarlyStopping early_stop = EarlyStopping(monitor="val_loss", patience=10, restore_best_weights=True)

return_sequences=True的第一层LSTM输出完整时间步序列给第二层,让第二层能捕捉更高层的时间模式;Dropout(0.3)在LSTM层之后生效,对循环层内部权重也有内置的dropout参数可以在构建时另设,两个位置要区分开。EarlyStoppingpatience=10表示验证损失连续10轮不下降就停止训练,restore_best_weights=True保证回到验证损失最低的权重,防止后段训练过拟合。

4.4 四类模型的训练脚本分工与评估

整个训练流程分布在几个脚本中,下面是它们的分工:

脚本名功能输出
train_HMM_model.py训练标准和GMM-HMM状态序列、转移矩阵
xgb.py / XGB_HMM.py训练XGBoost分类器,构建B矩阵状态概率、B矩阵
train_LSTM_model.py训练LSTM分类器预测概率、准确率
evaluate_plot.py汇总预测结果,绘制对比图混淆矩阵、收益曲线

predict.py和main_single_score.py负责单只股票的独立预测流程。train_LSTM_model.py跑完后,FIGURE目录下的train1.jpg、train2.jpg、best_iter.png分别是训练曲线、验证曲线和最优迭代步的预测效果图。源码中test1.jpg和test2.jpg则展示了测试集上的状态划分和趋势预测结果。

4.5 类别不平衡处理:bagging_balance_weight.py

股票趋势预测中“上涨”和“下跌”样本通常不均衡,尤其在震荡市里“横盘”样本占比很高。bagging_balance_weight.py实现了两种处理:一是给少数类样本分配更高的损失权重,二是在每个bagging子模型上做下采样,让每个子模型看到的类别比例接近均衡,最后集成多个子模型的预测结果。

from sklearn.utils.class_weight import compute_class_weight from sklearn.ensemble import BaggingClassifier # 计算类别权重,用于模型训练 classes = np.array([0, 1]) weights = compute_class_weight(class_weight="balanced", classes=classes, y=y_train) # 构建bagging LSTM评估器(示意) base_model = create_lstm_model() bagging_model = BaggingClassifier( estimator=base_model, n_estimators=5, max_samples=0.8, bootstrap=True, )

compute_class_weight会按样本总数和类别频次自动计算权重,少数类的权重会高于多数类;max_samples=0.8让每个子模型只用80%的样本,增加子模型间差异。在股票数据这种信噪比很低的任务里,bagging对提升稳定性比单模型调参更有效。

5. 组合预测与模型部署中的几个关键细节

5.1 combine.py的投票与加权策略

四个模型各有侧重:HMM擅长状态识别但预测收益方向较粗,GMM-HMM在波动率大的市场段表现更好,XGB-HMM在特征关系复杂时有优势,LSTM擅长捕捉短期动量。combine.py默认采用加权投票方式,权重由验证集上的每类模型的F1分数决定。一个可用的权重分配逻辑是:

from sklearn.metrics import f1_score # 四个模型在验证集上的预测概率(示意变量) model_probs = [hmm_prob, gmm_prob, xgb_hmm_prob, lstm_prob] model_names = ["HMM", "GMM-HMM", "XGB-HMM", "LSTM"] # 计算每个模型的F1分数作为权重 weights = [] for prob in model_probs: pred = (prob > 0.5).astype(int) weights.append(f1_score(y_val, pred)) # 加权平均预测概率 final_prob = np.average(model_probs, axis=0, weights=weights) final_pred = (final_prob > 0.5).astype(int)

combine_allow_flag.py的作用是对组合结果做合规过滤,比如当HMM判断当前处于高波动状态时,即使LSTM给出强买入信号也降权处理。这个逻辑在实际交易中是必要的,因为LSTM在极端行情下的预测往往外推过度。

5.2 数据泄漏与随机种子

这个项目中比较隐蔽的问题是:HMM和LSTM共用同一段行情数据时,HMM的观测序列如果包含了未来区间的数据信息,后续LSTM的输入就存在泄漏。源码中random_cut.py和combine_allow_flag.py设计了一套时间窗口切分机制:HMM只在训练集前半段拟合,LSTM使用后半段,两者之间的状态概率在验证集上重新计算。修改代码时要注意保持这个切分逻辑,不要在全数据集上一次性训练所有模型,否则测试结果会偏乐观。

5.3 参数调整速查表

在实际复现时按下面参数起步,再根据标的和周期微调:

参数位置推荐值调整方向
n_componentstrain_HMM_model.py4状态切换频繁则减小到3,长期趋势则增加到5
n_mixGMM_HMM.py3因子波动大时可增到5,但要防止过拟合
seq_lenrandom_cut.py60短周期交易可减到20,中长线可增到120
n_estimatorsxgb.py300特征多时增加,同时配合early stopping
LSTM unitstrain_LSTM_model.py128数据量大可增到256,小数据集建议64
learning_ratetrain_LSTM_model.py0.001训练不稳时降至0.0005

如果训练HMM后状态序列几乎不切换,大概率是因子平滑过度,检查process_on_raw_data.py中是否用了过大的移动平均窗口,或者把n_components减小到3。反之如果状态切换过于频繁,可以增加交易日级别的平滑处理,比如对后验概率做3日滑动平均后再取argmax。

5.4 运行过程中常见的三个报错

第一个是hmmlearn版本差异导致的参数名变化,旧版本中GaussianHMMcovariance_type参数是必填的,新版本改为可选但默认值不同,建议固定hmmlearn==0.2.7。第二个是LSTM训练时维度不匹配,检查input_shape的第二个维度是否等于因子数加上HMM状态概率列数。第三个是form_B_matrix_by_XGB.py中使用了XGBoost模型当前环境不支持的tree_method参数,换成hist即可兼容CPU环境。建议在运行main_train_model.py之前先按顺序执行各模块的单元测试,确定数据对齐后再跑全流程。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 1:40:08

Vue项目代码高效管理:Gitee实战指南

1. Vue项目代码管理现状与Gitee优势解析作为国内主流的代码托管平台,Gitee(码云)相比GitHub在国内访问速度更快、稳定性更好,特别适合中小团队和个人开发者管理Vue项目代码。我经手过的十几个Vue项目中,有80%都选择Git…

作者头像 李华
网站建设 2026/9/11 1:37:19

动态三维重构毫秒级极速响应技术实现白皮书

1 概述1.1 技术背景现代智能化作战呈现高速对抗、突发临机、快节奏博弈的典型特征,战场制胜权由传统兵力、火力优势逐步转向认知速度、感知时延、决策闭环效率的体系优势。OODA作战循环的极速压缩,已成为快速反应作战、应急处置、突发对抗场景的核心制胜…

作者头像 李华
网站建设 2026/9/11 1:36:59

分布式计算核心原理与实战:从引擎选型到集群部署避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 1:35:39

编程课程第二章作业设计:从基础到实践

1. 项目概述"第2章作业"这个标题看似简单,实则包含了丰富的教学内涵。作为一线教育工作者,我深知章节作业在知识巩固和能力培养中的关键作用。这类作业通常出现在教材或课程的第二章节之后,旨在检验学生对基础概念的掌握程度&#…

作者头像 李华
网站建设 2026/9/11 1:35:32

SpringBoot汽车美容平台开发与优化实践

1. 项目概述:汽车美容行业数字化解决方案这个基于SpringBoot的汽车美容平台项目,是我为本地一家连锁汽车服务企业开发的数字化管理系统。传统汽车美容行业长期面临服务流程不透明、客户管理混乱、员工绩效难量化等痛点。通过这套系统,我们实现…

作者头像 李华