在算法交易中 KOHONEN 神经网络的实际应用  第二部分优化和预测·进阶篇
🧠

在算法交易中 KOHONEN 神经网络的实际应用 第二部分优化和预测·进阶篇

(2/3)·从长报告里挑参数总靠肉眼?自组织映射把稳健区间和走势预判交给算法

含代码示例偏理论 第 2/3 篇

优化跑完拿到几百行测试报告,按利润排和按夏普排给出的参数经常是两码事。系统吐出一堆等价结果时,人肉挑设置往往凭直觉而非统计结构。把选择阶段仍留给肉眼,等于让算法交易在最后一公里回到手工。

「信号组合与风控参数的实盘可调区间」

这套 EA 把 RSI、Envelopes 和 AO 三个指标做了加权合成,再叠加抛物转向追踪止损与固定比例风控。默认输入里,RSI 周期设为 8、Envelopes 均线周期 45、通道偏移 0.15%,挂单过期 4 根柱,属于偏短线的组合。 但回测调参时这些默认值常被推翻。实测一组替代参数:RSI 周期拉到 73、Envelopes 周期缩到 20、偏移放宽到 0.5%,开仓阈值 40、平仓阈值 85,抛物转向步长 0.15、最大值 1.59,风险百分比 5.0。外汇与贵金属杠杆高,参数激进度上升后回撤可能显著放大,需用 MT5 策略测试器自行验证。 代码里的输入块直接决定了信号权重与止损逻辑,逐行看才能知道每根线在管什么。

MQL5 / C++
class="kw">input class="type">int                Signal_Expiration           =class="num">4;        class=class="str">"cmt">// 挂单的过期时间 (柱数)
class="kw">input class="type">int                Signal_RSI_PeriodRSI        =class="num">8;        class=class="str">"cmt">// 相对强弱指数 RSI(class="num">8,...)的计算周期数
class="kw">input ENUM_APPLIED_PRICE Signal_RSI_Applied          =PRICE_CLOSE; class=class="str">"cmt">// 相对强弱指数 RSI(class="num">8,...) 价格序列
class="kw">input class="type">class="kw">double             Signal_RSI_Weight           =class="num">1.0;       class=class="str">"cmt">// 相对强弱指数 RSI(class="num">8,...) 权重 [class="num">0...class="num">1.0]
class="kw">input class="type">int                Signal_Envelopes_PeriodMA   =class="num">45;        class=class="str">"cmt">// Envelopes(class="num">45,class="num">0,MODE_SMA,...) 平均周期数
class="kw">input class="type">int                Signal_Envelopes_Shift      =class="num">0;         class=class="str">"cmt">// Envelopes(class="num">45,class="num">0,MODE_SMA,...) 时间偏移
class="kw">input ENUM_MA_METHOD     Signal_Envelopes_Method     =MODE_SMA;  class=class="str">"cmt">// Envelopes(class="num">45,class="num">0,MODE_SMA,...) 平均的方法
class="kw">input ENUM_APPLIED_PRICE Signal_Envelopes_Applied    =PRICE_CLOSE;class=class="str">"cmt">// Envelopes(class="num">45,class="num">0,MODE_SMA,...) 价格序列
class="kw">input class="type">class="kw">double             Signal_Envelopes_Deviation  =class="num">0.15;      class=class="str">"cmt">// Envelopes(class="num">45,class="num">0,MODE_SMA,...) 偏移
class="kw">input class="type">class="kw">double             Signal_Envelopes_Weight     =class="num">1.0;       class=class="str">"cmt">// Envelopes(class="num">45,class="num">0,MODE_SMA,...) 权重 [class="num">0...class="num">1.0]
class="kw">input class="type">class="kw">double             Signal_AO_Weight             =class="num">1.0;       class=class="str">"cmt">// AO指标权重 [class="num">0...class="num">1.0]
class=class="str">"cmt">//--- 用于跟踪止损的输入参数
class="kw">input class="type">class="kw">double             Trailing_ParabolicSAR_Step   =class="num">0.02;      class=class="str">"cmt">// 速度增加值
class="kw">input class="type">class="kw">double             Trailing_ParabolicSAR_Maximum=class="num">0.2;       class=class="str">"cmt">// 最大比率
class=class="str">"cmt">//--- 用于资金管理的输入参数
class="kw">input class="type">class="kw">double             Money_FixRisk_Percent=class="num">5.0;                class=class="str">"cmt">// 风险百分比

自组织映射跑完后的参数与掩码读数

这段输出是某次 EA 参数优化后自组织映射(SOM)降维显示的原始打印。表头先列了 13 个维度:Profit、Profit Factor、Recovery Factor、Sharpe Ratio、Equity DD %、Trades,以及 7 个信号与 trailing 参数,最后一行 Trailing_ParabolicSAR_Maximum 是第 12 号特征。 看 N0 [3,2] 这组:净利润 18780.87,盈利因子 1.97233,恢复因子 3.60269,夏普 0.38653,回撤 16.77%,共 63 笔交易;对应信号阈值为开 20、平 66,RSI 周期 24,包络均线 20、偏离 0.5,SAR 步长 0.14、最大值 1.46,FeatureMask=1111110000000 表示前 6 维参与训练后掩码。 切到 N0 [14,1] 这组,净利润降到 17806.57,但盈利因子跳到 2.79534、恢复因子 6.78011、夏普 0.48506,回撤压缩到 10.70%,交易数 49.9;此时开仓阈值 40、平仓 86,RSI 周期变成 74,SAR 步长 0.13、最大值 1.29,掩码翻成 0000001111111 且 FeatureMaskAfterTraining=false——说明这组用的是后 7 维原始特征、未做训练后筛选。外汇与贵金属品种下这种参数迁移仅代表历史样本表现,实盘存在显著回撤扩大风险,概率上更优不代表必然稳健。 CSOMDisplayRGB 这个类继承自 CSOMDisplay,内部挂了 indexRGB[]、enabled、showrgb 三个成员,负责把 SOM 节点映射成 RGB 颜色供可视化,你可以直接把这段抄进 MT5 头文件里改自己的显示层。

MQL5 / C++
class CSOMDisplayRGB: class="kw">public CSOMDisplay
{
  class="kw">protected:
    class="type">int indexRGB[];
    class="type">bool enabled;
    class="type">bool showrgb;

◍ 用特征串驱动自组织映射的 RGB 渲染

在 MT5 里做 Kohonen 网络可视化时,可以用一个字符序列直接决定哪些特征维度参与 RGB 着色。代码里的 FeatureDirection 就是这种控制串,例如 FeatureDirection=++,,-​ 表示前两个特征正向映射、中间两个忽略、最后一个反向映射。 核心入口是 EnableRGB(),它接收一个 int 数组 rgbmask,数组长度必须等于特征方向串的长度。下面这段逻辑把字符串每个字符转成偏移量:逗号对应 0(屏蔽),加减号对应正负权重,转换式为 rgbmask[i] = -(StringGetCharacter(FeatureDirection, i) - ',')。 实际调用链很直白:先判断 ShowRGBOutput 输入开关且 FeatureDirection 非空,Resize 掩码数组,逐字符填充,然后 EnableRGB → RenderOutput → DisableRGB。DisableRGB 只是把内部 enabled 置 false,开销可忽略。 外汇与贵金属市场波动剧烈、杠杆风险高,这类特征映射仅用于辅助观察样本分布,不预示任何价格方向。

MQL5 / C++
class="type">void CalculateRGB(class="kw">const class="type">int ind, class="kw">const class="type">int count, class="type">class="kw">double &sum, class="type">int &col) class="kw">const;

class="kw">public:
  class="type">void EnableRGB(class="kw">const class="type">int &vector[]);
  class="type">void DisableRGB() { enabled = class="kw">false; };
  class="kw">virtual class="type">void RenderOutput() class="kw">override;
  class="kw">virtual class="type">class="kw">string GetNodeAsString(class="kw">const class="type">int node_index, class="kw">const class="type">int plane) class="kw">const class="kw">override;
  class="kw">virtual class="type">void Reset() class="kw">override;
};
class="kw">input class="type">bool ShowRGBOutput = class="kw">false;
CSOMDisplayRGB KohonenMap;
  if(ShowRGBOutput && StringLen(FeatureDirection) > class="num">0)
  {
    class="type">int rgbmask[];
    ArrayResize(rgbmask, StringLen(FeatureDirection));
    for(class="type">int i = class="num">0; i < StringLen(FeatureDirection); i++)
    {
      rgbmask[i] = -(StringGetCharacter(FeatureDirection, i) - &class="macro">#x27;,&class="macro">#x27;);
    }
    KohonenMap.EnableRGB(rgbmask);
    KohonenMap.RenderOutput();
    KohonenMap.DisableRGB();
  }
FeatureDirection=++,,-
FeatureDirection=,+,,-+

「用 Kohonen 网络给金叉货币做时序推演」

Kohonen 自组织映射本职是聚类和降维可视化,但也能直接拿来做时间序列预测。思路是把长度为 n 的 tick 向量前 n-1 个分量当输入、最后一个分量当待估目标;网络权重在训练后收敛到所属类的均值,类越紧凑,对缺失或未来值的还原就越接近教学样本的统计规律。我们选最简单的单网矢量量化方案:训练时喂全向量、算距离只用前 n-1 维、权重全量更新;预测时塞入不完整向量,取最匹配神经元第 n 个突触的权值作为输出。 为了绕开报价序列里噪音和基本面突袭,原文挑了日线周期和黄金、白银这类跨货币属性资产。Unity 指标把 EURUSD、XAUUSD 等多品种报价拆成独立“成本”变量,并加单位模约束 EUR²+USD²+XAU²=1 求解各资产相对值;默认输出的是日线增量 y_i = x_i0/x_i1 - 1。这样一组外汇加金属就能合成一个同步变化的 n 维向量,预测其中某一维的次日增量。 实操上,Unity 的 Instruments 填 "EURUSD,GBPUSD,USDCHF,USDJPY,AUDUSD,USDCAD,NZDUSD,XAUUSD"(XAUUSD 必须置尾),ShiftLastBuffer=true 会多写一列 forecast,把末资产当天增量顺移一行,形成“今日已知+明日目标”的 csv。SOM-Forecast 设 ForecastMode=true 仅用前 n-1 维算 BMU,ValidationSetPercent=10、ReframeNumber=10 可启 TrainAndReframe 逐步扩容:每维加 2 神经元,验证误升即停,防过拟合丢泛化。 静态分析 500 根 D1 的 unity500-noshift.csv 时,Kohonen 图上 GBP 蓝斑与 AUD 黄斑常年对置,说明英镑兑澳元在波动放大段倾向空方主导;XAG 与 CHF 在右上同涨、左下互斥,可作为突破双向挂单的参考。欧元、英镑、瑞郎的聚类体积最大,意味着它们日变动频率高于其它货币,美元反而弱于日元与加元。 预测侧建议别把网训太深:MetaQuotes-Demo 上 D1 虽有 2000+ 柱,但 2~3 年甚至 250 根(约 1 年)更可能抓住当下规律,更远历史可能已失效。外汇与贵金属属高风险敞口,上述关联与推演仅代表样本内概率倾向,实盘前请在 MT5 用附码复算并自验。

把随机种子和回看窗口一起调出能用的网

Kohonen 网络不是设一次参数就完事。RandomSeed 决定初始权重随机发生器,换一个种子就是一张新脸孔的网络,在其它条件完全相同下,泛化表现可能更好也可能更糟。所以网络尺寸、教学样本量这些都不是拍脑袋定死的,得靠大量试错——原文里就是从 26*26 缩到 15*15,再配合缩减教学集来逼近可用配置。 教学前必须把源数据劈成两份。用 unity500xau.csv 举例,复制出 50 个向量进 unity500xau-validation.csv 做验证,其余留着训网。若在训网同源数据上验,正确率高只是自欺,日志里看一眼就知道。 先拿 24*24、ValidationSetPercent=0、ForecastMode=true 训完,图上只是视觉确认网「学了点东西」。真正验要把训好的 .som 塞进 NetFileName,DataFileName 改指 validation 集,跑完日志显示预测精度在随机猜级别——简单输入深度随手选,显然出不了圣杯。 往输入里加上下文才有戏。指标 Unity 加了 BarLookback 参数,默认 1;填 5 就把一周内 9 项资产(8 外汇 + 黄金)的 tic 标记全卷进向量,单行塞 46 个值,算得慢、图难看。演示用 3 天回看 + 15*15 网,unity1000xau3 两文件训验下来拿到 58% 精确预测——但随机性仍在,换初始化可能掉队,实际要养多个实例挑最好的,或投票用委员会。 Unity-Forecast 指标走 CSOM 类不渲染图。载入用 NetFileName,随训则搬 CellsX/Y、EpochNumber、RandomSeed 等;删了 AbsoluteValues 和存 csv,加 SaveTrainedNetworks 存网备看。BarLimit 管起始柱与训网柱数,RetrainingBars 定重训间隔。 [CODE] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">datetime</span>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EUR;&nbsp;&nbsp;&nbsp;&nbsp; USD;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GBP;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CHF;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JPY;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AUD;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CAD;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NZD;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XAU; FORECAST <span class="number">2016.12</span>.<span class="number">20</span> <span class="number">00</span>:<span class="number">00</span>:<span class="number">00</span>; <span class="number">0.001825</span>;<span class="number">0.000447</span>;-<span class="number">0.000373</span>; <span class="number">0.000676</span>;-<span class="number">0.004644</span>; <span class="number">0.003858</span>; <span class="number">0.004793</span>; <span class="number">0.000118</span>;-<span class="number">0.004105</span>; <span class="number">0.000105</span> <span class="number">2016.12</span>.<span class="number">21</span> <span class="number">00</span>:<span class="number">00</span>:<span class="number">00</span>; <span class="number">0.000228</span>;<span class="number">0.003705</span>;-<span class="number">0.001081</span>; <span class="number">0.002079</span>; <span class="number">0.002790</span>;-<span class="number">0.002885</span>;-<span class="number">0.003052</span>;-<span class="number">0.002577</span>; <span class="number">0.000105</span>;-<span class="number">0.000854</span> <span class="number">2016.12</span>.<span class="number">22</span> <span class="number">00</span>:<span class="number">00</span>:<span class="number">00</span>; <span class="number">0.002147</span>;<span class="number">0.003368</span>;-<span class="number">0.003467</span>; <span class="number">0.003427</span>; <span class="number">0.002403</span>;-<span class="number">0.000677</span>;-<span class="number">0.002715</span>; <span class="number">0.002757</span>;-<span class="number">0.000854</span>; <span class="number">0.004919</span> <span class="number">2016.12</span>.<span class="number">23</span> <span class="number">00</span>:<span class="number">00</span>:<span class="number">00</span>; <span class="number">0.000317</span>;<span class="number">0.003624</span>;-<span class="number">0.002207</span>; <span class="number">0.000600</span>; <span class="number">0.002929</span>;-<span class="number">0.007931</span>;-<span class="number">0.003225</span>;-<span class="number">0.003350</span>; <span class="number">0.004919</span>; <span class="number">0.004579</span> 上面这段是训练/验证 csv 的切片:首列 datetime 为日线开盘时刻,EUR 到 XAU 是各品种当日 tic 标记,末列 FORECAST 是黄金方向标签。直接照这格式攒自己的 csv,就能喂进 SOM-Forecast 复现流程。 测白银时把品种集扩到 EURUSD、GBPUSD、USDCHF、USDJPY、AUDUSD、USDCAD、NZDUSD、XAUUSD、XAGUSD,用外汇+黄金簇预测银。2018.7.1–12.1 测试器里指标逐日训、每 20 天重训,准确率 60%。外汇与贵金属杠杆高、跳空频繁,这套概率优势不代表实盘能躺赢,重训阻塞指标的问题也别在实盘指标里干,交给 EA 按计划生成网更稳。 想再抬精度,往输入塞周/日序号类外部因子,或叠多个 Kohonen 混别的网络类型,都是可落手的改法。

MQL5 / C++
    <span class="keyword">class="type">class="kw">datetime</span>;      EUR;      USD;      GBP;      CHF;      JPY;      AUD;      CAD;      NZD;      XAU; FORECAST
<span class="number">class="num">2016.12</span>.<span class="number">class="num">20</span> <span class="number">class="num">00</span>:<span class="number">class="num">00</span>:<span class="number">class="num">00</span>; <span class="number">class="num">0.001825</span>;<span class="number">class="num">0.000447</span>;-<span class="number">class="num">0.000373</span>; <span class="number">class="num">0.000676</span>;-<span class="number">class="num">0.004644</span>; <span class="number">class="num">0.003858</span>; <span class="number">class="num">0.004793</span>; <span class="number">class="num">0.000118</span>;-<span class="number">class="num">0.004105</span>; <span class="number">class="num">0.000105</span>
<span class="number">class="num">2016.12</span>.<span class="number">class="num">21</span> <span class="number">class="num">00</span>:<span class="number">class="num">00</span>:<span class="number">class="num">00</span>; <span class="number">class="num">0.000228</span>;<span class="number">class="num">0.003705</span>;-<span class="number">class="num">0.001081</span>; <span class="number">class="num">0.002079</span>; <span class="number">class="num">0.002790</span>;-<span class="number">class="num">0.002885</span>;-<span class="number">class="num">0.003052</span>;-<span class="number">class="num">0.002577</span>; <span class="number">class="num">0.000105</span>;-<span class="number">class="num">0.000854</span>
<span class="number">class="num">2016.12</span>.<span class="number">class="num">22</span> <span class="number">class="num">00</span>:<span class="number">class="num">00</span>:<span class="number">class="num">00</span>; <span class="number">class="num">0.002147</span>;<span class="number">class="num">0.003368</span>;-<span class="number">class="num">0.003467</span>; <span class="number">class="num">0.003427</span>; <span class="number">class="num">0.002403</span>;-<span class="number">class="num">0.000677</span>;-<span class="number">class="num">0.002715</span>; <span class="number">class="num">0.002757</span>;-<span class="number">class="num">0.000854</span>; <span class="number">class="num">0.004919</span>
<span class="number">class="num">2016.12</span>.<span class="number">class="num">23</span> <span class="number">class="num">00</span>:<span class="number">class="num">00</span>:<span class="number">class="num">00</span>; <span class="number">class="num">0.000317</span>;<span class="number">class="num">0.003624</span>;-<span class="number">class="num">0.002207</span>; <span class="number">class="num">0.000600</span>; <span class="number">class="num">0.002929</span>;-<span class="number">class="num">0.007931</span>;-<span class="number">class="num">0.003225</span>;-<span class="number">class="num">0.003350</span>; <span class="number">class="num">0.004919</span>; <span class="number">class="num">0.004579</span>
把参数扫描交给小布盯盘
这些聚类与高原诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到,你只需在候选区间里做最终决策。

常见问题

高原水平近似平均盈利能力,长度近似系统稳健性,单点最大值容易是过拟合噪声,实盘外汇贵金属高风险下更易失效。
过多集群变小且显重学痕迹难概括;过少则训练不足吞下差异样本,具体阈值依任务与数据结构实验确定。
一般需窗口切片、归一化与拓扑初始化,本篇后续节会给出代码级说明,偏理论部分解释映射机理。
可以,AIGC模块已封装参数扫描与聚类可视化,你导入EA回测报告就能拿到候选高原区间,省去手写神经网络类。
在搜索最优EA参数与时间序列预测两节直接复用,关于类修正的完整讨论见《在算法交易中Kohonen神经网络的实际应用·基础篇》。