利用 MQL5 向导和 Hlaiman EA 生成器创建神经网络 EA·综合运用
(3/3)·从向导配置到生成器集成,零理论负担把神经网络EA跑起来
「正文」
<span class="string">" sym := exp.ObjectOfName('"</span>+hnn_sym+hnn_per+<span class="string">"');\n\r"</span> <span class="comment">// Line #5</span> <span class="string">" if (sym <> nil) then"</span> <span class="string">" begin"</span> <span class="string">" lst := TStringList.Create;"</span> <span class="string">" if (lst <> nil) then"</span> <span class="string">" begin"</span> <span class="string">" lst.Text := cons;"</span> <span class="string">" if (lst.Count >= (sym.TeachInput + sym.TeachOutput)) then"</span> <span class="string">" begin"</span> <span class="string">" out := StrToFloat(lst[0]);"</span> &
◍ HNN 训练指令的管道投递与回读
这段代码把「教神经网络」的动作翻译成一段外部脚本字符串,写进文件句柄 m_hnn,再靠轮询文件大小确认对方进程已接收。FileWriteString 写完立刻 FileFlush,避免缓冲区滞留导致 siz 一直为 0。 轮询逻辑里 siz<=0 且处于回测环境(MQL5_TESTER 为真)或 num<WAIT_TIMES 时,循环 Sleep(SLEEP_TIM) 并重新取 FileSize;若 WAIT_TIMES 设得过小,在慢盘上可能漏读。 TeachHNN 拼出的 source 脚本通过 mt45.dll 打开终端对象,定位到具体品种与周期(hnn_sym+hnn_per)的 exp 实例,先把 Teached 置 false 再置 true,强迫重新训练,最后返回 sym.Count 作为样本数。 回读时 FileReadString 只取 siz/2 长度,再用 StringToInteger 转成 res;若 res>0 则函数返回 true,代表训练触发成功。外汇与贵金属品种用这套机制时波动跳空多,重训频率过高可能拖累 EA 实时性。
" end; end.";
FileWriteString(m_hnn,source,StringLen);
FileFlush(m_hnn);
while(siz<=class="num">0 && (MQL5InfoInteger(MQL5_TESTER) || num<WAIT_TIMES))
{
Sleep(SLEEP_TIM);
siz=FileSize(m_hnn);
num++;
}
if(siz>class="num">0)
{
result=FileReadString(m_hnn,class="type">int(siz/class="num">2));
res=StringToInteger(result);
}
}
class="kw">return(res>class="num">0);
}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| TeachHNN |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">bool CSignalHNN::TeachHNN(class="type">void)
{
class="type">int num=class="num">0;
class="type">long res=class="num">0;
class="type">ulong siz=class="num">0;
class="type">class="kw">string result,source;
if(m_hnn!=class="num">0 || m_hnn!=INVALID_HANDLE)
{
TeachHNN; Interface const WAIT_TIM = class="num">100; WAIT_CNT = class="num">100;"
" var i: integer; libr, term, exp, sym: TObject;"
" Implementation function main: integer;\n\r" class=class="str">"cmt">// Line #class="num">1
" begin"
" Result := class="num">0;"
" libr := Open(&class="macro">#x27;mt45.dll&class="macro">#x27;);\n\r" class=class="str">"cmt">// Line #class="num">2
" if (libr <> nil) then"
" begin"
" term := Open(&class="macro">#x27;"+hnn_path+"&class="macro">#x27;);\n\r" class=class="str">"cmt">// Line #class="num">3
" if (term <> nil) then"
" begin"
" exp := term.ObjectOfName(&class="macro">#x27;"+hnn_nam+"&class="macro">#x27;);\n\r" class=class="str">"cmt">// Line #class="num">4
" if (exp <> nil) then"
" begin"
" sym := exp.ObjectOfName(&class="macro">#x27;"+hnn_sym+hnn_per+"&class="macro">#x27;);\n\r" class=class="str">"cmt">// Line #class="num">5
" if (sym <> nil) then"
" begin"
" if (sym.Teached) then sym.Teached := false;\n\r" class=class="str">"cmt">// Line #class="num">6
" sym.Teached := true;\n\r" class=class="str">"cmt">// Line #class="num">7
" Result := sym.Count;\n\r" class=class="str">"cmt">// ret input Line #class="num">8
" end;"
" end;"信号文件读写与方向判定
这段逻辑把外部 HNN 模型的输出通过文件桥接回 MT5:先向句柄 m_hnn 写入收尾指令串,再强制刷盘,避免缓冲区延迟导致读不到结果。 随后用 while(siz<=0) 轮询文件大小,每次 Sleep(SLEEP_TIM) 后再取 FileSize,num 累加计数;这种阻塞式等待在 EA 回测或实盘里都可能拖慢 tick 处理,外汇与贵金属品种波动快,高风险下要警惕卡顿造成的滑点。 文件有内容后,FileReadString 只读取 siz/2 长度,再用 StringToInteger 转成整型 res,函数最终返回 res>0 的布尔值,作为多空倾向的粗筛条件。 Direction 方法里先判 m_hnn 句柄有效性,无效直接返 EMPTY_VALUE;新柱出现才重算 CalculateHNN()*100 并缓存到 hnn_signal,否则沿用旧值——这意味着信号刷新粒度被 Bars 计数绑定,调 hnn_period 就能改变触发频率。
" end;" " end;" " end; end."; FileWriteString(m_hnn,source,StringLen); FileFlush(m_hnn); while(siz<=class="num">0) {class=class="str">"cmt">// && (MQL5InfoInteger(MQL5_TESTER) || num < WAIT_TIMES)) { Sleep(SLEEP_TIM); siz=FileSize(m_hnn); num++; } if(siz>class="num">0) { result=FileReadString(m_hnn,class="type">int(siz/class="num">2)); res=StringToInteger(result); } } class="kw">return(res>class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Check conditions for trading signals. | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double CSignalHNN::Direction(class="type">void) { if( m_hnn == class="num">0 || m_hnn == INVALID_HANDLE) class="kw">return(EMPTY_VALUE); class=class="str">"cmt">//--- check new bar condition class="type">int cur_bar = Bars(hnn_sym, hnn_period); if (hnn_bar != cur_bar) { class=class="str">"cmt">//--- condition OK hnn_signal = CalculateHNN() * class="num">100; hnn_bar = cur_bar; } class="kw">return(hnn_signal); }
「别急着下结论」
Hlaiman EA 生成器把 CSignalHNN 类塞进 MQL5 向导,等于在信号层开了个神经网络口子:SampleHNN.mq5 仅 6.35 KB,TeachHNN.mq5 训练脚本 9.67 KB,SignalHNN.mqh 信号模块 23.88 KB,三者放对路径就能直接出 EA。多信号模块并接后,跨货币、复合指标加时间过滤的神经网络 EA 在 MT5 里是可拼装的,不是ppt概念。 脚本解释跑在 EX5 之外这点确实拖计算效率,但插件和终端不同步、走命名网络管道,把终端丢到另一台机器跑,大网络训练压力能卸掉,隔离也顺带提升了安全性。外汇与贵金属自动交易杠杆高、滑点跳空频繁,这类方案只降低拼装成本,不替你扛回撤。 真要继续往前走,把 EA 运行代码和训练脚本揉进同一个 CSignalHNN 上下文,盘中自学那层逻辑目前最省事的就是这么干。材料已经够开一篇新坑,留给你在 MT5 里先跑通附件再说。