图表上的交互事件

MetaTrader 5 的图表不仅能直观展示数据,还是 MQL 程序的运行环境,同时还支持交互式事件机制,该机制让程序可以对用户操作及其他程序做出响应。这通过一种特殊事件类型 OnChartEvent实现,我们已经在 事件处理函数概述章节中讨论过该类型。

任何指标或 EA 交易均可接收此类事件,前提是在代码中定义了具有预定义签名的同名事件处理函数。在之前介绍的部分指标示例中,我们已经利用过这一功能。本章将详细探讨事件系统。

当用户执行以下图表操作时,客户端终端将生成 OnChartEvent事件:

  • 更改图表尺寸或设置
  • 图表窗口处于焦点状态时的按键操作
  • 鼠标光标移动
  • 鼠标点击图表
  • 鼠标点击图形对象
  • 创建图形对象
  • 删除图形对象
  • 用鼠标移动图形对象
  • 完成对 OBJ_EDIT 对象输入字段中测试内容的编辑

MQL 程序仅接收其运行所在图表触发的上述事件。与其他事件类型一样,这些事件会被添加到队列中。所有事件按到达顺序逐个处理。如果 MQL 程序的事件队列中已存在特定类型的 OnChartEvent 事件,或该事件正在处理中,则同类型的新事件将不会加入队列(将被丢弃)。

部分事件类型始终处于激活状态,而另一部分事件类型默认处于禁用状态,必须通过调用 ChartSetInteger 设置相应的图表特性来显式启用。这些禁用事件尤其包括鼠标移动和鼠标滚轮滚动。它们的特点是可能产生大量事件流,为节省资源,建议仅在必要时启用。

除标准事件外,还有“自定义事件”的概念。这类事件的参数意义和参数内容由 MQL 程序自身定义和解释(如果涉及多个程序交互,则由一组程序共同定义)。MQL 程序可通过 EventChartCustom函数向某一图表(包括其他图表)发送“用户事件”这类事件同样由 OnChartEvent函数处理。

如果图表上存在多个包含 OnChartEvent处理程序的 MQL 程序,这些程序将接收同一事件流。

所有 MQL 程序均在应用程序主线程之外的线程中运行。终端主线程负责处理所有 Windows 系统消息,而处理这些消息的结果,又会为其自身应用程序生成 Windows 消息。例如,用鼠标拖动图表时会生成多个 WM_MOUSE_MOVE 系统消息(从 Windows API 角度),用于应用程序窗口的后续绘制操作,同时也会向在该图表上运行的 EA 交易和指标发送内部消息。在这种情况下,可能会出现以下情况:应用程序主线程尚未完成 WM_PAINT 窗口重绘系统消息的处理(因此尚未改变图表的外观),而 EA 交易或指标已接收到鼠标光标移动事件。此时,图表特性 CHART_FIRST_VISIBLE_BAR 仅在图表绘制完成后发生更改。

由于在两类交互式 MQL 程序中,我们目前仅学习了指标,因此本章所有示例均基于指标构建。另一类程序 EA 交易将在本书下一章详细介绍。但其事件处理原理与本章所述完全一致。