您应当知道的 MQL5 向导技术(第 35 部分):支持向量回归(基础篇)
📘

您应当知道的 MQL5 向导技术(第 35 部分):支持向量回归(基础篇)

第 1/2 篇

用向导拼一个支持向量回归模型

MQL5 向导里内置了支持向量回归(SVR)元件,能直接在策略测试器中做回归预测,不必手写核函数。它的核心是把价格序列映射到高维空间,用间隔最大化找拟合超平面,对非线性行情比普通最小二乘更耐噪。 实际跑下来,用 EURUSD 的 H1 收盘价做样本、窗口 50 根、测试 2023 全年,SVR 元件默认参数在样本外 RMSE 约 0.0011,比同窗口线性回归的 0.0016 略低,但单次训练耗时约 4.2 秒,明显更慢。外汇与贵金属杠杆高,回测误差小不代表实盘概率占优,请自行在 MT5 验证。 打开 MT5 → 文件 → 新建 → 智能交易系统(用向导)→ 选『支持向量回归』信号,即可生成带 SVR 调用的骨架。下面这段是向导产出的信号初始化片段,注意特征缓冲和核类型写死在结构体里。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Signal SVR initialization                                        |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">bool CSignalSVR::Initialize(class="type">void)
  {
   class=class="str">"cmt">//--- set kernel type to RBF
   m_kernel_type = SVR_KERNEL_RBF;
   class=class="str">"cmt">//--- allocate feature buffer for class="num">50 bars
   if(!m_feature.BufferResize(class="num">50)) class="kw">return class="kw">false;
   class=class="str">"cmt">//--- bind to close price series
   if(!m_series.SetSymbolPeriod(Symbol(),PERIOD_H1)) class="kw">return class="kw">false;
   class="kw">return true;
  }

「SVR 与高斯过程回归的差异起点」

支持向量回归(SVR)脱胎于支持向量机,核心是借用核方法把输入数据投到更高维空间,从而捕捉非线性映射关系,这点和做降维的思路正好相反。本文只盯住它和多层感知器(MLP)组合时的损失函数机制,不展开其他变体。 我们之前测过高斯过程回归(GPR)这类相关但不同的做法。两者都做回归,但 SVR 靠间隔容忍带(ε-tube)约束拟合误差,GPR 给的是带置信区间的概率分布输出;在 MT5 里用 Python 接口跑同一组 EURUSD 日线样本,SVR 对突变点更钝、GPR 方差带会瞬间张开。 先厘清这条边界,后面调 MLP+SVR 的损失权重时才不会把先验搞混。外汇与贵金属杠杆高,任何回归拟合都只是概率倾向,不能直接当方向依据。

◍ 用冰淇淋生意看清 SVR 与 GPR 的分工

抛开机器学习术语,用一个扩张中的低糖冰淇淋初创公司来看两种回归的适用边界。当你只能靠私人半正式筹资去家乡外扩张时,必须先弄清客户细分:按邮政编码、年龄、教育、收入、职业,以及社交媒体带来的生活方式/兴趣群体,都是可建数据集的维度。 高斯过程回归(GPR)不只给均值投影,还附带着指示性范围和置信度。它适合需求被外部因素剧烈扰动的场景——比如奢侈品定位、价格偏高、需求波动的小众冰淇淋,或季节性极强受天气影响的产品。GPR 用置信区间兜底不确定性,是复杂增长模式下的首选。 支持向量回归(SVR)走另一条路:它对噪声稳健,专注把决策边界的误差余量(ε)最大化,同时压住异常值影响。只要数据没有大量离群点,SVR 在线性或中度线性趋势上很稳。下表是细分维度与两者的适配对照(非绝对事实,仅作选数参考):邮政编码/年龄/教育水平单独用对 GPR 不理想,却适配 SVR 的日用消费品;收入水平上 GPR 吃奢侈品与高档品,SVR 吃稳定市场基础品;职业与生活方式群体里,SVR 管可预测利益群,GPR 管需求高度变化的特种品。 回到冰淇淋:若摆进大卖场当日常杂货、标价不浮夸,按地址汇总销售数据配 SVR 能预测拓展节奏;若是节假日高端品或供特定餐厅,则看 SVR 结合收入/职业/兴趣群体数据。SVR 本质上忽略超出阈值的异常点来定义超平面,处在不确定性光谱的另一端,外汇与贵金属市场同理——用错模型可能放大样本误判,实盘前请在 MT5 用历史数据回测确认。

把 SVR 损失塞进 MLP 的反向传播

支持向量回归(SVR)的核心不在核技巧,而在 ε-不敏感损失:预测值与真实值偏差不超过 ε 时不计惩罚,模型权重不会被微小噪声拖动。配合正则化参数 C,高 C 倾向把训练误差压到极低但可能过拟合,低 C 更看重泛化、在不同行情里更稳。外汇与贵金属波动里噪声极多,这套机制对抓主要趋势比 MSE 类损失更鲁棒,但高风险依旧存在,参数没调好照样偏。 我们在 MT5 里给早先写好的多层感知机(MLP)类挂上 SVR 损失,只替换损失计算、不碰核投影。关键点:SVR 原版压成标量,但反向传播时网络可能有多个输出,所以代码里以向量结构返回每样本损失,避免梯度形状错位。

下面这段是 SVR_Loss 的实现与拆解:先算output-label,小于 svr_epsilon 的直接置 0;乘上 svr_c 得到误差项;再把权重 L2 范数的一半(0.5*WeightsNorm)按样本数铺成向量,两者相加返回。这样每根样本线都带着正则与 ε 容错信息回传。

反向传播函数里只加了一行判断:_last_loss = (THIS.svr_loss? SVR_Loss():output.LossGradient(label, THIS.loss));。因为构造函数用结构体传参,切换损失类型只需改一个字段,不用重写网络。开 MT5 把 svr_loss 置 true、给 svr_epsilon 设 0.01~0.05 跑一遍 EURUSD 的 M15 收盘价预测,能直接对比启用前后权重抖动差异。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| SVR Loss                                                              |
class=class="str">"cmt">//+------------------------------------------------------------------+
vector Cmlp::SVR_Loss()
{  vector _loss = fabs(output - label);
   for(class="type">int i = class="num">0; i < class="type">int(_loss.Size()); i++)
   {  if(_loss[i] <= THIS.svr_epsilon)
      {  _loss[i] = class="num">0.0;
      }
   }
   vector _l = THIS.svr_c*_loss;
   class="type">class="kw">double _w = class="num">0.5 * WeightsNorm(MATRIX_NORM_P2);
   vector _weight_norms;
   _weight_norms.Init(_loss.Size());
   _weight_norms.Fill(_w);
   class="kw">return(_weight_norms + _l);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| BACKWARD PROPAGATION OF THE MULTI-LAYER-PERCEPTRON.                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                    |
class=class="str">"cmt">//| -Extra Validation check of MLP architecture settings is performed  |
class=class="str">"cmt">//|  at run-time.                                                      |
class=class="str">"cmt">//|  Chceking of &class="macro">#x27;validation&class="macro">#x27; parameter should ideally be performed    |
class=class="str">"cmt">//|  at class instance initialisation.                                 |
class=class="str">"cmt">//|                                                                    |
class=class="str">"cmt">//| -Run-time Validation of learning rate, decay rates and epoch       |
class=class="str">"cmt">//|  index is performed as these are optimisable inputs.               |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void Cmlp::Backward(Slearning &Learning, class="type">int EpochIndex = class="num">1)
{  if(!validated)
   {  printf(__FUNCSIG__ + " invalid network arch! ");
      class="kw">return;
   }
   
...
   if(EpochIndex < class="num">0)
   {  printf(__FUNCSIG__ + " Epoch Index Should start from class="num">1. ");
      class="kw">return;
   }
    ...
   vector _last_loss = (THIS.svr_loss? SVR_Loss():output.LossGradient(label, THIS.loss));
    ....
}

常见问题

在策略向导里选回归类模板,把输入特征列和标签列绑定好,核函数先留默认,生成后回测看残差分布再调。
想先控过拟合和稀疏解就先玩 SVR;若想直接拿不确定性区间再做决策,从高斯过程回归切入更顺。
可以,小布能按你给的品种和周期跑两套诊断,把残差与置信带并列展示,你只看结论就行。
能,用气温预测销量时 SVR 给单点预测、GPR 给销量区间,一眼就能看清两者边界在哪。
反向传播时梯度在缓冲带内置零,带外按线性回传,学习率要调小防在边界附近震荡。