前几天写了个基于均线交叉的报警指标,编译通过,挂到欧美H1图表上,结果价格都穿过均线快20个点了,手机端MT4愣是一声不吭。回头查日志才发现,问题根本不在指标逻辑,而是报警触发那几行代码写得太想当然了。折腾了大半天,总算把MT4和MT5两边的报警机制都摸了一遍,这里把踩过的坑和最终能跑通的方案整理一下。
先说最核心的问题:很多人以为只要在指标里调用 Alert() 就完事了,其实不是。Alert() 只是弹窗,它不会自动发送到手机端。手机推送走的是另一套通道,必须依赖 MetaQuotes ID 和平台端的推送服务。MT4里要在 工具-选项-通知 里填上你的 MetaQuotes ID,MT5同理,在 工具-选项-通知 里配置。这个ID在手机端MT4/MT5的设置-聊天里能找到,是一串8位左右的字符。没填这个,代码写得再对也白搭。
然后是代码层面的关键点。以MT4为例,一个能同时弹窗加推送的报警函数大概长这样:
我一开始就是漏了触发控制那一步,结果价格在均线附近来回蹭的时候,手机被连续推送了十几条,差点把通知权限给关了。后来加上K线时间判断,世界才清净。
MT5这边稍有不同,SendNotification() 函数是一样的,但指标里取数据要用 CopyBuffer(),不能用 iMA 直接返回值。另外MT5的报警在策略测试器里是不触发的,这个坑我踩过,回测的时候一直以为代码有问题,后来翻文档才确认,测试模式下 SendNotification 和 Alert 都不会真正执行,必须挂到实盘或模拟盘的图表上才能验证。
还有一个容易忽略的点:VPS上跑报警的时候,如果VPS是Server Core或者没有音频设备,PlaySound() 会报错但不影响推送。另外VPS的时区要和经纪商服务器时间对齐,否则你判断K线时间的时候会错位,导致报警要么早要么晚。我现在的做法是统一用 TimeCurrent() 取服务器时间,不依赖本地时间。
最后提一下参数设置。报警的灵敏度取决于你判断交叉的方式,用 Close[1] 和 Open[1] 比用 Close[0] 稳,但会晚一根K线。如果做的是欧美M15这种节奏,晚一根K线可能就错过几个点了。折中方案是用 Close[0] 配合一个最小价格变动阈值,比如要求穿越幅度大于 2个点(Point*2) 才触发,这样既能及时提醒,又能过滤掉大部分假信号。
目前这套逻辑在MT4和MT5上都跑通了,欧美H1和镑美M30挂了一周多,推送基本没漏过。你们在配置报警的时候有没有遇到过推送延迟或者干脆收不到的情况?是MetaQuotes ID的问题还是VPS网络的问题,交流一下排查思路。
先说最核心的问题:很多人以为只要在指标里调用 Alert() 就完事了,其实不是。Alert() 只是弹窗,它不会自动发送到手机端。手机推送走的是另一套通道,必须依赖 MetaQuotes ID 和平台端的推送服务。MT4里要在 工具-选项-通知 里填上你的 MetaQuotes ID,MT5同理,在 工具-选项-通知 里配置。这个ID在手机端MT4/MT5的设置-聊天里能找到,是一串8位左右的字符。没填这个,代码写得再对也白搭。
然后是代码层面的关键点。以MT4为例,一个能同时弹窗加推送的报警函数大概长这样:
- 判断条件:用 iMA 取均线值,配合 Close[1] 和 Open[1] 做交叉判断,注意用已收盘K线,别用当前K线,否则会反复触发
- 触发控制:用一个静态变量记录上次报警的K线时间,比如 static datetime lastAlertTime = 0; 只有当 Time[0] != lastAlertTime 时才执行报警,避免同一根K线内反复刷屏
- 推送调用:SendNotification() 负责手机推送,Alert() 负责本地弹窗,两个可以一起用,也可以只用其中一个
- 声音提醒:PlaySound() 可以加一个wav文件,但注意路径要放在 MQL4\Files 目录下,否则静默失败
我一开始就是漏了触发控制那一步,结果价格在均线附近来回蹭的时候,手机被连续推送了十几条,差点把通知权限给关了。后来加上K线时间判断,世界才清净。
MT5这边稍有不同,SendNotification() 函数是一样的,但指标里取数据要用 CopyBuffer(),不能用 iMA 直接返回值。另外MT5的报警在策略测试器里是不触发的,这个坑我踩过,回测的时候一直以为代码有问题,后来翻文档才确认,测试模式下 SendNotification 和 Alert 都不会真正执行,必须挂到实盘或模拟盘的图表上才能验证。
还有一个容易忽略的点:VPS上跑报警的时候,如果VPS是Server Core或者没有音频设备,PlaySound() 会报错但不影响推送。另外VPS的时区要和经纪商服务器时间对齐,否则你判断K线时间的时候会错位,导致报警要么早要么晚。我现在的做法是统一用 TimeCurrent() 取服务器时间,不依赖本地时间。
最后提一下参数设置。报警的灵敏度取决于你判断交叉的方式,用 Close[1] 和 Open[1] 比用 Close[0] 稳,但会晚一根K线。如果做的是欧美M15这种节奏,晚一根K线可能就错过几个点了。折中方案是用 Close[0] 配合一个最小价格变动阈值,比如要求穿越幅度大于 2个点(Point*2) 才触发,这样既能及时提醒,又能过滤掉大部分假信号。
目前这套逻辑在MT4和MT5上都跑通了,欧美H1和镑美M30挂了一周多,推送基本没漏过。你们在配置报警的时候有没有遇到过推送延迟或者干脆收不到的情况?是MetaQuotes ID的问题还是VPS网络的问题,交流一下排查思路。
