MQL5三种打印模式实战教学
用Print/Comment/Alert调试交易品种属性
为什么初学者要先学打印调试
很多交易者在刚接触MQL5时,把它当成第一门编程语言来学,往往会觉得难以入门。实际上,只要从简单的脚本开始,逐步累积经验,几个月就能写出较复杂的程序。学习早期最大的障碍不是语法,而是程序不按预期运行却不知道问题出在哪里。此时,把关键变量的值打印出来观察,是最直接有效的排查手段。本文作为MQL5 Cookbook系列第一篇,专门用最基础的脚本来演示三种打印模式,目的是让新手建立“看得到内部状态”的调试习惯,而不是盲目猜测。
在MQL5开发中,程序没有反应或计算结果异常,通常是因为变量赋值错误、函数参数不对或逻辑分支没走通。通过打印中间值,你可以确认每一步是否如设想般执行。相比高级的断点调试,打印方式更直观、对终端环境要求低,非常适合刚安装好MetaTrader 5和MetaQuotes语言编辑器5的新手。
MQL5脚本与开发环境准备
我们从脚本(Script)开始,因为它最简单:被拖到图表上后执行一次OnStart函数就退出,不会像EA那样长期驻留,非常适合做实验。先安装MetaTrader 5终端,启动后按F4打开MetaQuotes语言编辑器5(简称MQE5)。两者可用工具栏按钮或快捷键切换。在MQE5中按Ctrl+N打开MQL5向导,选择“脚本”类型,输入文件名(默认存于MQL5/Scripts/下,你可自建子文件夹分类),如需外部参数就顺手添加,最后点完成,会生成带模板的mq5文件。
生成的模板顶部有#property版权、链接、版本等属性。以双斜线//开头的是注释,不影响执行,但好的注释能让你隔数月仍看懂逻辑。本文还会增加一个#property script_show_inputs,作用是让脚本运行前弹出参数窗口,方便我们选择打印模式。
#property copyright "Copyright 2012, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" #property script_show_inputs
定义打印模式枚举与输入参数
为了在下拉列表里选模式,先定义枚举类型ENUM_PRINT_MODE,包含PRINT、COMMENT、ALERT三个值。然后用input修饰符声明外部参数printMode,类型就是这个枚举,默认PRINT。input变量会出现在脚本参数窗口,用户可在运行前调整,这比改代码再编译方便得多。
enum ENUM_PRINT_MODE
{
PRINT = 0,
COMMENT = 1,
ALERT = 2
};
input ENUM_PRINT_MODE printMode=PRINT; // 打印模式
把上述枚举和input参数放在文件开头(#property之下、函数之前),编译后右击脚本运行,就会看到图3那样的下拉框。这是MQL5人机交互最基础的入口,后续文章里的EA面板也依赖类似机制。
获取交易品种属性并封装函数
我们创建一个独立函数PrintSymbolProperties(),在OnStart里调用它。函数返回类型用void,因为只做输出不返回数据。内部先声明变量:symb_symbol存品种名,symb_digits存小数位,symb_spread存点差,symb_stoplevel存止损级别,symb_ask和symb_bid分别存买卖价。类型要和数据匹配,字符串用string,整数用int,价格用double。
void PrintSymbolProperties()
{
string symb_symbol = "";
int symb_digits = 0;
int symb_spread = 0;
int symb_stoplevel = 0;
double symb_ask = 0.0;
double symb_bid = 0.0;
赋值用SymbolInfoInteger和SymbolInfoDouble。_Symbol是当前图表品种预定义宏,SYMBOL_DIGITS等是属性枚举。注意SymbolInfoInteger返回的是long,我们强转int;SymbolInfoDouble直接拿double。这些函数在MQL5参考的“交易品种属性”表格里都能查到,建议收藏。
symb_symbol =Symbol(); symb_digits =(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS); symb_spread =(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD); symb_stoplevel =(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL); symb_ask =SymbolInfoDouble(_Symbol,SYMBOL_ASK); symb_bid =SymbolInfoDouble(_Symbol,SYMBOL_BID);
模式一:Print输出到日志
当printMode==PRINT,用Print()把信息打到“工具箱-专家”标签页。Print可接多个逗号分隔参数,自动拼接。适合需要留存记录、事后翻看变量历史的情况。它不打扰图表,也无弹窗,脚本静默结束。缺点是不能实时贴在图上,要切到日志 tab 看。
if(printMode==PRINT)
{
Print("交易品种: ",symb_symbol,"\n",
"小数位数: ",symb_digits,"\n",
"点差: ",symb_spread,"\n",
"止损级别: ",symb_stoplevel,"\n",
"买价: ",symb_ask,"\n",
"卖价: ",symb_bid
);
}
模式二:Comment显示在图表
COMMENT模式调用Comment(),文字直接绘在图表左上角,写策略时看实时数值很方便。本文还用MessageBox弹个确认框,选Yes就Comment("")清掉文字。注意Comment是覆盖式更新,不手动清会一直留着。和Print不同,它不写日志,只存在于图表会话。
if(printMode==COMMENT)
{
int mb_res=-1;
Comment("交易品种: ",symb_symbol,"\n",
"小数位数: ",symb_digits,"\n",
"点差: ",symb_spread,"\n",
"止损级别: ",symb_stoplevel,"\n",
"买价: ",symb_ask,"\n",
"卖价: ",symb_bid
);
mb_res=MessageBox("您想要删除图表中的注释吗?",NULL,MB_YESNO|MB_ICONQUESTION);
if(mb_res==IDYES) { Comment(""); }
return;
}
模式三:Alert弹窗加声音
ALERT模式用Alert(),除在日志留记录外,还弹提醒窗并发出系统声音。字符串拼接要用IntegerToString、DoubleToString转换,不能直接和字符串相加整数。适合重要事件强提醒,但频繁调用会烦人且阻塞脚本,只适合偶尔检查。
if(printMode==ALERT)
{
Alert("交易品种: "+symb_symbol+"\n",
"小数位数: "+IntegerToString(symb_digits)+"\n",
"点差: "+IntegerToString(symb_spread)+"\n",
"止损级别: "+IntegerToString(symb_stoplevel)+"\n",
"买价: "+DoubleToString(symb_ask,_Digits)+"\n",
"卖价: "+DoubleToString(symb_bid,_Digits)
);
}
完整脚本结构与运行效果
把以上拼起来就是完整脚本:属性、枚举、input、OnStart调函数、函数内赋值并按模式分支输出。编译通过后,从导航器拖到图表,选模式运行。PRINT看专家页;COMMENT看图表左上再关弹窗;ALERT看弹窗与听声。三种方式覆盖静默日志、图形叠加、强提醒场景,新手可据习惯选。
#property script_show_inputs
enum ENUM_PRINT_MODE { PRINT=0, COMMENT=1, ALERT=2 };
input ENUM_PRINT_MODE printMode=PRINT;
void OnStart() { PrintSymbolProperties(); }
void PrintSymbolProperties()
{
string symb_symbol=Symbol();
int symb_digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
int symb_spread=(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
int symb_stoplevel=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
double symb_ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double symb_bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
if(printMode==PRINT) Print(...);
if(printMode==COMMENT) { Comment(...); MessageBox(...); }
if(printMode==ALERT) Alert(...);
}
与其他输出方案的对比及进阶
除了这三种,MQL5还能用FileWrite写txt或html报告,但涉及文件句柄和目录权限,对新手略复杂。Print适合日志追溯,Comment适合图形调试,Alert适合异常告警。实盘EA中常组合用:平时Comment显状态,出错Alert,详细Print留痕。本文方法虽简单,却是后续学指标、EA面板、仓位属性的基石。建议把脚本改造成打印账户余额、tick时间等,练熟再往下读Cookbook系列。