图形界面库跨平台测试:MT4与多程序类型的底层验证(基础篇)
(1/3)·自建界面库只在EA里跑过?指标、脚本和MT4终端的隐藏坑位一次摸清
三类程序里怎么挂界面库做测试
想把自定义图形界面塞进 MT4/MT5,第一步是搞清楚它能在哪类程序里跑。作者 Anatoli Kazharski 在 2016-03-10 发布的这篇示例,累计被查看 3777 次,说明这类底层界面库需求一直有真实交易者在使用。 界面库最常见的落点是三种宿主:指标(indicator)、脚本(script)和 EA。指标里挂表单,适合把参数面板、状态显示常驻在副图;脚本里挂表单,多用于一次性任务前的人机交互配置,跑完即退;EA 里挂表单则偏向长期运行时的实时控制。 在 MetaTrader 4 中验证这套界面库时,注意 MT4 与 MT5 的窗口消息机制有差异,直接把 MT5 的库搬过去可能收不到部分鼠标事件。建议新建一个空脚本,先只画一个按钮,确认能响应点击后再逐步加控件。外汇与贵金属品种波动剧烈,界面逻辑若卡顿可能错过入场,实盘前务必在模拟盘跑通。
「从 EA 测试转向指标与脚本的跨平台验证」
上一章我们已经给表单类补上了通过控件按钮管理表单的方法,但当时所有测试都跑在 MetaTrader 5 里,而且只用了 EA 交易类型的程序。这限制了对库通用性的判断。 本篇要换一种验证思路:用指标和脚本这类不同形态的 MQL 程序来跑同一套界面库,看看控件响应是否一致。库在设计之初就按跨平台目标写,所以 MT4 也必须能编译运行。 目前第一部分的完整库文件可从系列前章末尾的清单获取,解压后目录结构需保持与压缩包内一致,否则 MT4/MT5 都可能因路径错位加载失败。外汇与贵金属交易界面开发属高风险环境,跨平台差异可能引发隐性 bug,建议先在策略测试器做最小样例验证。
◍ 让控件表单在指标子窗口里听话
把 EA 里用过的 Program.mqh 直接拷进 MQL5/Indicators 下的新目录就能跑通主窗口指标表单,但一旦把指标挂到副图子窗口,两个毛病立刻暴露:表单设置仍落在主窗口,点关闭叉号也删不掉指标。根子在事件类不知道自己身在哪一格子。 在 CWndEvents 里加一个 DetermineSubwindow() 方法:先确认是指标,再用 ChartWindowFind() 拿窗口号,失败返回 -1 并打日志;若窗口号大于 0,用 ChartIndicatorsTotal() 查该子窗口指标数,不是 1 就取最后一个短名删掉并报告。构造函数里调它一次,库就能认子窗口。 副图里的界面有三类高度行为:自由模式(子窗口高随意拉)、固定模式(高=表单高,最小化也不变)、可最小化固定模式(最小化后高=表头高)。CWindow::RollUpSubwindowMode() 就是切这三种的开关,FreeHeight 指标可略过,RollUp 传 (false, true),DownFall 传 (true, ...) 让最小化时塌成表头。 RIGHT / FULL 模式下图表变宽要重定位或改宽,原 CWindow 没这能力,补 ChangeWindowWidth() 比参数更新按钮坐标。但事件流没进 CProgram::OnEvent(),要在 CWndEvents::CheckElementsEvents() 尾端转发,并在 ChartEventChartChange() 里按真实坐标移窗重绘,RIGHT 坐标才修正。 还有个坑:图表原有别的子窗口指标时,本指标删除后窗口号会变,库按旧号算相对坐标就歪。在 ChartEventChartChange() 里调新增的 CheckSubwindowNumber(),号不对就全控件刷新。目前建议一张图只挂一个本库程序,多挂会在滚动启用/禁用上打架,留待后文解决。外汇贵金属图表挂副图指标属高风险操作,参数改动前先在模拟盘验证。
正文
<span class="preprocessor">#property </span><span class="macro">copyright</span> <span class="string">"2015, MetaQuotes Software Corp."</span> <span class="preprocessor">#property </span><span class="macro">link</span> <span class="string">"[MQL5官方文档] <span style="background-color:rgb(255, 242, 153);"><span class="preprocessor">#property </span><span class="macro">indicator_chart_window</span></span> <span style="background-color:rgb(216, 232, 194);"><span class="preprocessor">#property </span><span class="macro">indicator_buffers</span> <span class="number">0</span></span> <span style="background-color:rgb(216, 232, 194);"><span class="preprocessor">#property </span><span class="macro">indicator_plots</span> <span class="number">0</span></span> <span class="comment">//--- 包含交易面板类</span> <span class="preprocessor">#include </span><span class="string">"Program.mqh"</span> CProgram program; <span class="comment">//+------------------------------------------------------------------+</span>
| <span class="comment">// | 自定义指标初始化函数 | </span> |
|---|
<span class="comment">//+------------------------------------------------------------------+</span> <span class="keyword">int</span> <span class="functions">OnInit</span>(<span class="keyword">void</span>) { program.OnI