连接 NeuroSolutions 神经网络(基础篇)
在 MT5 里接上 NeuroSolutions 神经网络
想把训练好的 NeuroSolutions 神经网络直接用在 MT5 实盘或回测里,核心是把它的 DLL 输出接进 Expert Advisor。官方给出的历史接入案例显示,截至 2013-12-31 该方案被浏览 5411 次、收藏 75 次,说明早期量化圈对这类混合架构需求不低。 具体做法是在 MQL5 侧用 #import 指令加载由 NeuroSolutions 生成的 DLL,再把输入特征(如收盘价、RSI、均线差)按训练时的顺序封装成 double 数组传入。外汇与贵金属杠杆高、滑点跳空频繁,神经网络预测仅代表概率倾向,实盘前务必在策略测试器用真实点差跑一遍。 下面这段是最小可用的导入骨架,注意函数名须和 DLL 导出名严格一致,否则 MT5 会报 4802 找不到函数。
class="macro">#class="kw">import "NeuroModel.dll" class="type">class="kw">double PredictNN(class="type">class="kw">double &inputs[]); class="macro">#class="kw">import class="type">class="kw">double inputs[class="num">5]; inputs[class="num">0]=Close[class="num">0]; inputs[class="num">1]=iRSI(_Symbol,_Period,class="num">14,PRICE_CLOSE,class="num">0); inputs[class="num">2]=iMA(_Symbol,_Period,class="num">20,class="num">0,MODE_SMA,PRICE_CLOSE,class="num">0)-Close[class="num">0]; inputs[class="num">3]=Volume[class="num">0]; inputs[class="num">4]=TimeCurrent()%class="num">86400/class="num">3600.0; class="type">class="kw">double out=PredictNN(inputs);
◍ 把训练好的网络塞进EA里跑
做价格行为的人迟早会碰到一个问题:在可视化工具里训好的神经网络,能不能直接交给 MT5 的 EA 在实时行情里下单?答案是可行的,前提是这个神经网络软件暴露了可供外部调用的程序接口。 NeuroSolutions 是少数带这种接口的桌面神经网络程序。它出到第 6 版了,但 6 版还没铺开,交易圈里真正流通、资料最多的是第 5 版。本文后续所有对接示例都基于第 5 版,因为这一版最稳、坑最少。 注意一点:你得装完整版 NeuroSolutions,不是试用版。完整版才带“自定义解决方案向导(Custom Solution Wizard)”,没有它,EA 端根本拿不到可调用的 DLL 或组件入口。外汇和贵金属杠杆高、滑点狠,接外部模型前先在策略测试器跑够样本,别直接上真仓。
「用周形态让神经网络替你猜日线收盘」
这次要落地的策略思路很直接,名字叫 WeekPattern。它在 D1 周期每根柱子开盘时启动一次,让神经网络去预测这一整根日线柱的收盘价,然后顺着预测方向做一笔单子并持有到当天结束。 喂给网络的特征不是裸价格,而是前 5 根柱子的 OHLC 数值。为了提升拟合稳定性,实际输入的是这些价格相对当前(第 0 根)柱开盘价的差值,而不是绝对价位本身。 这套做法的好处是特征被平移到同一基准,量纲更干净,MT5 里打开 D1 图表就能照此接数据。外汇与贵金属杠杆高、跳空频繁,日线级预测只是概率倾向,实盘前务必用策略测试器跑历史样本。
导出自带标签的周线训练集
训练前得先有合规数据。写个 MT5 脚本把报价按 NeuroSolutions 能读的 CSV 格式落盘:首行写字段名,之后每行是一次样本,由过去 5 根柱的 OHLC 作输入、当前柱 OHLC 作输出,共 24 个原始字段。 脚本要挂在具体品种和周期上跑。以 D1 的 EURUSD 为例,设 260 行大约覆盖 1 年历史;文件写在 MQL5\Files\NeuroSolutions\data.csv。代码里用 CopyRates 从偏移 1 的柱开始取 count=Export_Bars+5 根,避免用到未闭合的当前形成中柱。 价格做了相对化:以样本内第 0 根(输出柱)开盘价为 zlevel 基线,其余 Open/High/Low/Close 都减它再按品种精度 NormalizeDouble。这样网络看到的不是绝对价位,而是形态偏移量,泛化倾向更稳。 跑完得到 data.csv,前几行就是字段头加 260 组六柱相对 OHLC。外汇与贵金属波动受杠杆与跳空影响,高风险,样本外表现仅作概率参考,实盘前务必在 MT5 用不同品种重导验证。
class="macro">#class="kw">property script_show_inputs class=class="str">"cmt">//+------------------------------------------------------------------+ class="kw">input class="type">class="kw">string Export_FileName = "NeuroSolutions\\data.csv"; class=class="str">"cmt">// File for exporting(in the folder "MQL5\Files") class="kw">input class="type">int Export_Bars = class="num">260; class=class="str">"cmt">// Number of lines to be exported class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class=class="str">"cmt">// Create the file class="type">int file = FileOpen(Export_FileName, FILE_WRITE|FILE_CSV|FILE_ANSI, &class="macro">#x27;,&class="macro">#x27;); if (file != INVALID_HANDLE) { class=class="str">"cmt">// Write the heading of data class="type">class="kw">string row=""; for (class="type">int i=class="num">0; i<=class="num">5; i++) { if (StringLen(row)) row += ","; row += "Open"+i+",High"+i+",Low"+i+",Close"+i; } FileWrite(file, row); class=class="str">"cmt">// Copy all required information from the history class="type">MqlRates rates[], rate; class="type">int count = Export_Bars + class="num">5; if (CopyRates(Symbol(), Period(), class="num">1, count, rates) < count) { Print("Error! Not enough history for exporting of data."); class="kw">return; } ArraySetAsSeries(rates, true); class=class="str">"cmt">// Write data for (class="type">int bar=class="num">0; bar<Export_Bars; bar++) { row=""; class="type">class="kw">double zlevel=class="num">0; for (class="type">int i=class="num">0; i<=class="num">5; i++) { if (StringLen(row)) row += ","; rate = rates[bar+i]; if (i==class="num">0) zlevel = rate.open; class=class="str">"cmt">// level for counting of prices row += NormalizeDouble(rate.open -zlevel, Digits()) + "," + NormalizeDouble(rate.high -zlevel, Digits()) + "," + NormalizeDouble(rate.low -zlevel, Digits()) + ","