数据科学和机器学习(第 30 部分):预测股票市场的幂对、卷积神经网络(CNN)、和递归神经网络(RNN)·综合运用
◍ CNN 叠 LSTM 的建模与 MT5 落地
普通 RNN 抓不住长序列里的形态关系,LSTM 在这块明显更稳,也更能榨出序列中的长期依赖。把 LSTM 接在 CNN 后面,等于先让卷积层提局部特征、再交给记忆单元看时序,思路不复杂。 我们在特斯拉日线数据上先跑 Python 原型:只把原本简单 RNN 的那一层换成 LSTM,其余训练验证流程不动。测试集分类准确率落在 53%,precision 在 0 类 0.67、1 类 0.45,样本量 195。 转到 MT5 这边,函数库和此前 CNN+RNN 的 EA 基本通用,核心改动只是引用训练好的 ONNX 与标准化参数。用相同测试器设置回测,整体交易准确率约 74%,比前几个模型低一截,但作为辅助信号仍算能打。外汇与贵金属波动更狂,直接套用该准确率可能大幅衰减,务必先小周期验证。 下面这段是原型里换层的代码和 MT5 资源挂载,注意 LSTM 层只改了一行: from tensorflow.keras.layers import LSTM # Define the CNN model model = Sequential() model.add(Conv1D(filters=16, kernel_size=3, activation='relu', strides=2, padding='causal', input_shape=(time_step, X_train.shape[2]))) model.add(MaxPooling1D(pool_size=2)) model.add(LSTM(50, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(50, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(units=len(np.unique(y)), activation='softmax')) MT5 侧把训练产物挂成 resource,ConvNet 库直接复用: #resource "\\Files\\lstm+cnn.TSLA.D1.onnx" as uchar onnx_model[] #resource "\\Files\\lstm+cnn.TSLA.D1.standard_scaler_mean.bin" as double standardization_mean[] #resource "\\Files\\lstm+cnn.TSLA.D1.standard_scaler_scale.bin" as double standardization_std[] #include <MALE5\Convolutional Neural Networks(CNNs)\ConvNet.mqh> #include <MALE5\preprocessing.mqh> CConvNet cnn; StandardizationScaler *scaler;
from tensorflow.keras.layers class="kw">import LSTM # Define the CNN model model = Sequential() model.add(Conv1D(filters=class="num">16, kernel_size=class="num">3, activation=&class="macro">#x27;relu&class="macro">#x27;, strides=class="num">2, padding=&class="macro">#x27;causal&class="macro">#x27;, input_shape=(time_step, X_train.shape[class="num">2]) ) ) model.add(MaxPooling1D(pool_size=class="num">2)) model.add(LSTM(class="num">50, activation=&class="macro">#x27;relu&class="macro">#x27;)) model.add(Dropout(class="num">0.5)) model.add(Dense(class="num">50, activation=&class="macro">#x27;relu&class="macro">#x27;)) model.add(Dropout(class="num">0.5)) model.add(Dense(units=len(np.unique(y)), activation=&class="macro">#x27;softmax&class="macro">#x27;)) # For binary classification(e.g., buy/sell signal) model.summary() class="num">7/class="num">7 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step Classification Report precision recall f1-score support class="num">0 class="num">0.67 class="num">0.44 class="num">0.53 class="num">117 class="num">1 class="num">0.45 class="num">0.68 class="num">0.54 class="num">78 accuracy class="num">0.53 class="num">195 macro avg class="num">0.56 class="num">0.56 class="num">0.53 class="num">195 weighted avg class="num">0.58 class="num">0.53 class="num">0.53 class="num">195 class="macro">#resource "\Files\lstm+cnn.TSLA.D1.onnx" as class="type">uchar onnx_model[] class="macro">#resource "\Files\lstm+cnn.TSLA.D1.standard_scaler_mean.bin" as class="type">class="kw">double standardization_mean[] class="macro">#resource "\Files\lstm+cnn.TSLA.D1.standard_scaler_scale.bin" as class="type">class="kw">double standardization_std[] class="macro">#include <MALE5\Convolutional Neural Networks(CNNs)\ConvNet.mqh> class="macro">#include <MALE5\preprocessing.mqh> CConvNet cnn; StandardizationScaler *scaler;
GRU 接在 CNN 后面能跑出什么精度
GRU 和 LSTM 一样能抓长序列依赖,但结构更轻。把它塞进原先的 CNN 架构里,只需把循环层换成 GRU,其余卷积、池化、Dropout 与全连接层都不用动。 训练验证完成后,这套 CNN+GRU 在测试集上的准确率为 53%,分类报告里 0 类 precision 0.69 / recall 0.39,1 类 precision 0.45 / recall 0.73,宏平均 f1 仅 0.53,说明两类样本召回失衡比较明显。 导出 ONNX 与二进制的 scaler 参数后,在 MT5 测试器用相同设置跑 EA,GRU 模型约拿到 61% 的测试准确率——不如前两个模型,但作为轻量方案仍算能看。外汇与贵金属行情受突发事件扰动大,这类信号仅作概率参考,实盘前务必自测。 下面这段是构建与加载的核心代码,注意 GRU(50) 替换了原本的 LSTM 层,MT5 侧通过 #resource 把 onnx 与 scaler 均值/标准差二进制直接编进 EA。
from tensorflow.keras.layers class="kw">import GRU # Define the CNN model model = Sequential() model.add(Conv1D(filters=class="num">16, kernel_size=class="num">3, activation=&class="macro">#x27;relu&class="macro">#x27;, strides=class="num">2, padding=&class="macro">#x27;causal&class="macro">#x27;, input_shape=(time_step, X_train.shape[class="num">2]) ) ) model.add(MaxPooling1D(pool_size=class="num">2)) model.add(GRU(class="num">50, activation=&class="macro">#x27;relu&class="macro">#x27;)) model.add(Dropout(class="num">0.5)) model.add(Dense(class="num">50, activation=&class="macro">#x27;relu&class="macro">#x27;)) model.add(Dropout(class="num">0.5)) model.add(Dense(units=len(np.unique(y)), activation=&class="macro">#x27;softmax&class="macro">#x27;)) # For binary classification(e.g., buy/sell signal) model.summary() class="num">7/class="num">7 ━━━━━━━━━━━━━━━━━━━━ 1s 41ms/step Classification Report precision recall f1-score support class="num">0 class="num">0.69 class="num">0.39 class="num">0.50 class="num">117 class="num">1 class="num">0.45 class="num">0.73 class="num">0.55 class="num">78 accuracy class="num">0.53 class="num">195 macro avg class="num">0.57 class="num">0.56 class="num">0.53 class="num">195 weighted avg class="num">0.59 class="num">0.53 class="num">0.52 class="num">195 class="macro">#resource "\Files\gru+cnn.TSLA.D1.onnx" as class="type">uchar onnx_model[] class="macro">#resource "\Files\gru+cnn.TSLA.D1.standard_scaler_mean.bin" as class="type">class="kw">double standardization_mean[] class="macro">#resource "\Files\gru+cnn.TSLA.D1.standard_scaler_scale.bin" as class="type">class="kw">double standardization_std[] class="macro">#include <MALE5\Convolutional Neural Networks(CNNs)\ConvNet.mqh> class="macro">#include <MALE5\preprocessing.mqh> CConvNet cnn; StandardizationScaler *scaler;
「画得少,看得清」
把 CNN 与 RNN 揉进一个模型去猜行情,理论上有戏——卷积抓空间形态,递归抓时间依赖,确实能挖出单用一种网络漏掉的痕迹。但这类组合在实盘里少见不是没理由:过拟合首当其冲,模型在训练集漂亮、换批新数据就懵,尤其问题本身不复杂时更容易栽。 算力账也得算清楚。堆密集层、加神经元,显存和训练时间会直线飙,MT5 里跑 ONNX 推理还得平衡本地资源。本系列给的 CNN+RNN / GRU / LSTM EA 及 .onnx 模型,直接丢进 Experts 目录就能加载验证,外汇贵金属波动烈度高,复杂模型误判一样亏得快,先小样本回测再谈信任。 附件里的 cnns-rnns.ipynb 把 Python 侧训练全摊开了,想改结构就照着调。少画几张花哨曲线、多盯模型在新数据上的衰减,可能比堆复杂度更管用。