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 2018, MetaQuotes Software Corp."

#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_RIGHT: Print("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图表事件类型事件处理函数程序运行客户端事件