精通日志记录(第一部分):MQL5中的基础概念与入门步骤·综合运用
「给日志类加上三级告警接口」
在 MT5 的自定义日志工具里,光有普通记录还不够。把告警、错误、致命三类消息拆成独立方法,能让 EA 在跑外汇或贵金属策略时,按严重程度分流,方便后续用小布盯盘做 AIGC 异常归因。 下面这段是 CLogify 类的三个公开方法,入参一致:message 是正文,origin 填调用模块名,metadata 可挂附加 JSON。三者都调用内部 Append,区别仅在第二个枚举参数 LOG_LEVEL_ALERT / ERROR / FATAL。 Alert 用于可恢复提醒,比如点差突然扩大到 15 点(EURUSD 常规 1~3 点),概率上可能影响入场但不致命。Error 用于订单发送失败等需干预的事件。Fatal 留给内存越界、指标句柄失效等会让 EA 停摆的情况。外汇和贵金属杠杆高,这类分级日志能降低漏看风险事件的概率。 逐行看:每个方法签名都带默认空串参数,降低调用方负担;函数体只有一行 return,把 TimeCurrent() 拿到的服务器时间传给 Append,保证每条日志带毫秒级时间戳,开 MT5 后直接抄进你的 include 文件就能编译验证。
class="type">bool CLogify::Alert(class="type">class="kw">string message,class="type">class="kw">string origin="",class="type">class="kw">string metadata="") { class="kw">return(this.Append(TimeCurrent(),LOG_LEVEL_ALERT,message,origin,metadata)); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Error level message | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool CLogify::Error(class="type">class="kw">string message,class="type">class="kw">string origin="",class="type">class="kw">string metadata="") { class="kw">return(this.Append(TimeCurrent(),LOG_LEVEL_ERROR,message,origin,metadata)); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Fatal level message | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool CLogify::Fatal(class="type">class="kw">string message,class="type">class="kw">string origin="",class="type">class="kw">string metadata="") { class="kw">return(this.Append(TimeCurrent(),LOG_LEVEL_FATAL,message,origin,metadata)); } class=class="str">"cmt">//+------------------------------------------------------------------+
给 Logify 搭一个可跑的测试 EA
要验证 Logify 日志库是否按预期工作,最直接的方式是在 MT5 的 Experts 目录下新建一个 Logify 文件夹,把所有测试文件归置在一起,再建 LogifyTest.mq5 写个最小可用框架。 框架里先 #include <Logify/Logify.mqh> 并实例化 CLogify logify;,随后在 OnInit 中调用 Debug / Infor / Alert 三个级别,分别带模块名和附加参数,用来覆盖指标、订单、风控三类常见日志场景。 跑起来后终端预期会按级别分行打印:Debug 行显示 RSI 值 72.56(周期 14),Infor 行显示 EURUSD 0.1 手买单已发,Alert 行显示订单 12345678 止损平保。数字若与终端不一致,优先查 include 路径而非库本身。 外汇与贵金属行情波动剧烈、杠杆风险高,日志仅作排查辅助,不构成任何方向判断。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| LogifyTest.mq5 | class=class="str">"cmt">//| Copyright class="num">2023, MetaQuotes Ltd. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2023, MetaQuotes Ltd." 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">//| Expert initialization function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- class=class="str">"cmt">//--- class="kw">return(INIT_SUCCEEDED); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert deinitialization function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnDeinit(class="kw">const class="type">int reason) { class=class="str">"cmt">//--- } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert tick function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void OnTick() { class=class="str">"cmt">//--- } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#include <Logify/Logify.mqh> CLogify logify; class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Expert initialization function | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnInit() { class=class="str">"cmt">//--- logify.Debug("RSI indicator value calculated: class="num">72.56", "Indicators", "Period: class="num">14"); logify.Infor("Buy order sent successfully", "Order Management", "Symbol: EURUSD, Volume: class="num">0.1"); logify.Alert("Stop Loss adjusted to breakeven level", "Risk Management", "Order ID: class="num">12345678");
◍ 把异常分级丢进日志才看得清
MQL5 里直接 print 一堆文字,真到线上排查时根本分不清哪句是警告哪句是致命。上面这段把下单失败和初始化失败拆成了不同级别:Error 用于余额不足这类可恢复的业务异常,Fatal 留给参数缺失这种 EA 起不来的硬伤,第三个字符串参数标了模块名和原因,复盘时按关键字搜就能定位。 实际跑起来,MT5 的 Experts 日志会按级别着色,Error 偏黄、Fatal 偏红。你复制这段代码进 EA 的 OnInit 末尾,把返回前那行保留,初始化一旦撞到无效设置就会在日志里留红条,不用等下单才暴露问题。外汇和贵金属杠杆高,参数错配可能瞬间放大亏损,上线前用日志把初始化路径跑通再实盘。
logify.Error("Failed to send sell order", "Order Management", "Reason: Insufficient balance"); logify.Fatal("Failed to initialize EA: Invalid settings", "Initialization", "Missing or incorrect parameters"); class=class="str">"cmt">//--- class="kw">return(INIT_SUCCEEDED); } class=class="str">"cmt">//+------------------------------------------------------------------+
「收束」
Logify 这套基础架构在 MT5 实测里跑通了,预设的日志级别都能准确吐出对应消息,说明结构化日志管理的底座是稳的。模块化和简洁接口让 MQL5 程序接日志不再脏乱差,后续接数据库、文件或图表可视化的成本被压得很低。 外汇与贵金属行情高波动,这类日志框架只解决可观测性,不替你过滤风险;真要上生产,先把多输出渠道和动态配置补上,再谈策略稳定性。 下个迭代建议直接开 MT5 把 ZIP 里的 Logify 例程拖进 EA 跑一遍,确认级别过滤符合你的盘感,再决定要不要扩成多通道。