神经网络实验(第 1 部分):重温几何学(基础篇)
📘

神经网络实验(第 1 部分):重温几何学(基础篇)

第 1/2 篇

◍ 用几何直觉拆开神经网络的第一层

很多交易者一听到神经网络就觉得是黑箱,其实最浅的那一层本质就是高维空间里的几何变换。把输入特征看成坐标点,权重矩阵就是一次旋转加拉伸,偏置项把整个点云平移。理解这一步,后面反向传播的数学才不会悬空。 在 MT5 里跑一个最小感知机做验证,比看公式直观得多。下面这段用矩阵乘法算单层输出,输入是三根均线的归一化差值,输出一个原始信号强度。 外汇与贵金属杠杆高、滑点随机,信号强度只是概率倾向,不是方向保证。建议先用 EURUSD 的 M1 历史跑一遍,观察权重在 200 根 K 线内的漂移,再决定要不要接激活函数。

MQL5 / C++
class="type">class="kw">double Input[class="num">3] = {class="num">0.2, -class="num">0.1, class="num">0.05};   class=class="str">"cmt">// 三根均线归一化差值作为输入
class="type">class="kw">double Weight[class="num">3] = {class="num">0.6, -class="num">0.3, class="num">0.8}; class=class="str">"cmt">// 对应权重
 class="type">class="kw">double Bias = class="num">0.05;                  class=class="str">"cmt">// 偏置项
class="type">class="kw">double Output = Bias;                 class=class="str">"cmt">// 初始化输出为偏置
 for(class="type">int i=class="num">0; i<class="num">3; i++)               class=class="str">"cmt">// 遍历三个输入
   Output += Input[i] * Weight[i];    class=class="str">"cmt">// 加权累加
 class=class="str">"cmt">// 此时 Output 即单层线性变换后的原始信号

「为什么现成神经网络素材落不了地」

MQL5 社区里关于神经网络的文章、函数库和源码数量已经不少,光是公开可参考的 EA 框架就有几十套,但翻完一圈会发现一个共性问题:理论模块齐全,却没人把「输入特征→训练→实盘信号」串成一条能跑通的逻辑链。 多数示例停在回测曲线漂亮这一步,没有给出样本外验证和品种适配办法,直接搬去 EURUSD 或 XAUUSD 实盘,胜率往往会从回测的 70% 掉到 50% 边缘,外汇和贵金属的高杠杆会迅速放大这种偏差。 这篇里我把自己作为非专家、也给初学者做的实验过程摊开:不堆公式,只说怎么让网络输出变成下单依据,以及哪些坑是 MT5 里亲手跑过才发现的。

从几何形态到均线的网络输入

神经网络擅长抓形态,但喂进去的训练数据决定上限。我默认这个前提成立,并打算把几何形状直接映射进网络结构。 最初参考了 MetaTrader 4 的一个智能系统样本(MTC Combo),其底层是一个常规感知器。我在 MT5 里复现测试时,弃用了振荡器,改用均线作为主输入——回测里振荡器方案几乎不出有效信号。 大家都知道价格涨、 oscillator 跌的背离,但振荡器离价格本体太远。均线参数紧贴报价,作为几何形态的量化代理更稳,后续网络也更容易学到边界。

◍ 把均线关系捏成可喂模型的几何形状

基准用两条均线搭出来:周期 1 和 24、简单平均、收盘价。思路不是只给网络当前均线位置,而是把「当前之前的状态」也编码进去。直接把价格丢给神经网络基本是走弯路——价格可能在十年区间里乱晃,范围根本不固定。 正确做法是传价值点:所有数值压进一个固定区间,超不出边界。构建形状时,指标参数数量可多可少,形状能简能繁。下面几种是实测可用的结构:形状1取已收盘蜡烛 1、4、7、10 距 MA1 与 MA24 差值的点数;形状2取 1-4、4-7、7-10 三段距 MA1 的点数;形状3同理换成 MA24。 稍微复杂些的:形状4叫蝴蝶,用蜡烛 1—10 距 MA1、距 MA24 的点数,再加蜡烛1的 MA1 与蜡烛10的 MA24 互距、蜡烛1的 MA24 与蜡烛10的 MA1 互距,四条线一交就是蝶形。形状5是四边形,取两端蜡烛距双指标差、以及 MA1/MA24 各自 1—10 的跨度。形状6把前述全拼一起,喂给一个复杂形状。 代码里 perceptron1 到 perceptron5 就是这些形状的量化实现。以 perceptron1 为例:w1~w4 是权重偏置(各减 100.0),a1~a4 算的是 ind_In1 与 ind_In2 在柱 1/4/7/10 的差除以 Point() 转点数,返回加权求和。perceptron4 的 a3、a4 交叉取了不同均线的首尾柱距,对应蝴蝶的对角翼。 外汇和贵金属杠杆高、跳空频繁,这种形状构造只解决特征表达,不预示方向。开 MT5 把 ind_In1/ind_In2 接成你的 MA(1)/MA(24),改 perceptron 里的柱位就能验证哪类形状对当前品种更敏感。

MQL5 / C++
class="type">class="kw">double perceptron1()
  {
   class="type">class="kw">double w1 = x1 - class="num">100.0;
   class="type">class="kw">double w2 = x2 - class="num">100.0;
   class="type">class="kw">double w3 = x3 - class="num">100.0;
   class="type">class="kw">double w4 = x4 - class="num">100.0;
  
   class="type">class="kw">double a1 = (ind_In1[class="num">1]-ind_In2[class="num">1])/Point();
   class="type">class="kw">double a2 = (ind_In1[class="num">4]-ind_In2[class="num">4])/Point();
   class="type">class="kw">double a3 = (ind_In1[class="num">7]-ind_In2[class="num">7])/Point();
   class="type">class="kw">double a4 = (ind_In1[class="num">10]-ind_In2[class="num">10])/Point();

   class="kw">return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }
class="type">class="kw">double perceptron2()
  {
   class="type">class="kw">double w1 = y1 - class="num">100.0;
   class="type">class="kw">double w2 = y2 - class="num">100.0;
   class="type">class="kw">double w3 = y3 - class="num">100.0;
  
   class="type">class="kw">double a1 = (ind_In1[class="num">1]-ind_In1[class="num">4])/Point();
   class="type">class="kw">double a2 = (ind_In1[class="num">4]-ind_In1[class="num">7])/Point();
   class="type">class="kw">double a3 = (ind_In1[class="num">7]-ind_In1[class="num">10])/Point();

   class="kw">return (w1 * a1 + w2 * a2 + w3 * a3);
  }
class="type">class="kw">double perceptron3()
  {
   class="type">class="kw">double w1 = z1 - class="num">100.0;
   class="type">class="kw">double w2 = z2 - class="num">100.0;
   class="type">class="kw">double w3 = z3 - class="num">100.0;
  
   class="type">class="kw">double a1 = (ind_In2[class="num">1]-ind_In2[class="num">4])/Point();
   class="type">class="kw">double a2 = (ind_In2[class="num">4]-ind_In2[class="num">7])/Point();
   class="type">class="kw">double a3 = (ind_In2[class="num">7]-ind_In2[class="num">10])/Point();
  
   class="kw">return (w1 * a1 + w2 * a2 + w3 * a3);
  }
class="type">class="kw">double perceptron4()
  {
   class="type">class="kw">double w1 = f1 - class="num">100.0;
   class="type">class="kw">double w2 = f2 - class="num">100.0;
   class="type">class="kw">double w3 = f3 - class="num">100.0;
   class="type">class="kw">double w4 = f4 - class="num">100.0;
  
   class="type">class="kw">double a1 = (ind_In1[class="num">1]-ind_In1[class="num">10])/Point();
   class="type">class="kw">double a2 = (ind_In2[class="num">1]-ind_In2[class="num">10])/Point();
   class="type">class="kw">double a3 = (ind_In1[class="num">1]-ind_In2[class="num">10])/Point();
   class="type">class="kw">double a4 = (ind_In2[class="num">1]-ind_In1[class="num">10])/Point();
  
   class="kw">return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }
class="type">class="kw">double perceptron5()
  {
   class="type">class="kw">double w1 = c1 - class="num">100.0;
   class="type">class="kw">double w2 = c2 - class="num">100.0;
   class="type">class="kw">double w3 = c3 - class="num">100.0;
   class="type">class="kw">double w4 = c4 - class="num">100.0;
  
   class="type">class="kw">double a1 = (ind_In1[class="num">1]-ind_In1[class="num">10])/Point();
   class="type">class="kw">double a2 = (ind_In2[class="num">1]-ind_In2[class="num">10])/Point();

常见问题

多数现成案例用的是图像或文本数据,没把均线和价格关系转成几何形状喂给模型,落地前得先重构输入结构。
把均线差值、斜率和相对位置算成向量坐标,当作几何点输入第一层,比裸价格序列更稳。
小布可自动提取品种页的均线几何特征并标注形态,你直接看诊断不用自己写计算脚本。
本质是把输入空间做线性分割,看哪些价格几何区域被归为一类,用来判断趋势边界。
贵金属波动受消息驱动大,几何形态可能突然失效,务必用小样本回测且控仓位。