含 GUI 的 EA 面板开发:从零搭出可交互交易界面(基础篇)(基础篇)
🖥️

含 GUI 的 EA 面板开发:从零搭出可交互交易界面(基础篇)(基础篇)

(1/3)· 很多交易者想自动化重复操作却卡在界面开发,本文用标准指标信号 EA 演示如何低成本拼出 GUI 面板

新手友好 第 1/3 篇
不少人有现成策略却迟迟不做 EA 面板,误以为 GUI 开发必须啃标准库底层代码。结果要么手动重复切品种看信号,要么直接放弃交互功能。其实用对开发库,界面拼装比写交易逻辑还快。

「在 MT5 里给 EA 搭一个可交互面板」

想在 MT5 上做带图形界面的 EA,第一步不是写交易逻辑,而是先把面板画出来。多数新手直接堆按钮和输入框,结果坐标错位、事件漏接,最后界面比命令行还难用。 Anatoli Kazharski 在 2018 年 8 月 6 日发布的示例里,这套带 GUI 的 EA 教程累计被查看 8611 次、收到 15 条讨论,说明手动在图表上点单的需求一直真实存在。外汇与贵金属杠杆高、滑点频繁,界面响应慢半秒都可能错价成交。 核心思路是用 MQL5 的 CAppDialog 派生自己的面板类,把控件当作对象管理,而不是在 OnChartEvent 里写一堆 id==0 的硬编码判断。这样后面加按钮、加 Tab 页都只是扩类,不改主框架。

这套 GUI 到底由哪些零件构成

想在 MT5 里自己搭一套可视化面板,先得弄清底层元件清单。原文给出的目录把整套 GUI 拆成了十几个基础件:从表单、状态条、页面组,到输入栏位、按钮、带下拉的组合框、复选框、表格、标准图表和进度条,基本覆盖了手动交易与监控面板常用的交互控件。 这些元件不是孤立存在的。比如「用于控件的表单」是容器,「页面组」负责切换视图,「状态条」常挂在底部反馈运行状态,而「输入栏位 + 按钮 + 组合框」三者组合就能完成参数录入与触发。 另外目录里单列了 EasyAndFast 开发库的更新项,说明这套元件体系依赖该库迭代。交易者若要在实盘外汇或贵金属 EA 里复用,建议直接对照该库当前版本核对控件接口,避免老代码在 MT5 新 build 下编译失败。外汇与贵金属杠杆高,任何面板逻辑错误都可能放大下单风险,验证前务必在策略测试器跑通。

◍ 为什么给手工交易加一层信号面板

算法交易再热闹,仍有大量交易者坚持手动下单,但重复拉品种、切周期、盯指标这类机械活儿,人工做既费神又容易漏信号。 本文以终端自带的随机振荡指标(Stochastic)为例,演示如何写一个多品种信号 EA,并带图形界面(GUI)。你拿这套代码改一改,就能塞进任意指标,或按自己的计算逻辑触发交易决策。 这个面板顺手解决了几个手工交易的痛点:按属性筛出品种列表、不重新初始化 EA 就能切品种和周期、在界面里直接管图表属性、多品种用颜色块推送指标信号、还能操作已开仓位。 原文分两篇发,本篇只搭面板骨架,下一篇才填功能逻辑。想验证的话,开 MT5 建个 EA 把 Stochastic 信号接到界面上,先跑通多品种颜色提示就够了。

「EA 交互界面的元件分层」

做带 GUI 的 EA,核心价值是让使用者和程序直接对话,并把行情、仓位数据可视化。标准库能画控件,但用 EasyAndFast 这类开发库更省事——你只需盯逻辑,图形渲染交给底层。 先把界面拆成层级:最外层是窗口,底下挂状态栏和页面组。本例规划了两个页,「交易」页放品种过滤输入框、请求构建按钮、买卖按钮、交易量栏、信号水平输入框和品种表格;「仓位」页放持仓表与重放帧指示。 控件数量一多就容易乱,用分级表单列出来最直观:表单管总控,状态栏显概况,页面组分交易与仓位,图表属性再单独用组合框、复选框和输入框管时段、伸缩、缩进和指标开关。 主类 CProgram 里按上面清单声明各元件实例,创建代码拆到独立文件,用 MQL 程序类包含进来。下面这段是类声明的骨架,能直接看出整个 GUI 由哪些对象拼成。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 应用程序开发类                                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
class CProgram : class="kw">public CWndEvents
  {
class="kw">private:
   class=class="str">"cmt">//--- 窗口
   CWindow           m_window1;
   class=class="str">"cmt">//--- 状态条
   CStatusBar        m_status_bar;
   class=class="str">"cmt">//--- 页面
   CTabs             m_tabs1;
   class=class="str">"cmt">//--- 输入栏位
   CTextEdit         m_symb_filter;
   CTextEdit         m_lot;
   CTextEdit         m_up_level;
   CTextEdit         m_down_level;
   CTextEdit         m_chart_scale;
   class=class="str">"cmt">//--- 按钮
   CButton           m_request;
   CButton           m_chart_shift;
   CButton           m_buy;
   CButton           m_sell;
   CButton           m_close_all;
   class=class="str">"cmt">//--- 组合框
   CComboBox         m_timeframes;
   class=class="str">"cmt">//--- 复选框
   CCheckBox         m_date_scale;
   CCheckBox         m_price_scale;
   CCheckBox         m_show_indicator;
   class=class="str">"cmt">//--- 表格
   CTable            m_table_positions;
   CTable            m_table_symb;
   class=class="str">"cmt">//--- 标准图表
   CStandardChart    m_sub_chart1;
   class=class="str">"cmt">//--- 进度条
   CProgressBar      m_progress_bar;
   class=class="str">"cmt">//---
class="kw">public:
   class=class="str">"cmt">//--- 创建 GUI
   class="type">bool              CreateGUI(class="type">void);
   class=class="str">"cmt">//---
class="kw">private:
   class=class="str">"cmt">//--- 表单
   class="type">bool              CreateWindow(class="kw">const class="type">class="kw">string text);
   class=class="str">"cmt">//--- 状态条
   class="type">bool              CreateStatusBar(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap);
   class=class="str">"cmt">//--- 页面
   class="type">bool              CreateTabs1(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap);
   class=class="str">"cmt">//--- 输入栏位
   class="type">bool              CreateSymbFilter(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
   class="type">bool              CreateLot(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);

面板控件的声明接口长这样

在 MT5 自定义面板里,每一类图形元素都对应一个返回 bool 的创建函数,入参统一用 x_gap、y_gap 控制相对锚点的像素偏移,text 传标签文案。 从源码声明看,水平线类有 CreateUpLevel、CreateDownLevel 和 CreateChartScale,按钮类覆盖 CreateRequest、CreateChartShift、CreateBuy、CreateSell、CreateCloseAll,组合框只有 CreateComboBoxTF 一个时段切换器。 复选框组负责坐标显示开关:CreateDateScale、CreatePriceScale、CreateShowIndicator;表格类用 CreatePositionsTable 和 CreateSymbolsTable 把持仓与品种拉成二维网格;子图与进度条则留给 CreateSubChart1 等后续扩展。 把这些函数直接贴进 EA 的 C++ 风格面板类,编译后若返回 false,说明对应控件 ID 冲突或坐标越界,开 MT5 跑一遍就能定位是哪一行的 x_gap 超了图表右边界。

MQL5 / C++
class="type">bool CreateUpLevel(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreateDownLevel(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreateChartScale(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class=class="str">"cmt">//--- 按钮
class="type">bool CreateRequest(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreateChartShift(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreateBuy(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreateSell(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreateCloseAll(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class=class="str">"cmt">//--- 组合框
class="type">bool CreateComboBoxTF(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class=class="str">"cmt">//--- 复选框
class="type">bool CreateDateScale(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreatePriceScale(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class="type">bool CreateShowIndicator(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
class=class="str">"cmt">//--- 表格
class="type">bool CreatePositionsTable(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap);
class="type">bool CreateSymbolsTable(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap);
class=class="str">"cmt">//--- 标准图表
class="type">bool CreateSubChart1(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap);
class=class="str">"cmt">//--- 进度条

◍ 把进度条封装进可复用头文件

在 MT5 里反复手搓 GUI 控件会很拖累开发节奏,把创建逻辑收进一个独立的 mqh 头文件是更稳的做法。上面这段声明把一个进度条生成函数抽离出来,调用方只需传坐标偏移和文本就能拿到控件对象。 实际落地时,用 #include "CreateGUI.mqh" 把封装好的界面代码挂到主程序,编译后 EA 或脚本就能直接调 CreateProgressBar。外汇与贵金属品种波动大、点差跳变频繁,这类界面只做状态展示,不替代风控逻辑,实盘前务必在策略测试器里跑一遍验证坐标不溢出。 x_gap 和 y_gap 以像素为单位,文本参数决定进度条左侧说明文字;若你的图表缩放比例非 100%,建议先打印实际锚点再固化数值。

MQL5 / C++
  class="type">bool                CreateProgressBar(class="kw">const class="type">int x_gap,class="kw">const class="type">int y_gap,class="kw">const class="type">class="kw">string text);
  };
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 用于创建控件的代码                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#include "CreateGUI.mqh"
class=class="str">"cmt">//+------------------------------------------------------------------+
把面板雏形交给小布盯盘生成
这些 GUI 结构规划与小布盯盘的 AIGC 已内置,打开对应品种页即可看到类似的控件布局参考,你只需专注把信号逻辑接进去。

常见问题

标准库需要自己处理大量图形绘制与事件绑定,EasyAndFast 封装了表单、控件与页面组,开发者只需声明结构即可,更适合快速搭面板。
本文定位基础篇且新手友好,只要按小节顺序拼装控件、复制示例代码,大概率能跑出静态界面,后续再接功能。
目前小布盯盘内置的是品种页控件布局与诊断视图,不直接导出 MQL5 源码,但可作为你规划面板结构的参照减少试错。
交易品种多、控件杂时单窗口会过载,页面组把交易操作与图表属性分开,既清晰也避免重新初始化 EA 就能切品种时段。
外汇贵金属杠杆高、跳空频繁,GUI 只是交互层,信号触发后实际成交可能滑点,决策仍要人工确认,概率优势不等于稳赚。