创建一个人工交易助手(基础篇)
📘

创建一个人工交易助手(基础篇)

第 1/3 篇

给手动外汇交易者搭个 MT5 面板

手动做外汇差价合约,最烦的是反复开图表、点按钮、盯多个品种。Dmitriy Gizlyk 在 2016 年 7 月 25 日发布过一个完整交易面板实例,原始帖累计 14407 次浏览、94 条讨论,说明这类工具在 MT5 社区有真实需求。 这篇实例的定位很直接:不写 EA 替你自动跑,而是从零搭一个带完整功能的交易面板,帮人工交易者少点几次鼠标、把下单和风控集中到一个界面里。外汇与贵金属杠杆高、滑点跳空频繁,面板只是提高效率,不替你判断方向,亏损风险仍在交易者自己身上。 如果你手头是 MT5 终端,可以照着这类面板思路自己写一个,先解决「一键平仓 / 部分平仓 / 快速改止损」这几个高频动作,比装一堆指标实用。

「交易面板该长什么样」

动手写面板前,先把终态想清楚:你究竟要让它在 MT5 里替你干哪些活。我的版本至少塞进这几块:买/卖按钮、按品种或账户或方向(多/空)一键清仓的按钮。 外汇与贵金属杠杆高,错单清不掉比少赚更伤,所以清仓逻辑必须能按维度切,而不是只会全平。 止损止盈要支持两种模式:手填点数后存款币种与其它参数联动改写;或给定风险参数(存款额或余额百分比)自动算量并画在图上。图表上拖线改 SL/TP,面板数值要实时回显。 输入项得落盘——重启 MT5 后不重填。否则每次开盘前复算一遍,实战里就是纯损耗。

◍ 把面板当成工具而不是装饰

设计交易面板的第一页就该想清楚:它最终要落在 MT5 独立的子窗口里,所有控件和指标都塞进这个固定区域,而不是散在图表上。 可行性优先于好看。面板必须包含下单、撤单、看账户这些核心信息,文字和按钮密度以一眼能扫完为上限,多余的装饰元件只会拖慢点击决策。 我自己的版本就是把必需软件全收进一个页面里绘制,不堆视觉元素——它本质是交易者的操作台,不是屏幕壁纸。外汇和贵金属波动快,面板响应慢半秒都可能错过价位,这类品种高风险,界面冗余等于主动加杠杆。

用 CAppDialog 派生出面板骨架

想在 MT5 里快速搭一个可交互的交易面板,不必从零写窗口管理逻辑。MQL5 标准库里的 CAppDialog 已经封装了对话框基类,直接继承它就能省掉大量底层代码。 我们建一个 CTradePanel 类,public 继承 CAppDialog,只留构造和析构的空实现。再在全局声明一个 TradePanel 实例,EA 加载时就有了可操作的窗口对象。 OnInit 里调用 TradePanel.Create(),传入 ChartID()、名称 "Trade Panel",以及左上角坐标 (20,20) 和尺寸 320×420 像素。若创建失败返回 INIT_FAILED,成功则 Run() 启动消息循环,返回 INIT_SUCCEEDED。 别把正态当圣经:坐标和尺寸是写死的 20/20/320/420,实盘前最好按自己显示器分辨率调,否则面板可能挡住 K 线。外汇与贵金属杠杆高,任何 EA 面板都只辅助下单,不替你判断方向。

MQL5 / C++
class="macro">#include <Controls\Dialog.mqh>
class CTradePanel : class="kw">public CAppDialog
  {
class="kw">public:
                     CTradePanel(class="type">void){};
                    ~CTradePanel(class="type">void){};
  };
CTradePanel TradePanel;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| EA 初始化函数                                                    |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
class=class="str">"cmt">//---
   class=class="str">"cmt">// 创建交易面板
   if(!TradePanel.Create(ChartID(),"Trade Panel",class="num">0,class="num">20,class="num">20,class="num">320,class="num">420))
     {
      class="kw">return (INIT_FAILED);
     }
   class=class="str">"cmt">// 运行交易面板
   TradePanel.Run();
class=class="str">"cmt">//---
   class="kw">return(INIT_SUCCEEDED);
  }

「面板控件对象的声明与私有布局」

在 MT5 里搭交易面板,第一步是把界面上每一个可见元件都映射成一个类对象。标准库已经给了 CLabel、CEdit、CButton、CBmpButton 这些现成控件类,直接拿来声明就行,不用自己重写底层绘图。 注意 Edit.mqh 和 BmpButton.mqh 不用手动 include,它们会在 Dialog.mqh 内部被间接引入,多写反而容易重复定义报错。 变量声明要放在 CTradePanel 类的 private 段,外部只允许调用 public 里的 Creat() 来管理全部元件。下面这段就是声明区的骨架,ASK/BID 挂买卖价,Balance_label 与 Balance_value 分开存标签和数值,一共列了 19 个 CLabel 成员覆盖价格、余额、净值、风险、手数等面板字段。 打开 MT5 的 MetaEditor,新建一个继承 CAppDialog 的 CTradePanel 类,把这段贴进 private 区,编译若提示找不到 CLabel 再检查 Dialog.mqh 路径是否包含在编译头里。

MQL5 / C++
class="macro">#include <Controls\Dialog.mqh>
class="macro">#include <Controls\Label.mqh>
class="macro">#include <Controls\Button.mqh>
class CTradePanel : class="kw">public CAppDialog
  {
class="kw">private:
   CLabel            ASK, BID;                                      class=class="str">"cmt">// 显示买入和卖出价格
   CLabel            Balance_label;                                 class=class="str">"cmt">// 显示 "账户余额" 标签
   CLabel            Balance_value;                                 class=class="str">"cmt">// 显示账户余额
   CLabel            Equity_label;                                  class=class="str">"cmt">// 显示 "账户净值" 标签
   CLabel            Equity_value;                                  class=class="str">"cmt">// 显示账户净值
   CLabel            PIPs;                                          class=class="str">"cmt">// 显示 "点数" 标签
   CLabel            Currency;                                      class=class="str">"cmt">// 显示账户币别
   CLabel            ShowLevels;                                    class=class="str">"cmt">// 显示"显示"标签
   CLabel            StopLoss;                                      class=class="str">"cmt">// 显示 "止损" 标签
   CLabel            TakeProfit;                                    class=class="str">"cmt">// 显示"获利"标签
   CLabel            Risk;                                          class=class="str">"cmt">// 显示"风险"标签
   CLabel            Equity;                                        class=class="str">"cmt">// 显示 "净值百分比"标签
   CLabel            Currency2;                                     class=class="str">"cmt">// 显示账户币别
   CLabel            Orders;                                        class=class="str">"cmt">// 显示 "开启的订单" 标签
   CLabel            Buy_Lots_label;                                class=class="str">"cmt">// 显示"买入手数"标签
   CLabel            Buy_Lots_value;                                class=class="str">"cmt">// 显示买入手数值 
   CLabel            Sell_Lots_label;                               class=class="str">"cmt">// 显示 "卖出手数" 标签
   CLabel            Sell_Lots_value;                               class=class="str">"cmt">// 显示卖出手数数值 
   CLabel            Buy_profit_label;                              class=class="str">"cmt">// 显示 "买入利润" 标签

◍ 面板控件声明与生命周期钩子

上面这段声明集中列出了自定义交易面板用到的所有界面对象,从标签、编辑框到位图按钮一应俱全。CLabel 负责展示买卖盈亏数值,CEdit 承接手数、止损止盈点数与金额、风险百分比等可输入或回显字段,CBmpButton 则用于切换止损/止盈的计量方式(点数或资金)以及增减手数,CButton 直接挂上 BUY/SELL 与各类平仓按钮。 从变量命名能看出面板的逻辑:StopLoss_pips_b 与 StopLoss_money_b 成对出现,意味着止损既能按点数算也能按固定资金算,TakeProfit 与 Risk 同理。这种双模切换在 MT5 实盘里很实用,尤其贵金属跳点大时,用金额约束风险比死盯点数更直观。 类里只留了空构造与析构:CTradePanel(void){} 和 ~CTradePanel(void){},说明资源由控件自身管理,真正的创建逻辑在注释 //--- 创建函数 之后补。你开 MT5 新建面板类时,照这个声明清单抄一遍,编译就能看到控件骨架。

MQL5 / C++
  CLabel           Buy_profit_value;             class=class="str">"cmt">// 显示买入利润数值 
  CLabel           Sell_profit_label;             class=class="str">"cmt">// 显示 "卖出利润" 数值
  CLabel           Sell_profit_value;             class=class="str">"cmt">// 显示卖出利润数值 
  CEdit            Lots;                          class=class="str">"cmt">// 显示下一个订单的交易量
  CEdit            StopLoss_pips;                 class=class="str">"cmt">// 显示止损点数
  CEdit            StopLoss_money;                class=class="str">"cmt">// 显示止损资金数
  CEdit            TakeProfit_pips;               class=class="str">"cmt">// 显示获利点数
  CEdit            TakeProfit_money;              class=class="str">"cmt">// 显示获利资金数
  CEdit            Risk_percent;                  class=class="str">"cmt">// 显示风险占净值百分比
  CEdit            Risk_money;                    class=class="str">"cmt">// 显示风险资金数
  CBmpButton       StopLoss_line;                 class=class="str">"cmt">// 选中以显示止损线
  CBmpButton       TakeProfit_line;               class=class="str">"cmt">// 选中以显示获利线
  CBmpButton       StopLoss_pips_b;               class=class="str">"cmt">// 选择以点数止损
  CBmpButton       StopLoss_money_b;              class=class="str">"cmt">// 选择以资金数止损
  CBmpButton       TakeProfit_pips_b;             class=class="str">"cmt">// 选择以点数获利
  CBmpButton       TakeProfit_money_b;            class=class="str">"cmt">// 选择以资金数获利
  CBmpButton       Risk_percent_b;               class=class="str">"cmt">// 选择以净值百分比为风险参数
  CBmpButton       Risk_money_b;                 class=class="str">"cmt">// 选择以账户资金数为风险参数
  CBmpButton       Increase,Decrease;             class=class="str">"cmt">// 增加和减小按钮
  CButton          SELL,BUY;                      class=class="str">"cmt">// 卖出和买入按钮
  CButton          CloseSell,CloseBuy,CloseAll;   class=class="str">"cmt">// 关闭按钮

class="kw">public:
                CTradePanel(class="type">void){};
               ~CTradePanel(class="type">void){};
class=class="str">"cmt">//--- 创建函数

常见问题

可用 CAppDialog 派生出交易面板,把买入/卖出/止损按钮直接铺在图表上,点一下就发单,比手动填终端快得多。
不是。面板是工具不是装饰,只放你每天真用的控件,多余的反而挡价格、拖慢反应。
小布会扫描你关注的外汇贵金属品种,把波动率突增或流动性变薄的情况直接推到对应页面,你再决定要不要开面板手动介入。
在类私有区用指针声明控件,并在 OnDestroy 里依次 delete 并置空,生命周期和面板绑定就不会漏。
多半是生命周期钩子没接全,Create 里忘了初始化子控件或 Destroy 没释放,按私有布局逐项核对声明与释放即可。