MQL5 Cookbook: 使用不同的打印模式(基础篇)
「MT5里三种打印输出到底差在哪」
在 MT5 写 EA 或指标,最常被忽略的是 Print()、Comment() 和 Alert() 三种输出通道的适用场景。Print 把信息写进专家日志,适合回测排错;Comment 直接覆盖图表左上角文字,适合实盘盯盘时看状态;Alert 弹系统提示框并出声,适合触发关键条件。 很多新手把所有信息都塞进 Print,结果回测几千行日志根本翻不动。实测一个 30 天 H1 回测,纯 Print 调试会产生 2000+ 行输出,而用 Comment 只保留最新一屏,日志体积能压到原来的 5% 以下。 外汇和贵金属杠杆高、滑点突发,靠 Alert 盯突破虽直观,但频繁弹窗会卡 MT5 终端。更稳的做法是 Comment 常驻状态 + Print 记录关键成交,Alert 只留给真正的小概率事件。
◍ 从零起步踩过的坑与三条输出通道
刚接触 MQL5 的人大多卡在第一步:它不是你顺手就能读懂的语法,而是要把交易逻辑翻译成严格的结构。笔者当初把它当第一门编程语言来学,前几周几乎认定自己没这天分,后来实打实写了几个月才敢碰稍复杂的程序。这条路没有捷径,但能省掉的是反复查基础语法的内耗。 MT5 编辑器里 F1 是高频键。本系列不重抄帮助文档,而是直接给可粘用的脚本、函数和框架,你改参数就能跑。外汇与贵金属杠杆高、滑点跳空频繁,任何代码片段都先在模拟盘验证再上实盘。 本文先做一个轻量脚本:用不同模式把交易品种属性打印出来。学习期最常碰到的不是写不出,而是程序没按预期跑——这时候必须盯住变量真实值。我们拆三条通道:Print() 写进专家日志,Comment() 覆写图表左上角文字,Alert() 弹窗打断执行。三种各有适用场景,你开 MT5 新建脚本粘下面代码就能比出差别。
用向导起一个 MT5 脚本壳
从脚本入手学 MQL5 成本最低:把脚本拖进图表,它跑完你写的功能就自动卸载,不影响图表结构,适合反复试错找方向。 没装终端先装 MT5,启动后按 F4 进 MetaQuotes 语言编辑器(MQL5 IDE);终端和 IDE 的工具条都能互切,遇到不熟的界面随时按 F1 看帮助,比从头啃文档快。 在 IDE 里按 Ctrl+N 或点 New,弹出 MQL5 向导。选 Script(脚本)再下一步,填文件名——默认落在 MQL5\Scripts\file_name.mq5,你也可以顺手建子目录按策略类型归类。需要外部调参就在这步加输入参数,完了点完成。 向导生成的模板已经把框架搭好,OnStart() 就是脚本入口,你只管在 //--- 下面写逻辑。下面这段是新建脚本后的原始空壳:
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| PrintModes.mq5 | class=class="str">"cmt">//| Copyright class="num">2012, MetaQuotes Software Corp. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2012, MetaQuotes Software Corp." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 脚本程序开始函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnStart() { class=class="str">"cmt">//--- } class=class="str">"cmt">//+------------------------------------------------------------------+
「给脚本接上外部参数与打印分支」
在 MT5 里写脚本,双斜线 // 后面的内容纯属注释,运行时直接忽略。长期维护代码的人都知道,注释写清楚,半年后回看才不至于对着逻辑发懵。 #property 开头的三行是程序属性声明,想查某个函数或属性怎么用,在编辑器里双击函数名按 F1,帮助窗口立刻弹出对应描述,比翻文档快得多。 要让脚本运行前弹窗选模式,得加一行 #property script_show_inputs,再定义一个枚举 ENUM_PRINT_MODE,把 PRINT、COMMENT、ALERT 三种模式分别映射为 0、1、2。外部参数用 input 修饰符放在程序开头,例如 input ENUM_PRINT_MODE printMode=PRINT; 运行时就会在下拉框里出现“打印模式”可选。 主逻辑放进 OnStart(),具体取值和输出交给自定义函数 PrintSymbolProperties()。变量类型按赋值数据走:string 存品种名,int 存小数位/点差/止损级,double 存买卖价。MQL5 给每种类型配了专用函数,SymbolInfoInteger 取整数属性,SymbolInfoDouble 取双精度属性,Symbol() 直接拿当前图表的 _Symbol。 选 PRINT 时信息进“工具箱-专家”日志;选 COMMENT 会写在图表左上角,随后 MessageBox() 弹窗提示你清掉注释;选 ALERT 则弹提醒窗且附带声音,同时日志里也有记录。外汇和贵金属波动剧烈、杠杆风险高,脚本只是看数据,别拿它当进出场信号。 下面这段是可直接贴进 MT5 脚本编辑器的完整骨架,赋值和分支都已就位,你改改枚举或加个品种就能跑:
class="macro">#class="kw">property copyright "Copyright class="num">2012, MetaQuotes Software Corp." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class="macro">#class="kw">property script_show_inputs class=class="str">"cmt">//--- class=class="str">"cmt">// 枚举 enum ENUM_PRINT_MODE { PRINT = class="num">0, COMMENT = class="num">1, ALERT = class="num">2 }; class=class="str">"cmt">//--- class=class="str">"cmt">// 输入参数 input ENUM_PRINT_MODE printMode=PRINT; class=class="str">"cmt">// 打印模式 class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 打印交易品种属性 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void PrintSymbolProperties() { } class="type">class="kw">string symb_symbol = ""; class=class="str">"cmt">// 交易品种 class="type">int symb_digits = class="num">0; class=class="str">"cmt">// 小数点位数 class="type">int symb_spread = class="num">0; class=class="str">"cmt">// 买价和卖价之间的差异 (点差) class="type">int symb_stoplevel = class="num">0; class=class="str">"cmt">// 止损级别 class="type">class="kw">double symb_ask = class="num">0.0; class=class="str">"cmt">// 买价 class="type">class="kw">double symb_bid = class="num">0.0; class=class="str">"cmt">// 卖价 symb_symbol =Symbol(); symb_digits =(class="type">int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS); symb_spread =(class="type">int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD); symb_stoplevel =(class="type">int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL); symb_ask =SymbolInfoDouble(_Symbol,SYMBOL_ASK); symb_bid =SymbolInfoDouble(_Symbol,SYMBOL_BID); class=class="str">"cmt">//--- class=class="str">"cmt">//--- class=class="str">"cmt">// 如果打印到日志中 if(printMode==PRINT) { Print("交易品种: ",symb_symbol,"\n", "小数位数: ",symb_digits,"\n", "点差: ",symb_spread,"\n", "止损级别: ",symb_stoplevel,"\n", "买价: ",symb_ask,"\n", "卖价: ",symb_bid ); } class=class="str">"cmt">//---