从新手到专家:使用 MQL5 制作动画新闻标题(五)—— 事件提醒系统
目录:
概述
高影响力的经济新闻发布可能会引发剧烈的价格波动,有时会带来巨大的回报,有时会让交易者对突然的损失措手不及。我们的 News Headline EA 已经通过在图表上显示即将发生的事件、技术指标分析和 AI 生成的评论,为您提供了优势,因此您无需在窗口之间切换。但让我们面对现实吧:没有人愿意整天坐在屏幕上等待下一次数据发布。
为了使这一工作流程真正实用,我们下一步将集成一个智能预警系统,该系统将在每次重大事件发生前立即主动通知您。这样,你就可以专注于你的策略,确信自己不会错过最关键的新闻。
由于本系列是为经验丰富的开发人员和 MetaTrader 5 新手设计的,我们将所有与通知相关的材料组织到一个专门的部分。在这里,我们将详细探讨该平台的内置预警功能,从屏幕上的弹出窗口和声音到手机上的推送通知,以便您可以根据自己的交易风格定制及时的提醒。
在本次讨论中,我们将探讨 News Headline EA 目前的局限性,同时还将为您提供将 MQL5 提醒集成到您正在进行的任何项目中的技能。在下一节中,我们将详细介绍 MQL5 预警的功能,并逐步介绍我们将其无缝引入 EA 的计划。有了这个基础,您就可以自信地进入代码实现了。
概念
在本节中,我们将首先探讨 MQL5 在预警方面的功能,并讨论集成方案。下一段将介绍 MetaTrader 5 中的预警。
了解 MOL5 中的预警
预警是 MetaTrader 5 的一项重要功能,旨在在发生重要市场事件或条件时吸引交易者的注意力,例如达到特定价格水平、触发指标信号或执行交易。默认情况下,MetaTrader 5 终端中的预警是通过“工具箱”>“预警”选项卡进行管理的,用户可以在其中配置基本警报条件。
但是,MQL5 提供了强大的函数来创建自定义预警,包括 Alert()、PlaySound()、SendMail() 和 SendNotification() 。这些函数会生成弹出对话框、声音提示和消息,这些内容可以在桌面和移动 MetaTrader 5 终端上接收。即使不使用显式警报函数,您仍然可以使用 Print() 将重要事件记录到日志选项卡中并输出消息。
通过 API 调用,可以扩展原生 Alert() 机制,使其与 Telegram、Discord 等外部通知服务配合使用,从而实现进一步集成。虽然今天的讨论不会深入探讨这些外部整合,但我们之前的一些讨论已经涵盖了这些内容。
相反,今天的重点是了解如何在新闻交易中有效使用预警,因为信息的时效性和可见性对于决策至关重要。
下表描述了 MQL5 中可用的预警函数,以及如何在本项目的背景下有效地调整和应用每个函数。
| 函数 | 描述 | 对 News Headline EA 的适用性 |
|---|---|---|
| Alert() | 在 MetaTrader 5 终端上显示一个带有消息的弹出对话框。它会立即在屏幕上显示信息,打断用户操作,并将消息记录在专家日志中。 | 非常适合通知交易者即将发生的高影响事件或 EA 检测到的突然变化,确保即使在实时交易时段也能吸引用户的注意力。 |
| PlaySound() | 在桌面终端上播放自定义声音文件(WAV 格式)。可用于提供声音信号,而不需要用户看屏幕。 | 当 EA 中出现新的新闻标题、指标信号或 AI 见解时,非常适合添加声音提示,帮助交易者即使在多任务处理时也能保持知情。 |
| SendMail() | 通过 MetaTrader 5 选项中配置的 SMTP 服务器发送电子邮件。电子邮件可以包括主题和正文,以及相关的交易细节。 | 可用于向喜欢在终端外接收更新的交易者提供有关高影响事件的详细新闻摘要或警报,特别是当他们不在交易台时。 |
| SendNotification() | 向 MetaTrader 5 移动应用程序发送推送通知,允许交易者在智能手机或平板电脑上实时接收简洁的消息。 | 非常适合立即通知交易者 EA 检测到的关键事件、重大新闻更新或重要的 AI 见解,确保他们无论身处何地都能保持联系。 |
参考上表,提供即时关注的选项,如终端弹出预警和声音,尤其有价值,因为我们希望在即将发生的事件之前得到通知,以便及时准备。在这种情况下,基于终端的警报将具有更高的优先级,而 SendMail() 和 SendNotification() 将用作次要选项。虽然电子邮件和推送通知由于消息传输而引入了轻微的延迟,但这种延迟通常是最小的 —— 但在时间至关重要的情况下,仍然需要考虑这一点。
可扩展性
如前所述,我们可以通过集成 API 来扩展 EA 的功能,以支持其他平台上的外部通知。这包括创建自定义函数来收集预警详细信息,并通过 WebRequest 将其传输到外部服务器,从而实现通过 Slack、Telegram、短信网关或自定义 Web 应用程序等服务进行通信和通知。这种方法使得 News Headlin EA 具有高度的灵活性,能够无缝地融入各种交易工作流程和通知生态系统。
整合计划
今天,我们的主要重点将是实施即将发生的新闻事件的预警,旨在在每个事件发生前的预设时间触发。新闻预警分为三个关键类别,分别对应新闻影响级别:高、中、低。目前,我们将专注于管理这些新闻事件的预警,而将 EA 的其他功能暂时搁置。值得注意的是,并非每条新闻都需要生成预警 —— 相反,我们希望为交易者提供灵活性,让他们可以选择希望收到哪些影响级别的通知,以及在每个事件发生前收到通知的分钟数。
实现
第一步:输入参数配置
集成首先在一个地方定义所有与预警相关的设置:预警和推送通知的全局开关、高/中/低影响级别的单独开关以及“提前几分钟”参数。这种集中式配置不仅简化了用户界面 —— 交易者可以精确地自定义哪些事件会触发弹出窗口或推送通知 —— 而且还保持了 EA 的条件逻辑简洁。初始化时,EA 会读取这些输入参数,然后在触发任何预警之前检查每一个输入参数,从而避免代码中出现硬编码值或隐藏标志。
//--- ALERT INPUTS --------------------------------------------------- input bool InpEnableAlerts = true; //Enable Alerts input bool InpAlertHigh = true; //High Impact Alerts input bool InpAlertMed = false; // Medium Impact Alerts input bool InpAlertLow = false; // Low Impact Alerts input int InpAlertMinutesBefore = 5; //Alert Minutes Before Event //--- PUSH NOTIFICATIONS INPUTS ------------------------------------- input bool InpEnablePush = false; //Enable Push Notifications input bool InpPushHigh = true; //High Impact Push input bool InpPushMed = false; //Medium Impact Push input bool InpPushLow = false; //Low impact Push
第二步: 事件状态跟踪
每个日历事件都包装在一个 CEvent 对象中,该对象携带自己的 alerted 布尔值,初始值为 false。当程序确定需要发出通知时,EA 本身会调用 Alert() (用于屏幕弹出窗口),如果启用了 SendNotification() (用于移动推送),然后立即将该事件的 alerted 标志设置为 true。这种模式无需任何外部查找结构即可防止重复。温馨提示:在触发通知后,务必立即更新事件状态,以确保每个事件只发出一个预警。
// Event storage class CEvent : public CObject { public: datetime time; string sym, name; int imp; bool alerted; CEvent(datetime t,const string &S,const string &N,int I) { time = t; sym = S; name = N; imp = I; alerted = false; } };
第三步: 通知分发逻辑
所有通知分发都在 CheckAndAlertEvents() 函数内部进行,该函数在每个计时器事件触发时执行。该例程首先验证主预警开关,计算一个截止时间戳(now+minutesBefore * 60) ,然后依次遍历高影响、中影响和低影响数组。当发现尚未发出预警、在截止日期内且符合用户选择的影响级别的事件时,EA 会构建一条简洁的消息并触发通知调用。集中化这一逻辑,可以通过扩展此单一功能而不是修改 EA 的多个部分,轻松添加备用渠道(例如电子邮件或短信)。
//+------------------------------------------------------------------+ //| CheckAndAlertEvents: popups and optional push | //+------------------------------------------------------------------+ void CheckAndAlertEvents() { if(!InpEnableAlerts) return; datetime now = TimeTradeServer(); datetime threshold = now + InpAlertMinutesBefore * 60; string msg; for(int i=0;i<ArraySize(highArr);i++) { CEvent *e=highArr[i]; if(!e.alerted && e.time<=threshold && InpAlertHigh) { msg = "In "+IntegerToString(InpAlertMinutesBefore)+"m: "+e.sym+" "+e.name; Alert(msg); if(InpEnablePush && InpPushHigh) SendNotification(msg); e.alerted = true; } } for(int i=0;i<ArraySize(medArr);i++) { CEvent *e=medArr[i]; if(!e.alerted && e.time<=threshold && InpAlertMed) { msg = "In "+IntegerToString(InpAlertMinutesBefore)+"m: "+e.sym+" "+e.name; Alert(msg); if(InpEnablePush && InpPushMed) SendNotification(msg); e.alerted = true; } } for(int i=0;i<ArraySize(lowArr);i++) { CEvent *e=lowArr[i]; if(!e.alerted && e.time<=threshold && InpAlertLow) { msg = "In "+IntegerToString(InpAlertMinutesBefore)+"m: "+e.sym+" "+e.name; Alert(msg); if(InpEnablePush && InpPushLow) SendNotification(msg); e.alerted = true; } } }
第四步:OnTimer
为了确保图表动画流畅,EA 在 OnTimer() 开始时调用 CheckAndAlertEvents() ,然后再进行任何数据获取或绘制。由于 MQL5 中的 Alert() 和 SendNotification() 都是非阻塞的,因此后续的 20 毫秒重绘和滚动操作不会中断。这是一个很有用的策略:在循环中先运行影响小的例程,以便后续渲染保持流畅。
void OnTimer() { CheckAndAlertEvents(); // fire alerts and pushes first ReloadEvents(); FetchAlphaVantageNews(); FetchAIInsights(); DrawAll(); // … remaining drawing and scrolling … }
这一切的基础是一个模块化设计:输入处理配置, ReloadEvents 和 FetchAlphaVantageNews 管理数据检索, CheckAndAlertEvents 处理通知, DrawAll 及其助手管理图表渲染。这种清晰的关注点分离使您能够通过仅更改一个函数来替换或增强通知机制(添加短信、电子邮件、webhook 等),而无需触及 EA 的其余部分。以这种松耦合、文档完善的方式构建您的 EA 交易,可以大大简化后续的维护、扩展和调试工作。
测试
为了测试新的预警功能,我们将更新后的 News Headline EA 加载到实时图表上,并将“分钟之前”输入配置为针对下一个计划事件。输入面板可让您精确指定希望提前多少分钟接收每个预警,确保您在恰当的时机收到通知。以下是我实际测试的屏幕截图:一张显示了 EA 的输入设置,另一张捕捉了活动前几分钟出现的屏幕弹出窗口,以及到达我的移动终端的匹配推送通知的最终图像。

设置 News Headline EA
测试推送通知
每当 MetaTrader 5 安装到受支持的移动设备上时,都会为其分配一个唯一的 MetaQuotes ID (MQID)。该 ID 对于实现 MQL5 平台与桌面 MetaTrader 5 终端之间的通信至关重要。要允许移动终端接收推送通知,您需要将 MQID 添加到桌面终端并启用推送通知。
可以通过“工具”菜单或使用快捷键 Ctrl + O 打开“选项”对话框来完成此操作。在这些设置中,找到“通知”部分,在移动应用程序中找到您的 MQID,并将其输入到您希望用于预警的 ID 列表中。请参考下图。 此设置至关重要 —— 如果没有它,您将无法在移动设备上接收任何通知。
同时,请确保您的移动设备上已启用 MetaTrader 5 的通知功能,并考虑设置独特的通知声音以引起您的注意。这种类型的预警对交易者来说尤其有价值,因为人们通常会将移动设备放在身边,以确保他们不会错过 News Headline EA 发出的重要预警。

设置推送通知
在我的手机 MetaTrader 5 终端上,推送通知如期到达。下面摘录自屏幕截图,显示了这些预警,与上面的图表示例相对应。
在 Android 移动设备上收到 MetaTrader 5 的推送通知
结论
将预警功能融入我们的指标和 EA 交易中,对于提升其对交易者的实际价值至关重要。在这个项目中,我们成功地集成了一个通知系统,显著地将 News Headline EA 转变为更接近真正的交易助手。EA 交易功能广泛 —— 不仅可以执行交易操作,还可以像指标或脚本一样提供见解、可视化或自动响应。
在这个特定案例中,EA 的重点在于洞察和展示即将发生的经济事件,而不是执行交易。实际上,没有哪个交易者能整天坐在那里盯着图表,等待新闻和日历更新。这使得集成预警功能成为主动通知用户重大事件的完美解决方案。推送通知功能的加入进一步提升了该工具的功能,使交易者能够在移动设备上及时收到更新信息。这带来了真正的移动性和灵活性,尤其是在 EA 托管于线上但仍然可以与远程移动终端通信的情况下。
最初,我计划这将是 News Headline EA 的最后一次更新。然而,达到这一阶段揭示了新的可能性和改进,可以将其转化为更全面的解决方案。例如,整合与新闻事件直接关联的交易逻辑、为新闻驱动策略设计交易仪表板以及其他高级功能仍然是未来发展的令人兴奋的机会。每次发布后都会出现新的想法,如果有机会,我很想进一步扩展这个项目。
希望这次讨论能给你带来有价值的启发。下面我附上了完整的源代码,其中包含了我们一起探讨的所有细节以及上一篇文章中的 Python 文件。 欢迎您在此基础上进行扩展、添加新功能或根据需要改进EA。欢迎在下方评论区提出您的想法和反馈!
关键经验
| 经验 | 描述 |
|---|---|
| 集中式配置 | 在代码顶部对所有用户可调整的参数(开关、阈值、API 键)进行分组,以便在不深入逻辑的情况下轻松查找、记录和修改设置。 |
| 定时器驱动架构: | 使用毫秒计时器(OnTimer)来驱动周期性任务,例如数据获取、预警检查和画布更新,从而在响应速度和 CPU 负载之间取得平衡。 |
| Canvas 双缓冲 | 在调用 Update 之前,将所有绘图操作渲染到屏幕外位图(Canvas)上,以防止闪烁并确保图表上的动画流畅。 |
| 非阻塞式通知 | 在循环早期调用 Alert() 和 SendNotification();因为它们是非阻塞的,所以不会暂停你的重绘或数据处理。 |
| 有状态事件对象 | 在每个事件对象中直接嵌入 “alerted” 标志,以跟踪哪些事件已经触发了通知,从而无需外部映射即可消除重复警报。 |
| 模块化关注点分离 | 将您的 EA 交易分成清晰的部分 —— 配置、数据检索、警报逻辑和渲染 —— 以便于维护和未来的扩展。 |
| 限速逻辑 | 实施简单的基于时间的检查(例如,“分钟前”阈值),以防止发出过多或过早的预警,并控制外部 API 调用频率。 |
| WebRequest 集成 | 利用 MQL5 的 WebRequest 调用外部服务(新闻 API、AI 服务器),并在您的 EA 中处理报头、超时和响应解析。 |
| JSON 解析技术 | 使用 StringFind 和 substring 操作从返回的 JSON 字符串(例如,标题或见解文本)中提取必要的字段,保持解析逻辑的健壮性和简洁性。 |
| 清理和资源管理 | 始终在 OnDeinit 中销毁已创建的对象(Canvas、计时器)并删除动态内存,以防止内存泄漏并保持平台稳定。 |
附件
| 文件名 | 版本 | 描述 |
|---|---|---|
| News Headline EA.mq5 | 1.07 | 经济日历、Alpha Vantage 新闻、图表指标分析(RSI、Stoch、MACD、CCI)、AI 驱动的评论栏目,以及事件预警和可选推送通知。 |
| download_model.py | 1.00 | 使用 Hugging Face Hub 客户端下载并缓存量化 GGUF 模型的简单 Python 脚本,并打印其本地文件路径。 |
| serve_insights.py | 1.00 | FastAPI 应用程序通过 llama-cpp 加载 GGUF 模型,公开一个 POST /insights 端点,生成并返回 AI 见解。 |
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/18750
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
价格行为分析工具开发(第二十八部分):开盘区间突破工具
重构经典策略(第十三部分):让我们的交叉策略迈向新维度(2)
新手在交易中的10个基本错误
在 MQL5 中实现其他语言的实用模块(第 01 部分):构建受 Python 启发的 SQLite3 库