You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MQL脚本意外终止(deinit原因4)排查与自动重启咨询

关于MQL脚本意外终止(deinit原因4)的排查与自动重启方案

作为常年跟MQL打交道的开发者,我来帮你理清楚这个问题~

一、先搞懂deinit原因4是什么

你提到的deinit原因4对应的是REASON_REMOVE,这个退出码确实和手动点击停止按钮时一致,但自动触发的话,大概率是终端主动卸载了你的脚本,常见触发场景有这些:

  • 脚本依附的图表被关闭、切换了交易品种/时间周期,导致脚本被强制卸载
  • MT4/MT5终端进行自动更新,重启了相关进程
  • 脚本的while(true)+Sleep循环阻塞了线程,被终端判定为"无响应"从而强制终止
  • 交易函数执行时触发了某些未被捕获的严重权限/资源类错误,触发终端清理

二、怎么排查具体原因?

最直接的方法是给脚本加上OnDeinit日志函数,把终止时的上下文记录下来,下次出问题就能精准定位:

void OnDeinit(const int reason)
{
    // 记录终止原因、当前品种、时间、最后交易错误码
    Print("脚本终止 | 原因码:", reason, " | 当前品种:", Symbol(), " | 时间:", TimeToString(TimeCurrent()), " | 最后错误:", GetLastError());
    // 写入文件避免终端日志被覆盖
    int fileHandle = FileOpen("script_deinit_log.txt", FILE_WRITE|FILE_APPEND|FILE_TXT);
    if(fileHandle != INVALID_HANDLE)
    {
        FileWrite(fileHandle, TimeToString(TimeCurrent()), reason, Symbol(), GetLastError());
        FileClose(fileHandle);
    }
}

下次脚本意外终止后,去终端日志或者你写的文件里看记录,就能知道是图表切换、错误触发还是其他原因了。

三、如何实现自动重启?

因为MQL脚本本身没办法重启自己,得借助外部监控机制,这里给你两个实用方案:

方案1:把脚本改成EA(更推荐)

脚本的设计初衷是单次执行任务,你用while(true)强行让它长期运行,本身就不符合终端的预期,容易被清理。改成EA的话,用OnTimer事件代替循环,稳定性会高很多:

// 改成EA后的核心结构
input int ExecuteInterval = 10; // 执行间隔(秒)

void OnInit()
{
    // 设置定时器,每隔ExecuteInterval秒触发一次
    EventSetTimer(ExecuteInterval);
}

void OnTimer()
{
    // 你的下单逻辑,代替原来的MakeOrder
    MakeOrder(...);
}

void OnDeinit(const int reason)
{
    // 清理定时器
    EventKillTimer();
    // 同样可以加日志记录
    Print("EA终止 | 原因码:", reason);
}

EA是终端专门设计的长期运行程序,不会被轻易判定为无响应,稳定性远高于强行循环的脚本。

方案2:用监控EA重启脚本/EA

写一个简单的监控EA,运行在固定图表上,定期检查目标程序是否在运行,如果没运行就自动启动:

// 监控EA的核心逻辑
input string TargetProgramName = "YourScriptName"; // 要监控的脚本/EA名称

void OnInit()
{
    EventSetTimer(60); // 每分钟检查一次
}

void OnTimer()
{
    bool isRunning = false;
    // 遍历所有运行的脚本,检查是否有目标脚本
    for(int i=0; i<ScriptsTotal(); i++)
    {
        if(ScriptName(i) == TargetProgramName)
        {
            isRunning = true;
            break;
        }
    }
    // 如果没运行,启动脚本
    if(!isRunning)
    {
        Print("检测到脚本未运行,自动重启...");
        ExecuteScript(TargetProgramName, Symbol(), Period());
    }
}

如果是监控EA的话,把ScriptsTotal()换成ExpertsTotal(),ScriptName()换成ExpertName()即可。

四、额外的小建议

  • 尽量避免用while(true)+Sleep的循环逻辑,阻塞线程很容易触发终端的无响应检测
  • 在MakeOrder里加上错误处理,即使错误不会终止脚本,记录下来也能帮你排查问题
  • 确保终端的自动更新功能是可控的,避免更新导致程序意外终止

内容的提问来源于stack exchange,提问作者a4194304

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:03:46