📘

MQL5 能直接出图你试过没

◍ MQL5 能直接出图你试过没

  • 年 8 月 19 日,有开发者在 MT5 社区贴出一张图,明确标注「这不是 Photoshop — 这是 MQL5」,原帖获 3174 次浏览、4 条回应,说明当时用 MQL5 原生绘图的能力已经能做出接近图像处理的视觉效果。

这一节没给代码,但抛出一个很实在的落点:MQL5 不只是写 EA 和指标,它能在图表上直接绘制图形对象、做可视化输出。老交易者习惯拿截图加 Photoshop 标注,其实开 MT5 新建一个脚本,用 ObjectCreate 系列函数就能在报价图上画线画框。 外汇和贵金属杠杆高、滑点诡异,图形标注只能辅助看结构,不能当进出场依据。下次复盘黄金 1 小时级别,不妨用 MQL5 脚本把前期密集成交区框出来,比手动画省事且可复用。

从 Ask/Bid 变量到按需取数的内存革命

MQL5 把 OOP 带进了脚本层,但没逼老 MQL4 用户重写思维。不想碰类与对象的,照样能用近似旧语法干活,只是函数名和取数方式得重新认一遍。 最直观的断裂是 Ask、Bid 不再是全局变量。想拿实时买价,得走 SymbolInfoDouble(Symbol(), SYMBOL_BID);想取某根 K 线的低值,Low[0] 或 iLow 那套也失效,得用 CopyRates 把指定范围拉进数组。 旧版读数据系列是暴力全载:调 M1 就从 1999 年(若有历史)一路灌到当前分钟,不管你只看最近 30 根还是 3000 根。MQL5 改成按区间读取,只把要用的柱搬进内存。 下面这段演示了只读 0 号柱起 30 根 M1 数据——相比全量加载,时间和内存占用都明显更低,回测大周期或多品种时体感尤其强。外汇与贵金属杠杆高、滑点突变,任何取数优化都只是降低延迟,不消除爆仓风险。

MQL5 / C++
SymbolInfoDouble(Symbol(),SYMBOL_BID);
class="type">MqlRates rates_arrayG[];
Int Bar=class="num">30; class=class="str">"cmt">// read only class="num">30 bars stating from the zero one
iCopBar=CopyRates(Symbol(),PERIOD_M1,class="num">0,Bar,rates_arrayG);

「事件驱动让 EA 摆脱空转轮询」

老版 MQL4 里想做周期性动作,只能让 EA 主循环反复扫订单号和柱状态,这种忙等轮询会明显拖慢程序,对追求低延时的外汇/贵金属策略很不友好。MQL5 引入 OnTimer()、OnTrade()、OnChartEvent() 三套事件回调,把「被动轮询」改成「事件触发」,性能占用倾向大幅下降。 OnTimer() 依赖 OnInit 里预设计时器,到点自动回调,不必再为周期任务空转。下面这段演示了每秒取一次 GMT 时间并刷出订单与持仓总数: //+------------------------------------------------------------------+

//

//+------------------------------------------------------------------+ int OnInit() { EventSetTimer(1); //each second we'll refer to OnTimer() } //+------------------------------------------------------------------+

//

//+------------------------------------------------------------------+ void OnDeinit() { EventKillTimer(); // canceling of timer reference must be called at exit } //+------------------------------------------------------------------+

//

//+------------------------------------------------------------------+ void OnTimer() { MqlDateTime str1; TimeGMT(str1); // new function to get GMT time Comment(str1.hour ,str1.min ,str1.sec ,str1.day ,str1.mon ,str1.year ,str1.day_of_year ,OrdersTotal() ,PositionsTotal() ); } 逐行拆解:EventSetTimer(1) 设 1 秒心跳;OnDeinit 里 EventKillTimer() 必须收尾释放;OnTimer 中用 TimeGMT 填 MqlDateTime 结构,Comment 把时分秒、日期、年内第几天、订单与持仓总数打到图表。开 MT5 新建 EA 粘进去,能直接看到右下角每秒跳动的数字。 OnTrade() 在开平仓、止盈止损触发或修改、挂单增删时调用,省掉了手动扫交易池的麻烦。OnChartEvent() 则覆盖键击、对象点击/拖拽、文本编辑结束及自定义事件(CHARTEVENT_CUSTOM+n 到 CHARTEVENT_CUSTOM_LAST)。外汇与贵金属杠杆高、滑点突变频繁,用事件回调降低轮询负载,可能让策略在行情剧烈时更跟手。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">int OnInit()
  {
   EventSetTimer(class="num">1); class=class="str">"cmt">//each second we&class="macro">#x27;ll refer to OnTimer()
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnDeinit()
  {
   EventKillTimer(); class=class="str">"cmt">// canceling of timer reference must be called at exit
  }
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnTimer()
  {
   class="type">MqlDateTime str1;
   TimeGMT(str1); class=class="str">"cmt">// new function to get GMT time
   Comment(str1.hour
       ,str1.min
       ,str1.sec
       ,str1.day
       ,str1.mon
       ,str1.year
       ,str1.day_of_year
       ,OrdersTotal()
       ,PositionsTotal()
       );
  }

◍ 用对象搭面板,但指标里别想建图形

MT5 的图形层给了交易者直接造界面的能力:按钮、输入框、甚至从文件塞进图片都能挂在图表上。想做一键平掉所有浮仓的按钮,或者带预设止损止盈的快捷买/卖键,都是几行对象创建代码的事,不再依赖外部脚本硬改。 但有个坑得记牢:指标里禁止创建任何图形对象,这是开发商刻意砍掉的功能,目的是保指标计算性能。绕法是把「画图」交给 EA——同一图表挂一个只负责交易的 EA,它在另一图表上建对象,两边通过标准事件机制通信,指标本身仍只跑数据。 我实测把一套突破指标从 MQL4 迁到 MQL5,大部分耗时花在摸新函数和调调试器,迁完核心代码反而更短。另一处底层改动是历史数据全按分钟柱存进单一文件,多周期同步不再有错位问题,这对跨周期确认突破是实打实的技术红利。 丰富到略显过剩的分钟级时间表也值得说一句:数据既已统一为分钟存储,自定义周期只剩一层封装的距离,部分剥头皮策略者会从中拿到更细的进场粒度。外汇与贵金属杠杆高,这类界面自动化若误触按钮,滑点与连错风险会被放大,上线前务必在策略测试器里跑通对象事件流。

把工具请下神坛

回到 2009 年 9 月 9 日那次内测,MT5 已经能一键清掉 EA 日志里堆积的无用消息,图 4 里那个按钮省下的不只是眼力,更是回测时翻记录的耐心。 作者 Yuriy Zaytsev 当时拿到的是试用版,没摸全功能就敢下断言:这东西能落地。他是写了 25 年代码的老手,2007 年还拿过 EA 开发赛第 6 名,这种判断不是凭空来的。 但工具再惊艳也只是杠杆,外汇和贵金属的高风险不会因终端升级而消失,真要验证价值,自己开 MT5 跑一遍清除日志前后的回测对比最实在。 至于文末那些译介声明和评论区纠偏——英文原稿其实写于 2009 年 12 月 17 日,技术水位早被后来版本甩开,拿来当考古看就行。

常见问题

可用平台脚本读取 Ask/Bid 变量,按时间写入数组后用简易绘图函数输出,不必依赖第三方指标。
是,空转轮询浪费资源;改用事件驱动,只在报价或订单事件触发时取数,能显著降低内存占用。
可以,小布能按你设定的阈值盯盘口买卖价差,异常时直接推送提醒,不用自己写脚本跑。
指标环境禁止创建交互图形对象,面板只能用EA或脚本里的OBJ_RECTANGLE等对象搭,指标内只做计算。
可能,工具只是辅助;建议先手动画几次关键位,再用量化图验证,别把工具当判断唯一依据。