OnChartEvent

ChartEvent事件发生时在指标和EA中调用这个函数。这个函数意在处理由用户或者MQL5程序所做的图表更改。

void  OnChartEvent()
   const int       id,       // 事件ID 
   const long&     lparam,   // 长整型(long)事件参数
   const double&   dparam,   // 长整型(double)事件参数
   const string&   sparam    // 字符串型(string)事件参数
   );

参数

id

[in]  来自ENUM_CHART_EVENT枚举的事件ID。

lparam

[in] 长整型(long)事件参数

dparam

[in] 双精度型(double)事件参数

sparam

[in] 字符串型(string)事件参数

返回值

无返回值

注意

共有11种事件类型可以使用预定义OnChartEvent()函数来处理。为自定义事件提供了从CHARTEVENT_CUSTOM到CHARTEVENT_CUSTOM_LAST包含的65535个ID。若要生成自定义事件,请使用EventChartCustom()函数。

来自ENUM_CHART_EVENT 枚举的简短事件描述:

  • CHARTEVENT_KEYDOWN ― 当图表窗口处于焦点时,按下键盘上的一个按键;
  • CHARTEVENT_MOUSE_MOVE ― 移动鼠标,并且鼠标按键点击(如果图表 CHART_EVENT_MOUSE_MOVE=true);
  • CHARTEVENT_OBJECT_CREATE ― 创建一个图形对象(如果图表 CHART_EVENT_OBJECT_CREATE=true);
  • CHARTEVENT_OBJECT_CHANGE ― 通过属性对话框更改对象属性;
  • CHARTEVENT_OBJECT_DELETE ― 删除一个图形对象(如果图表 CHART_EVENT_OBJECT_DELETE=true);
  • CHARTEVENT_CLICK ― 点击图表;
  • CHARTEVENT_OBJECT_CLICK ― 鼠标单击属于图表的图形对象;
  • CHARTEVENT_OBJECT_DRAG ― 用鼠标拖动图形对象;
  • CHARTEVENT_OBJECT_ENDEDIT ― 在图形对象的“编辑”输入框中完成文本编辑(OBJ_EDIT);
  • CHARTEVENT_CHART_CHANGE ― 更改图表;
  • CHARTEVENT_CUSTOM+n ― 自定义事件ID,这里n的范围是从0到65535。CHARTEVENT_CUSTOM_LAST包含最后可接受的自定义事件ID (CHARTEVENT_CUSTOM+65535)。

所有MQL5程序都使用了不同于应用程序主线程的其他线程。主应用程序线程负责处理所有的Windows系统消息,反过来,作为该处理的结果,为其自身的应用程序生成Windows消息。例如,在图表上移动鼠标(WM_MOUSE_MOVE事件)为随后呈现的应用程序窗口生成几个系统消息,并将内部消息发送到在图表上启动的EA和指标。可能会出现这样的情况,主要的应用程序线程还没有处理WM_PAINT系统消息(因此还没有呈现修改过的图表),而EA或指标却已经收到了鼠标移动事件。在这种情况下,只有在呈现图表之后,图表属性CHART_FIRST_VISIBLE_BAR才会更改。

对于每种事件类型,OnChartEvent()函数的输入都具有处理该事件所需的某些值。该表列出了通过参数传递的事件和值。

事件

'id' 参数值

'lparam'参数值

'dparam'参数值

'sparam'参数值

Keystroke事件

CHARTEVENT_KEYDOWN

按下按键代码

在按键处于按下状态时生成的按键响应的数量

位掩码的字符串值,描述键盘按键的状态

鼠标事件 (如果图表CHART_EVENT_MOUSE_MOVE=true)

CHARTEVENT_MOUSE_MOVE

X 坐标

Y 坐标

位掩码的字符串值,描述鼠标按键的状态

鼠标滚轮事件(如果CHART_EVENT_MOUSE_WHEEL=true为图表设置)

CHARTEVENT_MOUSE_WHEEL

键盘按键和鼠标按键的状态标识,光标的X和Y坐标。请参阅示例中的描述

鼠标滚轮滚动的Delta值

创建一个图形对象(如果图表CHART_EVENT_OBJECT_CREATE=true)

CHARTEVENT_OBJECT_CREATE

已创建图形对象的名称

通过属性对话框更改对象属性

CHARTEVENT_OBJECT_CHANGE

已更改图形对象的名称

移除一个图形对象(如果图表CHART_EVENT_OBJECT_DELETE=true)

CHARTEVENT_OBJECT_DELETE

已移除图形对象的名称

图表点击图表

CHARTEVENT_CLICK

X 坐标

Y 坐标

鼠标点击图形对象

CHARTEVENT_OBJECT_CLICK

X 坐标

Y 坐标

事件所发生的图形对象的名称

使用鼠标移动图形对象

CHARTEVENT_OBJECT_DRAG

已移动图形对象的名称

在图形对象输入框的“输入字段”中完成文本编辑

CHARTEVENT_OBJECT_ENDEDIT

“输入字段”图形对象的名称,在这里完成文本编辑

通过属性对话框窗口,调整图表大小或更改图表属性

CHARTEVENT_CHART_CHANGE

N个数字的自定义事件

CHARTEVENT_CUSTOM+N

通过EventChartCustom()函数定义的值

通过EventChartCustom()函数定义的值

通过EventChartCustom()函数定义的值

示例图表事件监听器:

//+------------------------------------------------------------------+
//|                                          OnChartEvent_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Sample chart event listener and custom events generator"
//--- 服务键ID
#define KEY_NUMPAD_5       12
#define KEY_LEFT           37
#define KEY_UP             38
#define KEY_RIGHT          39
#define KEY_DOWN           40
#define KEY_NUMLOCK_DOWN   98
#define KEY_NUMLOCK_LEFT  100
#define KEY_NUMLOCK_5     101
#define KEY_NUMLOCK_RIGHT 102
#define KEY_NUMLOCK_UP    104
//+------------------------------------------------------------------+
//| EA交易初始化函数                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 显示CHARTEVENT_CUSTOM常数值
   Print("CHARTEVENT_CUSTOM=",CHARTEVENT_CUSTOM);
//---
   Print("Launched the EA ",MQLInfoString(MQL5_PROGRAM_NAME));
//--- 设置接收图表对象创建事件的标识
   ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_CREATE,true);
//--- 设置接收图表对象移除事件的标识
   ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_DELETE,true);
//--- 启用鼠标滚轮来滚动信息
   ChartSetInteger(0,CHART_EVENT_MOUSE_WHEEL,1);
//--- 强制更新图表属性确保做好事件处理的准备
   ChartRedraw();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| EA报价函数                                                        |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- 用于生成自定义事件的报价计数器
   static int tick_counter=0;
//--- 通过这个值除以累积的报价
   int simple_number=113;
//--- 
   tick_counter++;
//--- 如果报价计数器是simple_number的倍数,则发送自定义事件
   if(tick_counter%simple_number==0)
     {
      //--- 形成自定义事件ID(从0到65535)
      ushort custom_event_id=ushort(tick_counter%65535);
      //---  发送参数填充的自定义事件
      EventChartCustom(ChartID(),custom_event_id,tick_counter,SymbolInfoDouble(Symbol(),SYMBOL_BID),__FUNCTION__);
      //--- 添加到日志来分析示例结果
      Print(__FUNCTION__,": Sent a custom event ID=",custom_event_id);
     }
//---     
  }
//+------------------------------------------------------------------+
//| ChartEvent 函数                                                   |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- 按键响应
   if(id==CHARTEVENT_KEYDOWN)
     {
      switch((int)lparam)
        {
         case KEY_NUMLOCK_LEFT:  Print("Pressed KEY_NUMLOCK_LEFT");   break;
         case KEY_LEFT:          Print("Pressed KEY_LEFT");           break;
         case KEY_NUMLOCK_UP:    Print("Pressed KEY_NUMLOCK_UP");     break;
         case KEY_UP:            Print("Pressed KEY_UP");             break;
         case KEY_NUMLOCK_RIGHTPrint("Pressed KEY_NUMLOCK_RIGHT");  break;
         case KEY_RIGHT:         Print("Pressed KEY_RIGHT");          break;
         case KEY_NUMLOCK_DOWN:  Print("Pressed KEY_NUMLOCK_DOWN");   break;
         case KEY_DOWN:          Print("Pressed KEY_DOWN");           break;
         case KEY_NUMPAD_5:      Print("Pressed KEY_NUMPAD_5");       break;
         case KEY_NUMLOCK_5:     Print("Pressed KEY_NUMLOCK_5");      break;
         default:                Print("Pressed unlisted key");
        }
     }
//--- 左击图表
   if(id==CHARTEVENT_CLICK)
      Print("Mouse click coordinates on a chart: x = ",lparam,"  y = ",dparam);
//--- 点击图形对象
   if(id==CHARTEVENT_OBJECT_CLICK)
      Print("Clicking a mouse button on an object named '"+sparam+"'");
//--- 被移除的对象
   if(id==CHARTEVENT_OBJECT_DELETE)
      Print("Removed object named ",sparam);
//--- 被创建的对象
   if(id==CHARTEVENT_OBJECT_CREATE)
      Print("Created object named ",sparam);
//--- 被更改的对象
   if(id==CHARTEVENT_OBJECT_CHANGE)
      Print("Changed object named ",sparam);
//--- 被移动的对象或被改变的定位点坐标
   if(id==CHARTEVENT_OBJECT_DRAG)
      Print("Changing anchor points of object named ",sparam);
//--- 在“编辑”图形对象的输入字段更改文本
   if(id==CHARTEVENT_OBJECT_ENDEDIT)
      Print("Changed text in Edit object ",sparam,"  id=",id);
//--- 鼠标移动事件
   if(id==CHARTEVENT_MOUSE_MOVE)
      Comment("POINT: ",(int)lparam,",",(int)dparam,"\n",MouseState((uint)sparam));
   if(id==CHARTEVENT_MOUSE_WHEEL)
     {
      //--- 考虑这个事件的鼠标按键和滚轮的状态
      int flg_keys = (int)(lparam>>32);          // Ctrl 和 Shift 键,鼠标按键的状态标识
      int x_cursor = (int)(short)lparam;         // 鼠标滚轮事件发生的X坐标
      int y_cursor = (int)(short)(lparam>>16);   // 鼠标滚轮事件发生的Y坐标
      int delta    = (int)dparam;                // 鼠标滚动的总值,到达 +120 或 -120 时触发
      //--- 处理标识
      string str_keys="";
      if((flg_keys&0x0001)!=0)
         str_keys+="LMOUSE ";
      if((flg_keys&0x0002)!=0)
         str_keys+="RMOUSE ";
      if((flg_keys&0x0004)!=0)
         str_keys+="SHIFT ";
      if((flg_keys&0x0008)!=0)
         str_keys+="CTRL ";
      if((flg_keys&0x0010)!=0)
         str_keys+="MMOUSE ";
      if((flg_keys&0x0020)!=0)
         str_keys+="X1MOUSE ";
      if((flg_keys&0x0040)!=0)
         str_keys+="X2MOUSE ";
 
      if(str_keys!="")
         str_keys=", keys='"+StringSubstr(str_keys,0,StringLen(str_keys)-1)+"'";
      PrintFormat("%s: X=%d, Y=%d, delta=%d%s",EnumToString(CHARTEVENT_MOUSE_WHEEL),x_cursor,y_cursor,delta,str_keys);
     }
//--- 使用属性对话框窗口调整图表大小或更改图表属性的事件
   if(id==CHARTEVENT_CHART_CHANGE)
      Print("Changing the chart size or properties");
//--- 自定义事件
   if(id>CHARTEVENT_CUSTOM)
      PrintFormat("Custom event ID=%d, lparam=%d, dparam=%G, sparam=%s",id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+
//| 鼠标点选位置                                                       |
//+------------------------------------------------------------------+
string MouseState(uint state)
  {
   string res;
   res+="\nML: "   +(((state& 1)== 1)?"DN":"UP");   // 鼠标左移
   res+="\nMR: "   +(((state& 2)== 2)?"DN":"UP");   // 鼠标右移 
   res+="\nMM: "   +(((state&16)==16)?"DN":"UP");   // 鼠标居中
   res+="\nMX: "   +(((state&32)==32)?"DN":"UP");   // 鼠标点选第一个X键
   res+="\nMY: "   +(((state&64)==64)?"DN":"UP");   // 鼠标点选第二个 X 键
   res+="\nSHIFT: "+(((state& 4)== 4)?"DN":"UP");   // 移位键
   res+="\nCTRL: " +(((state& 8)== 8)?"DN":"UP");   // 控制键
   return(res);
  }

另见

EventChartCustom图表事件类型事件处理函数程序运行客户端事件