神经网络实验(第 4 部分):模板·进阶篇
🧠

神经网络实验(第 4 部分):模板·进阶篇

(2/3)·当 DeepNeuralNetwork 收益不如简单感知器,把价格带进扇形与三角形模板能否翻盘?

含代码示例实战向 第 2/3 篇

接上篇,我们继续深挖神经网络喂什么数据才不浪费。前一篇里函数库网络跑出的结果甚至不如单层感知器,问题大概率出在输入形态而非模型本身。

用感知机量化 48 根 K 线的位移结构

把近 48 根 K 线相对早期收盘价的点差离散成百点整数,是给后续模型喂特征的第一步。下面这段函数在 MT5 里直接取当前品种 PERIOD_CURRENT 的收盘价,算 48 棒前到 1、13、25、37 棒前的点差,再除以 Point() 转成整数点,最后用 (int)(a/100)*100 截断到百点级别,写进 xInputs 数组。 这种截断不是精度损失,而是把噪声磨掉:外汇和贵金属秒级跳动常带几点的毛刺,百点化后模型更关注波段骨架。回测 EURUSD M15 时,48 棒约覆盖 12 小时,xInputs[0] 若落在 300~700 区间,往往对应一段已被市场确认的中速趋势。 感知机部分另起一组变量,把外部传入的 x1~x4、y1~y4 各减 10.0 做偏移,再重算一套 a1~a4(这次对照的是 1、7、13、19 棒前)。两套窗口错位,等于让网络同时看慢速与快速位移残差。 别把正态当圣经:百点截断后分布明显厚尾,直接套均值方差容易低估跳空风险,贵金属尤其如此。

MQL5 / C++
class="type">int CandlePatterns(class="type">class="kw">double &xInputs[])
  {
  class="type">int a1 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point()));
  xInputs[class="num">0] = (class="type">int)(a1/class="num">100)*class="num">100;
  class="type">int a2 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13))/Point()));
  xInputs[class="num">1] = (class="type">int)(a2/class="num">100)*class="num">100;
  class="type">int a3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">25))/Point()));
  xInputs[class="num">2] = (class="type">int)(a3/class="num">100)*class="num">100;
  class="type">int a4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">37))/Point()));
  xInputs[class="num">3] = (class="type">int)(a4/class="num">100)*class="num">100;  
  class="kw">return(class="num">1);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|  The PERCEPRRON - a perceiving and recognizing function          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">double perceptron1()
  {
  class="type">class="kw">double w1 = x1 - class="num">10.0;
  class="type">class="kw">double w2 = x2 - class="num">10.0;
  class="type">class="kw">double w3 = x3 - class="num">10.0;
  class="type">class="kw">double w4 = x4 - class="num">10.0;
  class="type">class="kw">double v1 = y1 - class="num">10.0;
  class="type">class="kw">double v2 = y2 - class="num">10.0;
  class="type">class="kw">double v3 = y3 - class="num">10.0;
  class="type">class="kw">double v4 = y4 - class="num">10.0;
  class="type">int a1 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point()));
  a1 = (class="type">int)(a1/class="num">100)*class="num">100;
  class="type">int a2 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">7))/Point()));
  a2 = (class="type">int)(a2/class="num">100)*class="num">100;
  class="type">int a3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13))/Point()));
  a3 = (class="type">int)(a3/class="num">100)*class="num">100;
  class="type">int a4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">19))/Point()));
  a4 = (class="type">int)(a4/class="num">100)*class="num">100;

◍ 把多周期收盘差压成百点整数档

这段逻辑干的事很直接:拿当前品种 48 根 K 线前的收盘价,分别减去 25、31、37、43 根前的收盘价,再除以 Point() 转成整数点差,最后全部向下取整到百点(除以 100 乘 100)。b1~b4 就是四档「远端收盘位移」的百点快照,用来喂给后面的加权求和。 CandlePatterns 函数换了个写法,把同样思路的价差塞进 xInputs 数组:a1~a4 取 48 对 1/7/13/19 根前收盘差,g1~g2 取 48 对 25/31 根前收盘差,每个都压成百点整数。注意这里偏移步长是 6 根(1→7→13→19),而前一段 b 系列是 6 根但起点在 25,两组窗口错开覆盖,倾向把中短与中长波段位移都抓出来。 实盘里直接把这段贴进 MT5 自定义指标,symbolS1 换成你盯的 XAUUSD 或欧美对,跑出来 xInputs[0] 若等于 300,意味着 48 根前比 1 根前收盘高了约 300 点(按该品种 Point 计)。外汇与贵金属杠杆高,点差档位只是状态描述,不构成方向判断。

MQL5 / C++
class="type">int b1 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">25))/Point()));
 b1 = (class="type">int)(b1/class="num">100)*class="num">100;
 class="type">int b2 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">31))/Point()));
 b2 = (class="type">int)(b2/class="num">100)*class="num">100;
 class="type">int b3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">37))/Point()));
 b3 = (class="type">int)(b3/class="num">100)*class="num">100;
 class="type">int b4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">43))/Point()));
 b4 = (class="type">int)(b4/class="num">100)*class="num">100;

 class="kw">return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4  +   v1 * b1 + v2 * b2 + v3 * b3 + v4 * b4);
 }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|percentage of each part of the candle respecting total size       |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int CandlePatterns(class="type">class="kw">double &xInputs[])
  {

  class="type">int a1 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point()));
  xInputs[class="num">0] = (class="type">int)(a1/class="num">100)*class="num">100;
  class="type">int a2 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">7))/Point()));
  xInputs[class="num">1] = (class="type">int)(a2/class="num">100)*class="num">100;
  class="type">int a3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13))/Point()));
  xInputs[class="num">2] = (class="type">int)(a3/class="num">100)*class="num">100;
  class="type">int a4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">19))/Point()));
  xInputs[class="num">3] = (class="type">int)(a4/class="num">100)*class="num">100;

  class="type">int g1 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">25))/Point()));
  xInputs[class="num">4] = (class="type">int)(g1/class="num">100)*class="num">100;
  class="type">int g2 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">31))/Point()));
  xInputs[class="num">5] = (class="type">int)(g2/class="num">100)*class="num">100;

「感知机与K线比例特征的取整套路」

这段逻辑把近期收盘价差值换算成点数,再按 100 点一档向下取整,塞进模型输入数组。比如 48 周期与 37 周期收盘差除以 Point 后,g3 先转整型,xInputs[6] 只保留百位以上的整百值,过滤掉小噪音。 perceptron1() 里 w1~w4 各自减 10.0 做偏移,再乘上 a1~a4 四个取整后的点差特征。a1 用 1 周期与 24 周期收盘各加 800 点后的均值减现价,a2~a4 则混合不同周期与 ±800 点偏移,最终返回加权求和,倾向作为线性判别分数。 CandlePatterns() 开头重算了一遍 a1,同样除以 Point 后按 100 取整写进 xInputs[0]。这种把价格差压成整百点数的做法,能让外汇与贵金属这类高波动品种在 MT5 上跑时减少过拟合,但杠杆市场高风险,回测盈利不代表实盘概率同高。 直接把下面代码贴进 MT5 自定义指标或 EA 的同类函数里,改 symbolS1 为你盯的 XAUUSD 或 EURUSD,就能看取整后的输入分布。

MQL5 / C++
class="type">int g3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">37))/Point()));
 xInputs[class="num">6] = (class="type">int)(g3/class="num">100)*class="num">100;
 class="type">int g4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">43))/Point()));
 xInputs[class="num">7] = (class="type">int)(g4/class="num">100)*class="num">100;

 class="kw">return(class="num">1);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|  The PERCEPRRON - a perceiving and recognizing function          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">double perceptron1()
 {
 class="type">class="kw">double w1 = x1 - class="num">10.0;
 class="type">class="kw">double w2 = x2 - class="num">10.0;
 class="type">class="kw">double w3 = x3 - class="num">10.0;
 class="type">class="kw">double w4 = x4 - class="num">10.0;

 class="type">int a1 = (class="type">int)((((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">800*Point()))+(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))/class="num">2)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point());
 a1 = (class="type">int)(a1/class="num">100)*class="num">100;
 class="type">int a2 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">7)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)-(class="num">800*Point())))/Point());
 a2 = (class="type">int)(a2/class="num">100)*class="num">100;
 class="type">int a3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13))/Point());
 a3 = (class="type">int)(a3/class="num">100)*class="num">100;
 class="type">int a4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)-(class="num">800*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">19))/Point());
 a4 = (class="type">int)(a4/class="num">100)*class="num">100;

 class="kw">return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|percentage of each part of the candle respecting total size        |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int CandlePatterns(class="type">class="kw">double &xInputs[])
 {

 class="type">int a1 = (class="type">int)((((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">800*Point()))+(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))/class="num">2)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point());
 xInputs[class="num">0] = (class="type">int)(a1/class="num">100)*class="num">100;

感知机里的特征量化与权重偏移

这段逻辑把价格距离换算成以 100 点为步长的整数特征,再喂给一个简化版感知机做线性组合。外汇与贵金属市场波动剧烈、杠杆风险高,这类特征工程只是信号生成的输入环节,不代表任何方向确定性。 先在前半段用 iClose 取不同偏移 K 线的收盘价,叠加 800 点常量后再除以 Point(),把绝对价差转成点数;a2、a3、a4 分别用 7/1、24/13、24/19 的收盘价组合,最后都做 (int)(a/100)*100 的百点取整,写进 xInputs[1~3]。 perceptron1() 里给 x1~x4 各减 10.0 作为权重 w1~w4,再算一组以 1200 点为基准的 a1~a4(覆盖 1、13、25、37、48 根 K 线),同样百点取整,返回 w1*a1+w2*a2+w3*a3+w4*a4 的加权和。 开 MT5 把这段代码贴进 EA 测试:把 800/1200 点常量改成你品种的平均波动点数,感知机输出分布可能明显变化;黄金 M15 上 1200 点约合 12 美元,调参前先确认 Point() 精度。

MQL5 / C++
  class="type">int a2 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">7)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)-(class="num">800*Point())))/Point());
  xInputs[class="num">1] = (class="type">int)(a2/class="num">100)*class="num">100;
  class="type">int a3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13))/Point());
  xInputs[class="num">2] = (class="type">int)(a3/class="num">100)*class="num">100;
  class="type">int a4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)-(class="num">800*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">19))/Point());
  xInputs[class="num">3] = (class="type">int)(a4/class="num">100)*class="num">100;

  class="kw">return(class="num">1);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|  The PERCEPRRON - a perceiving and recognizing function          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">double perceptron1()
  {
  class="type">class="kw">double w1 = x1 - class="num">10.0;
  class="type">class="kw">double w2 = x2 - class="num">10.0;
  class="type">class="kw">double w3 = x3 - class="num">10.0;
  class="type">class="kw">double w4 = x4 - class="num">10.0;

  class="type">int a1 = (class="type">int)((((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">1200*Point()))+(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)+(class="num">1200*Point()))/class="num">2)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point());
  a1 = (class="type">int)(a1/class="num">100)*class="num">100;
  class="type">int a2 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)-(class="num">1200*Point())))/Point());
  a2 = (class="type">int)(a2/class="num">100)*class="num">100;
  class="type">int a3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)+(class="num">1200*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">25))/Point());
  a3 = (class="type">int)(a3/class="num">100)*class="num">100;
  class="type">int a4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-(class="num">1200*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">37))/Point());
  a4 = (class="type">int)(a4/class="num">100)*class="num">100;

  class="kw">return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|percentage of each part of the candle respecting total size        |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int CandlePatterns(class="type">class="kw">double &xInputs[])
  {

◍ 把价差压成整百点阵喂给感知机

这段逻辑干的事很直白:把不同 K 线收盘价的差加上一个固定偏移(1200 点或 800 点),除以 Point() 转成整数点值,再向下取整到百点倍数,塞进 xInputs 数组。偏移量不是随机的——1200 点在外汇常见品种上约等于 12 美元波动带,用来把近期价格结构抬进正整数区间,避免负号干扰后续矩阵运算。 以 a1 为例:取前一根收盘加 1200 点,与 48 根前收盘加 1200 点取平均,再减前一根收盘,得到的就是 48 周期中值相对即时的偏离,用 Point() 归一。a2、a3、a4 分别捕捉 13 根、48 对 25 根、48 减 1200 点对 37 根的跨度,全数百点化后入参。 perceptron1() 里把外部传入的 x1~x4、y1~y4 各减 10.0 做中心化,同时用更窄的 800 点偏移重算了一套 a1~a3:周期压缩到 24、5、9,说明第二套感知器更盯短线。你在 MT5 里把 1200 改成 800 或把 48 改成 24,会直接看到 xInputs 分布整体左移,模型对近期扰动的权重可能变大。 外汇和贵金属杠杆高、点差跳变频繁,这类整百点量化只是特征工程一步,实盘信号概率会随品种流动性漂移,务必先开策略测试器跑历史段验证。

MQL5 / C++
class="type">int a1 = (class="type">int)((((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">1200*Point()))+(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)+(class="num">1200*Point()))/class="num">2)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point());
xInputs[class="num">0] = (class="type">int)(a1/class="num">100)*class="num">100;
class="type">int a2 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)-(class="num">1200*Point())))/Point());
xInputs[class="num">1] = (class="type">int)(a2/class="num">100)*class="num">100;
class="type">int a3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)+(class="num">1200*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">25))/Point());
xInputs[class="num">2] = (class="type">int)(a3/class="num">100)*class="num">100;
class="type">int a4 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">48)-(class="num">1200*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">37))/Point());
xInputs[class="num">3] = (class="type">int)(a4/class="num">100)*class="num">100;

class="kw">return(class="num">1);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|  The PERCEPRRON - a perceiving and recognizing function          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">double perceptron1()
  {
  class="type">class="kw">double w1 = x1 - class="num">10.0;
  class="type">class="kw">double w2 = x2 - class="num">10.0;
  class="type">class="kw">double w3 = x3 - class="num">10.0;
  class="type">class="kw">double w4 = x4 - class="num">10.0;

  class="type">class="kw">double v1 = y1 - class="num">10.0;
  class="type">class="kw">double v2 = y2 - class="num">10.0;
  class="type">class="kw">double v3 = y3 - class="num">10.0;
  class="type">class="kw">double v4 = y4 - class="num">10.0;

  class="type">int a1 = (class="type">int)((((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">800*Point()))+(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))/class="num">2)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point());
  a1 = (class="type">int)(a1/class="num">100)*class="num">100;
  class="type">int a2 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">5)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">800*Point())))/Point());
  a2 = (class="type">int)(a2/class="num">100)*class="num">100;
  class="type">int a3 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">9)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)-(class="num">800*Point())))/Point());
  a3 = (class="type">int)(a3/class="num">100)*class="num">100;

「把 K 线局部比例塞进特征数组」

这段逻辑接着前面的加权打分,把单根与相邻 K 线的相对位置量化后写进 xInputs 数组,供后续模型或规则使用。注意所有偏移都叠了 800*Point(),相当于在现价上下各留 8 个点的缓冲带,避免点差和报价跳动把整数百点边界弄脏。 a1 取的是第 1 根收盘加上缓冲、与第 24 根收盘加缓冲的一半,再减第 1 根收盘,除 Point 后取整并百点化,填入 xInputs[0]。a2 用第 5 根减第 1 根加缓冲,a3 用第 9 根减第 1 根减缓冲,同样百点化后写进 xInputs[1]、xInputs[2]。 开 MT5 把这段贴进 EA 或脚本,把 symbolS1 换成你盯的 XAUUSD 或 EURUSD,打印 xInputs 看在 15 分钟图上数值是否集中在 0~800 区间;外汇和贵金属杠杆高,信号仅作概率参考,实盘前先用历史数据验证分布。

MQL5 / C++
class="type">int a4 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">800*Point())))/Point());
  a4 = (class="type">int)(a4/class="num">100)*class="num">100;
  class="type">int b1 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">13))/Point());
  b1 = (class="type">int)(b1/class="num">100)*class="num">100;
  class="type">int b2 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">17))/Point());
  b2 = (class="type">int)(b2/class="num">100)*class="num">100;
  class="type">int b3 = (class="type">int)(((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)-(class="num">800*Point()))-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">21))/Point());
  b3 = (class="type">int)(b3/class="num">100)*class="num">100;
  class="type">int b4 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)-((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)-(class="num">800*Point()))+(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)-(class="num">800*Point()))/class="num">2))/Point()) ;
  b4 = (class="type">int)(b4/class="num">100)*class="num">100;
  class="kw">return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4   +   v1 * b1 + v2 * b2 + v3 * b3 + v4 * b4);
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|percentage of each part of the candle respecting total size        |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int CandlePatterns(class="type">class="kw">double &xInputs[])
  {
  
  class="type">int a1 = (class="type">int)((((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">800*Point()))+(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">24)+(class="num">800*Point()))/class="num">2)-iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1))/Point());
  xInputs[class="num">0] = (class="type">int)(a1/class="num">100)*class="num">100;
  class="type">int a2 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">5)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)+(class="num">800*Point())))/Point());
  xInputs[class="num">1] = (class="type">int)(a2/class="num">100)*class="num">100;
  class="type">int a3 = (class="type">int)((iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">9)-(iClose(symbolS1.Name(),PERIOD_CURRENT,class="num">1)-(class="num">800*Point())))/Point());
  xInputs[class="num">2] = (class="type">int)(a3/class="num">100)*class="num">100;
把重复劳动交给小布
这些形态识别与多模板前向验证的批量诊断,小布盯盘的 AIGC 已内置,打开对应品种页即可看到历史深度与参数维度的稳定性评分,你只管调策略方向。

常见问题

倾向是传递给网络的数据散射范围过大、缺乏稳定结构,导致训练无法收敛出可复用规律;本篇改用形态模板压缩输入维度来应对。
文中通过 3 年优化加 1 年前向验证对比,具体优劣随历史深度与参数数量变化,概率上模板形态比裸价格序列更利于网络判定。
5 位报价下用较大止损包容噪声、较小止盈锁定微观波动,并显式计入点差,避免在回溯里虚高盈利。
可以,品种页的 AIGC 模块内置了形态跟踪与多窗口验证视图,你导入模板参数就能看复杂准则下的稳定性,不必自己搭脚本。
复杂准则偏好在样本外也稳健的参数组合,实盘中外汇贵金属高风险环境下过拟合概率更低。